2012-11-24 15 views
5

より大きい値を保持している文字列から、二重の解析:1.7976931348623157E308すべての言及値については、次のJavaコードを考えてみましょうDouble.MaxValue

String toParse = "1.7976931348623157E308"; //max value of a double in java   
double parsed = Double.parseDouble(toParse); 
System.out.println(parsed); 

することは理にかなっていると、一つは正しい出力を取得します。

1.7976931348623158E308(末尾の数字がEより前になる)を解析しようとすると、最大値がコンソールに表示されます。
1.7976931348623159E308を解析しようとした後で(やはり最後の桁が増えた)、大きい方がInfinityになります。
対応する負の値についても同様の動作です。

なぜ... 8E308... 7E308に解析され、Infinityではないのですか?

+1

これはアプリケーションと関連性がありますか? – AlexWien

+1

私は、あなたがエッジケースで楽しいことをしていると思います。あなたはソースコードを見ましたか? –

+0

@AlexWienがちょうど "事故"でこれを見つけました、今私は好奇心です –

答えて

9

parseDoubleドキュメントのSE 7バージョンが言うのvalueOfのドキュメントを指す。また、オーバーフローとアンダーフローの挙動をラウンドツー最も近いルール意味

留意されたいです。 sの正確な値が(MAX_VALUE + ulp(MAX_VALUE)/ 2)以上の大きさであれば、2倍に丸めれば無限大になり、sの正確な値が大きければ小さいほどよりOR)MIN_VALUE/2に等しく、フロートに丸めがゼロになります。

これは、入力に丸めることは、二重フローティングIEEE 754の通常のラウンドへの最も近いルールであることを声明と一致しています

変換は、指数の制限を無視して最も近い浮動小数点数を計算してから、指数が適合するかどうかをチェックすることによって行われます。Double.MAX_VALUEは、それ それよりも厳密に大きい。

次のプログラムを検討し、これは通常の丸め動作であることを確認するには:それは出力

public class Test { 
     public static void main(String[] args) { 
     double ulp = Math.ulp(Double.MAX_VALUE); 
     System.out.println(ulp); 
     System.out.println(Double.MAX_VALUE); 
     System.out.println(Double.MAX_VALUE+ulp/2.0000000001); 
     System.out.println(Double.MAX_VALUE+ulp/2); 
     } 
    } 

を:

1.9958403095347198E292 
1.7976931348623157E308 
1.7976931348623157E308 
Infinity 

をDouble.MAX_VALUEに少しでも半分以下ULPは変わらない何かを追加しますそれ。半分のulpを追加すると、無限にオーバーフローします。

+0

+1のコード例では、これは私の頭の周りを包み込んだ部分でした!ありがとう、パトリシア –

関連する問題