是的,只要这些操作是EXACT ,您就可以将构造分解为浮点操作,并且您可以负担一个最终的不精确操作。
不幸的是,浮点运算很快就会变得不精确,当你超过尾数的精度时,结果会被四舍五入。一旦引入了舍入“错误”,它将在进一步的操作中累积......
所以,一般来说,不,你不能使用这种幼稚的算法来转换任意小数,这可能会导致不正确的舍入数字,相差几个正确的 ulp,就像其他人已经告诉你的那样。
但让我们看看我们能走多远:
如果您像这样仔细重建浮点数:
if(biasedExponent >= 0)
return integerMantissa * (10^biasedExponent);
else
return integerMantissa / (10^(-biasedExponent));
在累积整数尾数(如果它有很多位)以及将 10 提高到biasedExponent 的幂时,都存在超过精度的风险......
幸运的是,如果前两个运算是精确的,那么您可以承受最终的不精确运算 * 或 /,这要归功于 IEEE 属性,结果将被正确舍入。
让我们将其应用于精度为 24 位的单精度浮点数。
10^8 > 2^24 > 10^7
注意 2 的倍数只会增加指数而尾数保持不变,我们只需要处理 5 的幂即可获得 10 的幂:
5^11 > 2^24 > 5^10
不过,您可以在 integerMantissa 中提供 7 位精度和 -10 到 10 之间的 biasedExponent。
双精度,53 位,
10^16 > 2^53 > 10^15
5^23 > 2^53 > 5^22
所以你可以负担得起 15 个十进制数字,以及 -22 和 22 之间的有偏指数。
看你的数字是否总是在正确的范围内由你决定......(如果你真的很棘手,你可以通过插入/删除尾随零来安排尾数和指数的平衡)。
否则,您将不得不使用一些扩展精度。
如果您的语言提供任意精度整数,那么要正确处理它有点棘手,但并不难,我在 Smalltalk 中做了这个,并在http://smallissimo.blogspot.fr/2011/09/clarifying-and -optimizing.html和http://smallissimo.blogspot.fr/2011/09/reviewing-fraction-asfloat.html
请注意,这些都是简单而幼稚的实现。幸运的是,libc 更加优化。