是否有可以在一条指令中执行 * 10^n 的融合指令?

is there a fused instruction that can perform a * 10^n in a single instruction?

在任何 C 派生语言中调用 a * pow(10.0, n) 会导致两个舍入错误,但我只需要一个舍入错误,因为可以由单个融合指令提供。

例如 a=39762108874335653 n=-297 应该给出 3.9762108874335653E-281 (可以通过解析字符串 "3.9762108874335653E-281" 或使用任意精度算法并输出浮点数来验证)但是引用的代码returns 3.976210887433566E-281.

这又回到了问题:是否有融合指令(或 C 函数)可以以机器可能的最高精度执行此计算?

我只关心an是整数,结果是双精度浮点数的情况。请注意,a 可能无法准确表示为浮点数。

转换为字符串并解析不是一个可接受的解决方案(它太慢了),也不是使用任意精度库(例如 Java 的 BigDecimal,也因为它太慢)。

请注意,有一个类似的 C stdlib 函数,ldexp(与 scalbn 相关)它使用 base2,因此计算 a * 2^n 作为单个融合指令。

我知道 https://en.wikipedia.org/wiki/C_mathematical_functions

中列出的说明

不是 Is floating point math broken? 的骗局,这不是要了解四舍五入的原理。它只是在问:这个函数是否存在于任何地方,最好是在 CPU 融合指令中以获得最佳性能?显然,在没有这种情况的情况下,解决方法是使用任意精度,但这是相当重量级的。

答案是“否”,正如@eric-postpischil in chat and the evidence for this can be backed up by the fact that standard libraries would use it if it were available, e.g. glibc strtod

回答的那样,没有一条指令可以执行此操作

然而,虽然没有单个 CPU 指令,但可以提取 strtod 实现以按照此问题中的要求对整数输入进行操作,正如 Alex Huszagh 在 Rust 中所做的那样.此处讨论的算法有效地使用 a * pow(10.0, n) 当有效数字被估计足够小时(首选负 n 的除法)并回退到收敛算法以消除舍入误差。