20

元の質問は、範囲ではなく精度の問題に焦点を当てるために編集(短縮)されました。

単精度または倍精度の実数のすべての表現は、(-range、+ range)に制限されます。この範囲内にはいくつかの整数があります(1、2、3、4 ...など。負の数についても同じことが言えます)。

IEEE 754実数(float、doubleなど)がその範囲内のすべての整数を「カバー」できるという保証はありますか?「カバー」とは、実数が(たとえば)「5.000001」ではなく、整数を正確に表すことを意味します。

リマインダーと同じように:http ://www3.ntu.edu.sg/home/ehchua/programming/java/DataRepresentation.htmlさまざまな数値表現形式のわかりやすい説明。

アップデート:

質問は「できる」ということなので、これができないという事実も探しています。数字を引用するだけで十分だからです。たとえば、「いいえ、できません。たとえば、番号1748574は、浮動小数点数で正確に表されていません」(もちろん、この番号は薄い空気から取り出されています)。

好奇心旺盛な読者のために

IEEE 754表現を試してみたい場合-オンライン計算機:http ://www.ajdesigner.com/fl_ieee_754_word/ieee_32_bit_word.php

4

4 に答える 4

43

いいえ、すべてではありませんが、すべての整数を正確に表現できる範囲が存在します。

32ビット浮動小数点数の構造

32bit 浮動小数点型は

  • 符号用の 1 ビット
  • 指数は8ビット
  • 小数部の 23 ビット (先頭の 1 を暗黙指定)

数字を表す

基本的に、フォームに数字があります

(-)1.xxxx_xxxx_xxxx_xxxx_xxxx_xxx (binary)

次に、(偏りのない)指数で左右にシフトします。

ビットを必要とする整数を表すには、左にビット単位nでシフトする必要があります。(浮動小数点を超えるn-1すべてのes は単純にゼロです)x

整数を 24 ビットで表現する

24 ビット (およびそれ以下) を必要とするすべての整数を表すことができることは簡単にわかります。

1xxx_xxxx_xxxx_xxxx_xxxx_xxxx.0 (unbiased exponent = 23)

xes を任意に または のいずれかに1設定できるため0です。

この方法で表現できる最大数は次のとおりです。

1111_1111_1111_1111_1111_1111.0

また2^24 - 1 = 16777215

次に大きい整数は です1_0000_0000_0000_0000_0000_0000。したがって、25 ビットが必要です。

整数を 25 ビットで表現する

25 ビット整数 (偏りのない指数 = 24) を表現しようとすると、数値は次の形式になります。

1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0

利用可能な 23 桁はすべて、浮動小数点を超えてシフトされています。先頭の桁は常に 1 です。合計で 24 桁です。しかし、25 が必要なので、ゼロが追加されます。

最大値が見つかりました

「1_0000_0000_0000_0000_0000_0000 with the form1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0 , by simply assigning 1 to allx es. The next higher integer from that is: 1_0000_0000_0000_0000_0000_0001 . It's easy to see that this number cannot be represented accurately, because the form does not allow us to set the last digit to 1 : It is always 0」と表すことができます。

24個のゼロが続くの1は、正確に表現できる整数の上限です。下限は、符号ビットが反転されているだけです。

すべての整数を表現できる範囲(境界を含む)

  • 上限として2 24
  • -2 24を下限として

64 ビット浮動小数点数の構造

  • 符号用の 1 ビット
  • 11 指数ビット
  • 52小数ビット

すべての整数を表現できる範囲(境界を含む)

  • 上限として2 53
  • 下限として-2 53

これは、同じ議論を 64 ビット浮動小数点数の構造に適用することで簡単に実現できます。

: これは、表現できるすべての整数であるとは言えませんが、すべての整数を表現できる範囲を示しています。その範囲を超えると、その範囲の整数を掛けた 2 のべき乗のみを表すことができます。

組み合わせ論

32 ビット整数が表現できるすべての整数を 32 ビット浮動小数点数で表現することは不可能であると自分自身に納得させるだけで、浮動小数点数の構造を見る必要さえありません。

  1. 32 ビットでは、2 32の異なるものを表すことができます。それ以上でもそれ以下でもありません。
  2. 32 ビット整数は、これらすべての「もの」を使用して数値を表します (ペアごとに異なります)。
  3. 32 ビット浮動小数点数は、少なくとも 1 つの数値を小数部分で表すことができます。

したがって、32 ビットの浮動小数点数が、2 32 個の整数すべてに加えて、この小数を表すことは不可能です。

于 2012-09-16T09:13:28.543 に答える
9

macias、phant0mによるすでに優れた回答に追加するために(賛成です。受け入れることをお勧めします)、私はあなた自身の言葉を使用します。

「いいえ、できません。たとえば、番号 16777217 は浮動小数点数で正確に表されません。」

また、「たとえば、9223372036854775809 という数字は、倍数で正確に表されません」。

