Javaでfloatとdoubleには有効数字がいくつありますか?


83

floatには32の2進数があり、doubleには64の2進数がありますか?ドキュメントは難しすぎて理解できませんでした。

すべてのビットが有効数字に変換されますか?または、小数点の位置がビットの一部を占めていますか?


2
これらのビットはすべて有効数字に変換されますか?または、小数点の位置がビットの一部を占めていますか?
イーモンモロニー2012年

@ user1774214浮動小数点数は、整数のようにエンコードされていません。私が与えるリンクを見てください。たとえば、精度が均一ではないことを理解する必要があります。
デニス・Séguret

@dystroy「精度が均一ではない」とはどういう意味かわかりません。非正規化数を参照していない限り、53ビットと24ビットの精度でほぼ均一です。
パスカルキュオック2014年

2
@PascalCuoq数値が小さいほど、精度が高くなります。指数が変化する(またはポイントが浮く)と、仮数は同じ桁数を表し続けます。したがって、数値が大きい場合、仮数は有効数字の下位桁に「到達できない」ため、精度が低下します。
Vituel 2015年

3
@Virtuel精度は53ビットです。それが私たちが精度と呼んでいるものです。あなたは絶対的な正確さか何かを考えているように見えます。
パスカルキュオック2015年

回答:


108

float32ビット(4バイト)。ここで、23ビットは仮数(約7桁の10進数)に使用されます。指数には8ビットが使用されるため、フロートはこれらの8ビットを使用して小数点を右または左に「移動」できます。そうすることで、0.0000003(3×10 -7)または3000000(3×10 7)のように仮数に多くのゼロを格納することを回避できます。符号ビットとして使用される1ビットがあります。

double64ビット(8バイト)。ここで、52ビットは仮数(約16桁の10進数)に使用されます。指数には11ビットが使用され、1ビットは符号ビットです。

2進数(0と1のみ)を使用しているため、数値がゼロ以外の場合、仮数の1ビットは暗黙的に1になります(floatとdoubleの両方でこのトリックを使用します)。

また、すべてが2進数(仮数と指数)であるため、10進数への変換は通常正確ではありません。0.5、0.25、0.75、0.125などの数値は正確に格納されますが、0.1は格納されません。他の人が言っているように、セントを正確に格納する必要がある場合は、floatまたはdoubleを使用せず、int、long、BigInteger、またはBigDecimalを使用してください。

出典:

http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

http://en.wikipedia.org/wiki/Binary64

http://en.wikipedia.org/wiki/Binary32


6から9とはどういう意味ですか?どのようにそれを変えることができますか?したがって、0.000000001のような10進数の8桁のコードを複数回実行すると、異なる結果が得られますか?それはどういう意味ですか?
aequitas 2015年

2
一部の数値は、他の数値よりも2進数で正確に表すことができます。0.125(1 / 8、8は2の累乗)と0.1(1 / 10、10は2の累乗ではない)の違いを確認できます。前者はより多くの(10進数の)桁を持っていますが、正確に表されます。したがって、小数点以下6桁の数値は、8桁の別の数値よりも丸め誤差が大きい可能性があります。
マーカス2015年

9
の場合は15.9の10進数、つまり15と7の場合はdouble7.2ですfloat。それぞれの場合にいくつかの大きな数値を表すことができ、分数には適用されませんが、「平均」はなく、ソースのいずれも言いません。そうでなければ。
user207421 2016年

1
平均という言葉が気に入らない場合は、編集を提案してください。そもそも私が追加したのではなく、他の誰かが編集したのです...(そして私はその編集の必要性を本当に感じませんでした)。
マーカス2016

4
興味深いことに、実際には仮数/仮数に格納されているよりも1桁多い精度があります。23ビットと52ビットはそれぞれfloatとdoubleに格納されますが、数値が正規化されているため、先頭の1ビットを想定して省略できます。これが、実効精度がそれぞれ24ビットと53ビットである理由です。正確な小数精度は、log10(2 ^ 24)= 7.22およびlog10(2 ^ 53)= 15.95で計算されます
Georgie

32

32ビットのfloatの精度は約7桁、64ビットのdoubleの精度は約16桁です。

長い答え:

浮動小数点数には3つの要素があります。

  1. 数値が正か負かを判別するための符号ビット。
  2. 大きさを決定するための指数数値。
  3. 2つの指数値の間の数値の距離を決定する分数。これは、「仮数、仮数、または係数」と呼ばれることもあります

