掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.27573

整数と浮動小数点数の変換について
投稿者---丈太郎(2006/07/07 00:28:40)


整数と浮動小数点数の変換について質問があります。

K&RのA6.3に整数と浮動小数点数の変換について述べられていますが、
具体的に整数を2の補数、浮動小数点数をIEEE754で表現すると
以下の内容は正しいと思うのですがいかがでしょうか?

shortを16bit, intを32biと仮定します。

(1)short型の値をfloat型もしくはdouble型へ変換すると誤差がない正確な値として表現できる。
(2)int型の値をdouble型へ変換すると誤差がない正確な値として表現できる。
(3)float型で整数を表現(例 5.0等)し、それをshort型へ変換すると正しい整数となる。
ただし範囲はSHRT_MIN〜SHRT_MAXとする。
(4)double型で整数を表現(例 5.0等)し、それをint型へ変換すると正しい整数となる。
ただし範囲はINT_MIN〜INT_MAXとする。

つまり整数と浮動小数点の相互の変換で誤差が発生しないということは言えるでしょうか?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:整数と浮動小数点数の変換について 27574 si 2006/07/07 02:30:04
<子記事> Re:整数と浮動小数点数の変換について 27585 Mook 2006/07/08 15:22:18


No.27574

Re:整数と浮動小数点数の変換について
投稿者---si(2006/07/07 02:30:04)


>つまり整数と浮動小数点の相互の変換で誤差が発生しないということは言えるでしょうか?
#include <stdio.h>
int main(void)
{
    unsigned int i,j;
    float x;
    double y;
    i = 1;
    for ( i = 1, j = 0 ;  j < 32 ; i = (i << 1) | 1, j++ ) {
        x = i;
        y = i;
        printf("%u %f %lf\n",i,x,y);
    }
}

結果
1 1.000000 1.000000
3 3.000000 3.000000
7 7.000000 7.000000
15 15.000000 15.000000
31 31.000000 31.000000
63 63.000000 63.000000
127 127.000000 127.000000
255 255.000000 255.000000
511 511.000000 511.000000
1023 1023.000000 1023.000000
2047 2047.000000 2047.000000
4095 4095.000000 4095.000000
8191 8191.000000 8191.000000
16383 16383.000000 16383.000000
32767 32767.000000 32767.000000
65535 65535.000000 65535.000000
131071 131071.000000 131071.000000
262143 262143.000000 262143.000000
524287 524287.000000 524287.000000
1048575 1048575.000000 1048575.000000
2097151 2097151.000000 2097151.000000
4194303 4194303.000000 4194303.000000
8388607 8388607.000000 8388607.000000
16777215 16777215.000000 16777215.000000
33554431 33554432.000000 33554431.000000
67108863 67108864.000000 67108863.000000
134217727 134217728.000000 134217727.000000
268435455 268435456.000000 268435455.000000
536870911 536870912.000000 536870911.000000
1073741823 1073741824.000000 1073741823.000000
2147483647 2147483648.000000 2147483647.000000
4294967295 4294967296.000000 4294967295.000000
環境
Linux 2.6.17-1.2145_FC5smp i686 GNU/Linux
gcc バージョン 4.1.1 20060525 (Red Hat 4.1.1-1)


この投稿にコメントする

削除パスワード

No.27575

Re:整数と浮動小数点数の変換について
投稿者---Mook(2006/07/07 09:47:48)


同様の結果でした。
#include <stdio.h>
int main(void)
{
    unsigned int i;
    int j;
    float f;
    double d;
    for ( j = 31 ;  j>=0 ;  --j ) {
        i = (0xffffffff >> j);
        f = (float)i;
        d = (double)i;
        printf("  0x%08x : %12u %14.2f %14.2lf\n",i, i,f,d);
    }
}

  0x00000001 :            1           1.00           1.00
  0x00000003 :            3           3.00           3.00
  0x00000007 :            7           7.00           7.00
  0x0000000f :           15          15.00          15.00
  0x0000001f :           31          31.00          31.00
  0x0000003f :           63          63.00          63.00
  0x0000007f :          127         127.00         127.00
  0x000000ff :          255         255.00         255.00
  0x000001ff :          511         511.00         511.00
  0x000003ff :         1023        1023.00        1023.00
  0x000007ff :         2047        2047.00        2047.00
  0x00000fff :         4095        4095.00        4095.00
  0x00001fff :         8191        8191.00        8191.00
  0x00003fff :        16383       16383.00       16383.00
  0x00007fff :        32767       32767.00       32767.00
  0x0000ffff :        65535       65535.00       65535.00
  0x0001ffff :       131071      131071.00      131071.00
  0x0003ffff :       262143      262143.00      262143.00
  0x0007ffff :       524287      524287.00      524287.00
  0x000fffff :      1048575     1048575.00     1048575.00
  0x001fffff :      2097151     2097151.00     2097151.00
  0x003fffff :      4194303     4194303.00     4194303.00
  0x007fffff :      8388607     8388607.00     8388607.00
  0x00ffffff :     16777215    16777215.00    16777215.00
  0x01ffffff :     33554431    33554432.00    33554431.00
  0x03ffffff :     67108863    67108864.00    67108863.00
  0x07ffffff :    134217727   134217728.00   134217727.00
  0x0fffffff :    268435455   268435456.00   268435455.00
  0x1fffffff :    536870911   536870912.00   536870911.00
  0x3fffffff :   1073741823  1073741824.00  1073741823.00
  0x7fffffff :   2147483647  2147483648.00  2147483647.00
  0xffffffff :   4294967295  4294967296.00  4294967295.00

環境
Windos XP
Borland C++ 5.5.1


この投稿にコメントする

削除パスワード

No.27584

