C言語関係掲示板

過去ログ

No.420.float型の整数のみを取り出す

[戻る] [ホームページ]
No.2916

float型の整数のみを取り出すための質問です。
投稿者---キウイ(2002/10/11 16:13:11)


float型の整数のみをintで取り出す関数を自作したいのですが、
(int floor(float)みたいなもの)
float型の表現形式自体よくわかっていないため、アルゴリズム
が作れません。その辺が分かる文献やHPがありましたら、ご紹介
下さい。よろしくお願いします。

No.2917

Re:float型の整数のみを取り出すための質問です。
投稿者---kikk(2002/10/11 17:20:31)


ども。


とにかく実現すればいいのであれば、intにキャストすればOKです。
移植性と速度の面ではたぶんこれがベスト。

ビットパターンから抽出したい場合、浮動小数点型の内部表現は規格では
規定されていないので、まず、使っている処理系がどの方式を採用している
かをマニュアル等で調べる必要があります(たぶんIEEE形式だとは思います
が)。実際の仕様を調べるには、サーチエンジンで「方式+"内部表現"」等で
検索してもいいですし、情報処理技術者試験の対策ページみたいなところ
でものっていると思います。


では。

No.2918

Re:float型の整数のみを取り出すための質問です。
投稿者---C職人(2002/10/11 17:55:51)


#include <stdio.h>

int main(void)
{
    float fnum;
    char  str[256];
    char  temp[256];
    char  *p;
    int   i = 0;

    fnum = 123.45;

    /*float値を文字列に変換*/
    sprintf(str,"%lf",fnum);

    /*先頭アドレス取得*/
    p = str;

    /*文字列の終わりまで*/
    while(*p != '\0'){
        /*カンマでないとき*/
        if(*p != '.'){
            /*一文字格納*/
            temp[i] = *p;
        }
        else{
            /*文字列の終了マーク付加*/
            temp[i] = '\0';

            /*ループを抜ける*/
            break;
        }
        /*ポインタを進める*/
        p++;

		/*添え字を進める*/
        i++;
    }

    /*結果表示*/
    printf("%s\n",temp);

    return 0;
}





No.2920

Re:float型の整数のみを取り出すための質問です。
投稿者---キウイ(2002/10/11 19:59:08)


kikkさん、C職人さん、情報ありがとうございました。
C職人さんのプログラムを利用して、期待するものが
できました。
floor関数が使えないシステムなのですが、printfは
使えましたので、なんとか動作しました。欲を言えば
sprintfは重そうな関数なので、これを使わないで
なんとか早く実行できないかと考えています。




No.2921

Re:float型の整数のみを取り出すための質問です。
投稿者---かずま(2002/10/11 20:22:02)


> float型の整数のみをintで取り出す関数を自作したいのですが、
> (int floor(float)みたいなもの)
> float型の表現形式自体よくわかっていないため、アルゴリズム
> が作れません。その辺が分かる文献やHPがありましたら、ご紹介
> 下さい。よろしくお願いします。

IEEE754 で検索してみてください。

int が 4バイト、float が IEEE754 で 4バイトの場合について作ってみました。
Borland C++ と gcc ではコンパイルできますが、VC++ ではだめのようです。
float の仮数は 24ビットの精度しかなく、31ビットの int には不足です。
また、int は、2147483647までの数値しか扱えません。
#include <stdio.h>

int ifloor(float x)
{
    int a = *(int *)&x;
    int e = (a>>23 & 0xFF) - 127;    /* 指数(exponent) */
    int m = a & 0x7FFFFF | 0x800000; /* 仮数(mantissa) */

    if (e < 0) m = 0;
    else if (e < 23) m >>= 23 - e;
    else if (e < 31) m <<= e - 23;   /* 精度不足 */
    else if (e < 128) printf("too large "), m = 0;
    else if (m == 0x800000) printf("Inf "), m = 0;
    else printf("NaN "), m = 0;
    return (a < 0) ? -m : m;
}

void print(float f) { printf("%d\n", ifloor(f)); }

int main()
{
    print(0.012345);
    print(1234.567);
    print(1234567890.1234);
    print(123456789012.34);
    print(1 / 0.0);
    print(0 / 0.0);
    return 0;
}