web-dev-qa-db-ja.com

整数から単精度への変換が精度を失う可能性がある場合

私が読んでいたのは 拡大変換とOption Strict Onに関するMicrosoftの記事 で、その部分に着いたとき

次の変換は精度を失う可能性があります:

  • 整数から単一
  • ロングからシングルまたはダブル
  • 10進数からシングルまたはダブル

ただし、これらの変換によって情報や大きさが失われることはありません。

..しかし データ型に関する別の記事 によると、

  • 整数型は-2.147.483.648から2.147.483.647までを格納でき、

  • シングルタイプから収納可能

    • 正の数の場合、1,401298E-45から3,4028235E + 38
    • 負の数の場合は-3,4028235E + 38〜-1,401298E-45

..したがって、SingleはIntegerよりもはるかに多くの数を格納できます。 IntegerからSingleへのこのような変換が精度を失う可能性がある状況を理解できませんでした。誰かが説明してもらえますか?

27
Vinicius V

シングルは整数よりもはるかに多くの数を格納できます

いいえ、できません。 SingleIntegerはどちらも32ビットです。つまり、どちらもまったく同じの数値を格納できます。 232 = 4294967296の異なる番号。

Singlerangeはそれよりも明らかに大きいため、(ピジョンホール原理)それができない可能性があることは、その範囲内のすべての数値を表します。

また、Integerの範囲は、IntegerSingleの両方が表すことができる数値の最大量とまったく同じサイズですが、Singleも表すことができますその範囲外の数値の場合、Integerの範囲内のすべての数値を表すことができない可能性があることは明らかです。

Integerで表現できないSingleの数がある場合、IntegerからSingleに変換する必要がありますmust情報を失う可能性があります。

87
Jörg W Mittag

浮動小数点型(SingleやDoubleなど)は、メモリ内では符号、仮数、指数で表されます。それを科学的表記法と考えてください:

Sign*Mantissa*Base^Exponent

それらは-あなたが予想するように-基数2を使用します。無限大とNaNを表すことを可能にする他の微調整があり、指数はオフセットされます(それに戻ります)、仮数の短縮形(それにも戻ります)。 。詳細については、その表現と操作をカバーする標準のIEEE 754を探してください。

ここでは、2進数の「仮数」と、小数点をどこに置くかを指示する「指数」と考えることができます。


シングルの場合、彼の符号には1ビット、指数には8、仮数には23があります。

さて、問題は、最上位の桁から仮数を格納することです。左にあるすべてのゼロは関係がないことに注意してください。また、バイナリで作業していることを考えると、最上位の桁は1※であることがわかります。まあ、それはわかっているので、保存する必要はありません。その短縮形のおかげで、仮数の有効範囲は24ビットです。

※:当店の収納数がゼロでない限り。そのため、すべてのビットをゼロに設定します。しかし、私が与えた説明の下でそれを解釈しようとすると、2 ^ 24(暗黙の1)に1を掛けた(2の指数0のべき乗)になります。したがって、それを修正するために、指数ゼロは特別な値です。指数に無限大とNaNを格納する特別な値もあります。

指数オフセットに従って-特別な値を回避することを除いて、それをオフセットすることで、仮数の開始前または終了後に小数点を配置できます。指数に符号を付ける必要はありません。


これは、大きな数値の場合、浮動小数点型は仮数の終わりを超えて小数点を置くことを意味します。

仮数は24ビットの数値であることに注意してください。 25ビットの数値を表すことはありません...追加のビットはありません。したがって、シングルは2 ^ 24と2 ^ 24 + 1を区別できません(これらは最初の25ビットの数値であり、シングルで表されていない最後のビットで異なります)。

したがって、整数の場合、単一の範囲は-2 ^ 24から2 ^ 24です。また、1を2 ^ 24に追加しようとすると、2 ^ 24になります(型に関する限り、2 ^ 24と2 ^ 24 + 1は同じ値です)。 オンラインで試す 。これが、整数から単一に変換するときに情報が失われる理由です。 これが、singleまたはdoubleを使用するループが、気付かずに実際に無限ループになる可能性がある理由でもあります。

28
Theraot

IntegerからSingleへの変換が精度を失う場合の実際の例を次に示します。

Singleタイプは-16777216から16777216までの整数を格納できますが、この範囲外のすべての整数を格納することはできません。たとえば、16777217という数値を格納することはできません。さらに言えば、16-777216より大きいany奇数を格納することはできません。

Windows PowerShellを使用して、IntegerSingleに変換して戻すとどうなるかを確認できます。

PS C:\Users\tanne> [int][float]16777213
16777213
PS C:\Users\tanne> [int][float]16777214
16777214
PS C:\Users\tanne> [int][float]16777215
16777215
PS C:\Users\tanne> [int][float]16777216
16777216
PS C:\Users\tanne> [int][float]16777217
16777216
PS C:\Users\tanne> [int][float]16777218
16777218
PS C:\Users\tanne> [int][float]16777219
16777220

16777217は16777216に切り捨てられ、16777219は16777220に切り上げられていることに注意してください。

25
Tanner Swett

浮動小数点型は、物理学の「科学表記」に似ています。数値は、符号ビット、指数(乗数)、および仮数(有効数字)に分割されます。したがって、値の大きさが大きくなると、ステップサイズも大きくなります。

単精度浮動小数点には23の仮数ビットがありますが、「暗黙の1」があるため、仮数は事実上24ビットです。したがって、最大2つの等級を持つすべての整数24 単精度浮動小数点で正確に表すことができます。

その上では、連続して表示できる数が少なくなります。

  • 2から24 2に25 偶数のみを表すことができます。
  • 2から25 2に26日 4の倍数のみを表すことができます。
  • 2から26日 2に27日 8の倍数のみを表すことができます。
  • 2から27日 2に28 16の倍数しか表現できません
  • 2から28 2に29日 32の倍数しか表現できません
  • 2から29日 2に30 64の倍数しか表現できません
  • 2から30 2に31 128の倍数しか表現できません

ので、232 可能な32ビット符号付き整数値のみ2 *(224 + 7 * 223)= 9 * 224 単精度浮動小数点で表すことができます。それは全体の3.515625%です。

12
Peter Green

単精度浮動小数点数は24ビットの精度です。それを超えるものはすべて、最も近い24ビットの数値に丸められます。 10進数の科学表記で理解する方が簡単かもしれませんが、実際の浮動小数点はバイナリを使用することに注意してください。

10桁のメモリが5桁あるとします。通常の符号なし整数のようなものを使用することを選択でき、0から99999までの任意の数値を使用できます。より大きな数値を表すことができるようにしたい場合は、指数表記を使用して、2桁を指数に割り当てることができます。 0から9.99 x 10までのすべてを表現できるようになりました99

ただし、正確に表現できる最大数は999のみです。12345を表現しようとすると、1.23 x 10を取得できます。4、または1.24 x 104ですが、十分な桁数がないため、その間の数値を表すことはできません。

8
Karl Bielefeldt