Re:整数と浮動小数点数の変換について
投稿者---丈太郎(2006/07/08 14:40:52)


si様、Mook様テストプログラムを使っての確認ありがとうございます。

これで安心して?整数と浮動小数点の変換ができます。

ありがとうございました。


この投稿にコメントする

削除パスワード

No.27585

Re:整数と浮動小数点数の変換について
投稿者---Mook(2006/07/08 15:22:18)
http://www.nextindex.net/java/binary.html


誤解していなければ良いのですが、一応確認です。

float の仮数部は23 bit, double の仮数部は52bitです。
SHRT_MIN〜SHRT_MAX は ±0x007fffff
INT_MIN〜INT_MAX は ±0x000fffffffffffff
の範囲です。

この範囲では誤差が出ませんが、これを超えると誤差が出ます。

#include <stdio.h>

static void castTest( unsigned int i );

void main(void)
{
    int j;
    unsigned int i;
    for( j=0 ; j<16 ; j++ ) {
        castTest( 0x01fffff0 + j );
    }

    for( j=0 ; j<16 ; j++ ) {
        castTest( 0xfffffff0 + j );
    }
}

static void castTest( unsigned int i )
{
    float f;
    double d;
    f = (float)i;
    d = (double)i;
    printf("  0x%08x : %12u %14.2f %14.2lf\n",i, i,f,d);
}

  0x01fffff0 :     33554416    33554416.00    33554416.00
  0x01fffff1 :     33554417    33554416.00    33554417.00
  0x01fffff2 :     33554418    33554418.00    33554418.00
  0x01fffff3 :     33554419    33554420.00    33554419.00
  0x01fffff4 :     33554420    33554420.00    33554420.00
  0x01fffff5 :     33554421    33554420.00    33554421.00
  0x01fffff6 :     33554422    33554422.00    33554422.00
  0x01fffff7 :     33554423    33554424.00    33554423.00
  0x01fffff8 :     33554424    33554424.00    33554424.00
  0x01fffff9 :     33554425    33554424.00    33554425.00
  0x01fffffa :     33554426    33554426.00    33554426.00
  0x01fffffb :     33554427    33554428.00    33554427.00
  0x01fffffc :     33554428    33554428.00    33554428.00
  0x01fffffd :     33554429    33554428.00    33554429.00
  0x01fffffe :     33554430    33554430.00    33554430.00
  0x01ffffff :     33554431    33554432.00    33554431.00
  
  0xfffffff0 :   4294967280  4294967296.00  4294967280.00
  0xfffffff1 :   4294967281  4294967296.00  4294967281.00
  0xfffffff2 :   4294967282  4294967296.00  4294967282.00
  0xfffffff3 :   4294967283  4294967296.00  4294967283.00
  0xfffffff4 :   4294967284  4294967296.00  4294967284.00
  0xfffffff5 :   4294967285  4294967296.00  4294967285.00
  0xfffffff6 :   4294967286  4294967296.00  4294967286.00
  0xfffffff7 :   4294967287  4294967296.00  4294967287.00
  0xfffffff8 :   4294967288  4294967296.00  4294967288.00
  0xfffffff9 :   4294967289  4294967296.00  4294967289.00
  0xfffffffa :   4294967290  4294967296.00  4294967290.00
  0xfffffffb :   4294967291  4294967296.00  4294967291.00
  0xfffffffc :   4294967292  4294967296.00  4294967292.00
  0xfffffffd :   4294967293  4294967296.00  4294967293.00
  0xfffffffe :   4294967294  4294967296.00  4294967294.00
  0xffffffff :   4294967295  4294967296.00  4294967295.00
 



この投稿にコメントする

削除パスワード

No.27588

Re:整数と浮動小数点数の変換について
投稿者---丈太郎(2006/07/09 01:29:56)


>float の仮数部は23 bit, double の仮数部は52bitです。
>SHRT_MIN〜SHRT_MAX は ±0x007fffff
>INT_MIN〜INT_MAX は ±0x000fffffffffffff
>の範囲です。
>
>この範囲では誤差が出ませんが、これを超えると誤差が出ます。

仮数部の範囲(floatなら23bit, doubleなら52bit)の整数ならば
正しく変換できるということですね。

下のソースコードは
float型では23bitを超えているので正しく表現できないが
double型では52bit以内なので正しく表現できる
ということでしょうか?


この投稿にコメントする

削除パスワード

No.27594

Re:整数と浮動小数点数の変換について
投稿者---Mook(2006/07/09 20:05:55)


>float型では23bitを超えているので正しく表現できないが
>double型では52bit以内なので正しく表現できる
>ということでしょうか?

そういうことです。


この投稿にコメントする

削除パスワード

No.27601

Re:整数と浮動小数点数の変換について
投稿者---かずま(2006/07/10 13:28:22)


> float の仮数部は23 bit, double の仮数部は52bitです。
> SHRT_MIN〜SHRT_MAX は ±0x007fffff
> INT_MIN〜INT_MAX は ±0x000fffffffffffff
> の範囲です。
>
> この範囲では誤差が出ませんが、これを超えると誤差が出ます。
float の仮数部は 23ビットですが、正規化したときの最上位の 1 が
省略されているので、精度は 24ビットあります。
だから、0x00ffffff までの整数を誤差なく float で表現できます。

 0x00ffffff :     16777215    16777215.00    16777215.00

という実行結果に気づきませんでしたか?

さらに、その 1つ上の 0x01000000 は最下位が 0 なのでこれも誤差なく
float で表現できます。
次の 0x01000001 は、25ビット必要なので float では表現できません。
したがって、±0x01000000 の範囲で誤差が出ません。
これを超えても、下位ビットに 0 があると、少ない有効ビット数で済む
ので float で表現できる場合があります。

double の場合も同様で、53ビットの精度があります。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