これは、コンピュータが IEEE 浮動小数点形式を使用していることを前提としています。これはかなり強い賭けです。

于 2012-09-16T14:12:23.433 に答える
7

いいえ。

たとえば、私のシステムでは、タイプfloatは約までの値を表すことができます3.40282e+38。整数として、それはおよそ340282000000000000000000000000000000000、または約2128になります。

のサイズは32ビットであるため、最大で232個の異なる数値floatを正確に表すことができます。

整数オブジェクトは通常、そのすべてのビットを使用して値を表します(1ビットは符号付きタイプの符号ビット専用です)。浮動小数点オブジェクトは、そのビットの一部を使用して指数を表します(IEEE 32ビットの場合は8ビットfloat)。これにより、精度が失われる代わりに範囲が広がります。

具体的な例(1267650600228229401496703205376.0は2 100であり、正確にaとして表すことができますfloat):

#include <stdio.h>
#include <float.h>
#include <math.h>
int main(void) {
    float x = 1267650600228229401496703205376.0;
    float y = nextafterf(x, FLT_MAX);
    printf("x = %.1f\n", x);
    printf("y = %.1f\n", y);

    return 0;
}

私のシステムの出力は次のとおりです。

x = 1267650600228229401496703205376.0
y = 1267650751343956853325350043648.0

それを見る別の方法:

32ビットオブジェクトは、最大232個の異なる値を表すことができます。

-214748364832ビットの符号付き整数は、 .. 2147483647(-2 31 .. +2 31 -1)の範囲のすべての整数値を表すことができます。

32ビットは、小数(0.5)または大きすぎる(2.0 100float )ために、32ビットの符号付き整数では表現できない多くの値を表すことができます。32ビットでは表現できるが32ビットでは表現できない値があるため、32ビットでは表現できるが32ビットでは表現できない他の値が必要です。には31個の値ビットがありますが、には約24個しかないため、これらの値は、が処理できるよりも有効桁数が多い整数です。floatintintfloatfloatintfloat

于 2012-09-15T21:32:02.597 に答える
1

どうやら、実数型がその範囲内のすべての整数値(CではFLT_MAXまたはDBL_MAXまでの絶対値、または他の言語では同様の定数)を表すことができるかどうかを尋ねているようです。

Kビットに格納された浮動小数点数で表現できる最大数は、通常、Kビットで表現できる整数の2 ^ K数よりもはるかに大きいため、通常、答えはノーです。32ビットCフロートは10^37を超え、32ビットC整数は10^10未満です。ある数値の次の表現可能な数値を見つけるには、nextafter()またはnextafterf()を使用します。たとえば、コード

printf ("%20.4f %20.4f\n", nextafterf(1e5,1e9), nextafterf(1e6,1e9));
printf ("%20.4f %20.4f\n", nextafterf(1e7,1e9), nextafterf(1e8,1e9));

プリントアウト

     100000.0078         1000000.0625
   10000001.0000       100000008.0000

SR<1およびR<J<Sと仮定して、2つの近くの小数浮動値RとSの間にある整数Jを正確に表すことができるかどうかに興味があるかもしれません。はい、そのようなJは正確に表すことができます。すべての浮動小数点値は、整数と2の累乗の比率です(または、整数と2の累乗の積です)。2の累乗をPとし、R = U / P、S =V/と仮定します。 P。ここで、U / P <J <V / Pなので、U <J * P<Vです。J*Pの下位ビットの多くは、U、Vのビットよりもゼロです(SR <1のため、VU <Pであるため)。したがって、Jを正確に表すことができます。

J *PU<PおよびVJ*P <Pであることを示すためにすべての詳細を入力していませんが、SR<1という仮定の下では簡単です。R、J、S、P、U、V値の計算の例を次に示します。R= 99999.9921875 = 12799999/128(つまり、P = 128)とします。S = 1000000.0078125=12800001/128とします。U=0xc34fffとV=0xc35001があり、それらの間に、どちらよりも低次のゼロが多い数があります。つまり、J = 0xc35000 / 128 = 12800000/128=100000.0です。この例の数値については、UとVが正確に表現するために24ビットが必要であることに注意してください(6個、4ビットの16進数)。24ビットは、IEEE754単精度浮動小数点数の精度のビット数であることに注意してください。(ウィキペディアの記事の表を参照してください。)

各浮動小数点数が整数と2の累乗の積または比率であるということ(上記の2つの段落で述べたように)も、その浮動小数点の記事の次の段落で説明されています。

その性質上、浮動小数点形式で表されるすべての数値は、関連する基数で終了する展開を持つ有理数です(たとえば、...基数2で終了する2進数展開)。πや√2などの無理数、または非終了有理数は近似する必要があります。精度の桁数(またはビット数)も、正確に表現できる有理数のセットを制限します。

于 2012-09-15T21:58:42.310 に答える