C の strtold への呼び出しを置き換えるために、D プログラミング言語で関数を作成しようとしています。(理論的根拠: D から strtold を使用するには、D 文字列を C 文字列に変換する必要がありますが、これは非効率的です。また、コンパイル時に strtold を実行することはできません。)最下位ビットの精度がいくらか失われるようです。
アルゴリズムの興味深い部分のコードを以下に示します。精度の低下の原因はわかりますが、それを取り除く方法はわかりません。(読みやすくするために、コア アルゴリズムに関係のないコードの多くの部分を省略しました。) string-to-float アルゴリズムは、結果が IEEE 番号にできるだけ近いことを保証します。行を文字列で表される値に変更します。
real currentPlace = 10.0L ^^ (pointPos - ePos + 1 + expon);
real ans = 0;
for(int index = ePos - 1; index > -1; index--) {
if(str[index] == '.') {
continue;
}
if(str[index] < '0' || str[index] > '9') {
err();
}
auto digit = cast(int) str[index] - cast(int) '0';
ans += digit * currentPlace;
currentPlace *= 10;
}
return ans * sign;
また、古いバージョンの単体テストを使用しています。これは次のようなことを行いました。
assert(to!(real)("0.456") == 0.456L);
私の関数によって生成される答えは、浮動小数点リテラルを解析するときにコンパイラが生成する表現よりも実際には正確である可能性がありますが、コンパイラ (C++ で記述されている) は常に strtold と正確に一致します。浮動小数点リテラル?