2017-04-21 10 views
2

OracleのBINARY_DOUBLEとJavaのDoubleは、IEEE 754標準を使用しています。OracleとJava(IEEE 754)のdouble値の差

しかし、その精度に違いがあります。たとえば値については

456.67d

オラクル:

declare 
    a BINARY_DOUBLE := 456.67d; 
begin 
    SYS.DBMS_OUTPUT.PUT_Line(TO_CHAR(a,'9.99999999999999999999EEEE')); 
end; 

結果:+ 02 4.56670000000000020000E

Javaの:

Double d = 456.67d; 
DecimalFormat formatter = new DecimalFormat("0.000000000000000000000E000"); 
System.out.println(formatter.format(d)); 

結果:Javaで4.566700000000000000000E002

値は、Oracleほど正確ではありません。なぜJavaの精度でOracleのように同じではありません

4.56670000000000015916157281026E2

:?

オンラインコンバータは、456.67dのための最も正確な表現であることを言いましたか そして、私はどのようにJavaでより正確な価値を得ることができますか?

答えて

3

使用BigDecimal

Double d = 456.67d; 
BigDecimal bd = new BigDecimal(d); 
bd.setScale(50); 
System.out.println(bd); 
DecimalFormat formatter = new DecimalFormat("0.000000000000000000000E000"); 
System.out.println(formatter.format(bd)); 

出力:

456.67000000000001591615728102624416351318359375 
4.566700000000000159162E002 
1

どちらが正確です。彼らは単に印刷のために別の戦略を使用します。ここで

はSqueakのSmalltalkのを経由して印刷された正確な値です(ただし、言語は重要ではありません、それは同じ表現と同じ算術です):

d := 456.67. 
{ 
    d predecessor asFraction printShowingMaxDecimalPlaces: 50. 
    d asFraction printShowingMaxDecimalPlaces: 50. 
    d successor asFraction printShowingMaxDecimalPlaces: 50}. 

- >

#(
    '456.6699999999999590727384202182292938232421875' 
    '456.67000000000001591615728102624416351318359375' 
    '456.670000000000072759576141834259033203125' 
)  

だから、任意の10進数表現(d predecessor asFraction + d asFraction)/2 printShowingMaxDecimalPlaces: 50.(d successor asFraction + d asFraction)/2 printShowingMaxDecimalPlaces: 50.の間は、同じ浮動小数点値に丸められます(境界は除外されます。正確な結びつきは最も近い偶数に丸められ、この浮動小数点は奇数であるため...)

だから範囲は以下のとおりです。

#(
    '456.669999999999987494447850622236728668212890625' 
    '456.670000000000044337866711430251598358154296875' 
) 

Oracleはちょうど17桁の数字を使用し、17は任意の二つの倍精度浮動小数点値を区別するために十分であることが知られているので、さらに数字を気にしません。

Javaはもう少し巧妙です。Javaは、表現可能な次の浮動小数点値と区別するのに十分な数字を使用します。したがって、位置17、または4.5666999999999999e2に0,1,2,3または4を置くことは重要ではありませんが、それは依然として同じ浮動小数点値です。

関連する問題