基本的に、これはにうまくいきsign * 2^exponent * (1 + fraction)ます。数値の「サイズ」、つまり指数は、分数部分の値のみをスケーリングするため、私たちには関係ありません。それlog₁₀(n)n†の桁数を与えることを知っていると、浮動小数点数の精度をlog₁₀(largest_possible_fraction)。で決定できます。floatの各ビットには2つの可能性が格納されるため、2進数のnビットには最大2ⁿ - 1(合計値)の数値を格納でき2ⁿ ます。1つがゼロである値のます。浮動小数点数は、使用できるよりも1ビット少ない小数で格納されることが判明したため、これは少し厄介になります。ゼロは特別に表され、すべての非ゼロ数には少なくとも1つの非ゼロバイナリビットがあるためです。‡

これを組み合わせると、浮動小数点数の精度の桁はです log₁₀(2ⁿ)。ここnで、は浮動小数点数の分数のビット数です。32ビットのfloatには、10進数の約7.22桁の精度で24ビットの小数部があり、64ビットのdoubleには、約15.95の10進数の精度で53ビットの小数部があります。

浮動小数点の精度の詳細については、マシンイプシロンの概念について読むことをお勧めします。


n ≥ 1少なくとも—他の数値の場合、数式は次のようになります ⌊log₁₀(|n|)⌋ + 1

‡「このルールは、先行ビット規則、暗黙ビット規則、または隠しビット規則とさまざまに呼ばれます。」(ウィキペディア


17

Java仕様から:

浮動小数点型はfloatとdoubleであり、概念的には、IEEE Standard for Binary Floating-Point Arithmetic、ANSI / IEEEで指定されている単精度32ビットおよび倍精度64ビット形式のIEEE754値と操作に関連付けられています。標準754-1985(IEEE、ニューヨーク)。

IEEE754の基本を理解せずに数字で何かを行うのは難しいので、ここに別のリンクがあります。

精度は均一ではなく、これは整数の場合のように数値を正確に格納するものではないことを理解することが重要です。

例 :

double a = 0.3 - 0.1;
System.out.println(a);          

プリント

0.19999999999999998

任意精度が必要な場合(たとえば、財務目的で)、BigDecimalが必要になる場合があります。


7

通常の数学の答え。

浮動小数点数が指数と残りを表すいくつかのビットとして実装されていることを理解すると、ほとんどの場合(バイナリシステムでは)、次の状況になります。

指数が高く、たとえば最下位ビットが変更された場合は10²³の場合、2つの隣接する識別可能な数値の間に大きな違いが現れます。さらに、基数2の小数点により、多くの基数10の数値は概算しかできません。1 / 5、1 / 10は無限の数です。

したがって、一般的には、有効数字を気にする場合は浮動小数点数を使用しないでください。計算を伴う金額については、e、a、BigDecimalを使用するのが最適です。

以下のために物理ポイント浮動ダブルス適切である、浮くんほとんどありません。さらに、プロセッサの浮動小数点部分であるFPUは、内部でもう少し精度を使用することもできます。


3

浮動小数点数は、指数形式を使用してエンコードさm * b ^ eれます。つまり、整数のようなものではありません。あなたが尋ねる質問は、固定小数点数の文脈で意味があります。利用可能な固定小数点演算ライブラリは多数あります。

浮動小数点演算について:10進数の数は、表示と記数法によって異なります。たとえば0.33333、10進数では有限の表現を持たないが、2進数では有限の表現を持ち、その逆の周期数()があります。

また、それは言及する価値があるポイントにポイント数を浮上することは1より大きく違い、すなわち持っているということであるvalue + 1利回りをvalueするので、value + 1使用してエンコードすることができないm * b ^ e場合は、mbおよびe長さに固定されています。1より小さい値でも同じことが起こります。つまり、考えられるすべてのコードポイントの距離が同じではありません。

このため、10進数のnすべての数値にnIEEEエンコーディングがあるわけではないため、固定小数点数のように正確な桁の精度はありません。

浮動小数点数について説明している、ほぼ必須のドキュメントがあります。 すべてのコンピューター科学者が浮動小数点演算について知っておくべきことです。


2
「すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと」に言及するための+1。ただし、有限の2進数の分数表現を持つすべての数値には、有限の10進数表現もあることに注意しください。問題は10進数から2進数に移行するだけです。
パトリシアシャナハン

1

Float.intBitsToFloatおよびDouble.longBitsToDoubleソートのビットは浮動小数点数に対応する方法を説明しています。特に、通常のビットはfloat次のようになります

 s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW

ここで、A ... Wは23ビット(0と1)で、2進数の分数を表します。sは+/- 1で、それぞれ0または1で表され、expは符号付き8ビット整数です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.