如何以完美的准确度将字符串转换为浮点数?

dsi*_*cha 10 floating-point d floating-accuracy

我正在尝试用D编程语言编写一个函数来替换对C的strtold的调用.(基本原理:要使用来自D的strtold,你必须将D字符串转换为C字符串,这是低效的.另外,strtold不能在编译时执行.)我想出了一个主要有效的实现,但是我似乎在最不重要的位上失去了一些精确度.

算法的有趣部分的代码如下,我可以看到精度损失来自哪里,但我不知道如何摆脱它.(我遗漏了许多与核心算法无关的代码部分,以节省人们的阅读.)什么字符串到浮点算法将保证结果尽可能接近IEEE编号line到字符串表示的值.

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;
Run Code Online (Sandbox Code Playgroud)

此外,我正在使用旧版本的单元测试,其中包括:

assert(to!(real)("0.456") == 0.456L);
Run Code Online (Sandbox Code Playgroud)

我的函数生成的答案是否有可能比解析浮点文字时编译器生成的表示更准确,但编译器(用C++编写)总是与strtold完全一致,因为它在内部使用strtold进行解析浮点文字?

Dou*_*rie 10

ClingerSteele&White开发了用于读写浮点的精细算法.

有一个回顾展在这里一起实现的一些参考文献一起.

David Gay的论文改进了Clinger的工作,而Gay 在C中的实现也很棒.我已经在嵌入式系统中使用它们,我相信Gay已经dtoa进入了许多libc人的行列.

  • 既然你写了这个答案,就会发现一个比Gay更有效的算法来打印浮点数的最短规范值!也许更新你的答案以反映这一点?请参见"使用整数快速准确地打印浮点数":http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf (2认同)

Mar*_*ett -1

您无法在数字计算机中以完美的精度存储大多数浮点数