私は、Javaの悪名高いDouble.toStringアルゴリズムの最適化に取り組んでいます。私はすでにFloat.toStringを書き換えて成功しています(速度が400%以上向上しました)。 Float.toStringのアルゴリズムをテストするのは簡単でした。なぜなら、卵を煮沸するのにかかった時間で、可能なすべての値をInteger.MIN_VALUEからInteger.MAX_VALUEにスローすることができるからです。Double.toStringアルゴリズムがすべての値に対して正しいことをどのように証明できますか?
しかし、同じ方法でDouble.toStringをテストすると、Long.MIN_VALUEからLong.MAX_VALUEまで反復処理する必要があります。私はすべてのスレッドでこのテストを開始し、残りの人生で実行することができました。
私はこのアルゴリズムをテストするときに、結果として得られるStringを取得し、java.lang.Double.toString(double d)の結果に対してString.equalsを呼び出すだけです。一致すれば、次の値に移動します。
このアルゴリズムを改良した主な点は、不要な精度をなくすことです。 Double.toStringが計算されると、これを行うために特殊なBigIntegerクラスが使用されます。しかし、私は重要でないビットをトリミングすることによって、パフォーマンスの大幅な向上を伴って同じ結果を得ることができることを発見しました。
私はテストを失敗せずにすべての値を128ビット(トリムビットをオフセットに置き換えて)でトリミングできますが、どのようにすべての値を反復することなくこれを証明できますか?
私は何を求めているのでしょうか?元のアルゴリズムの作成者は、あらゆる可能な入力をテストせずにアルゴリズムが正しいことを絶対確実に知っていましたか?
浮動小数点は実数を表し、0と1の間には実際には**無限の**量があるので、あなたは「そしてそれは終わらないと言っています」と言うのは正しいです。より正確には、任意の2つの実数の間に**無限**の量の他の実数があります。 –
これのもう一つの結果は、浮動小数点数はすべての実数を決して正しく表すことはできません。 floatに格納されている現在の値が0の後にほんのわずかな桁しかない場合、**重要ではない**ビットのみが存在し、バイナリを表すことができます。 0。1は1/10なので、バイナリで表示することはできません。 –
実用的には、JavaではDouble.toStringに2^64の可能な入力があります。これらのいくつかは同じ値(NaN)に解決されます。半分は負です。負と有限の無限大、負と正のゼロがあります。わずかに変更されたLong.toStringアルゴリズムを使用して、いくつかの問題を解決できます。しかし、ほとんどの場合、(b/s)* 10^decExp = double valueのような値bとsを見つけることによって計算されます。小数指数は、必要に応じて見積もられ、調整されます。 – HesNotTheStig