为什么在VxWorks中给出大数字时strtod会冻结?

时间:2015-07-16 18:22:30

标签: floating-point vxworks

在VxSim中,当我运行strtod(“1E1000000”,0)(在stdlib.h中)它运行得非常快(并返回1),而strtod(“1E1000000000000000000000000000”,0)大约需要20秒,然后返回1有时它总是很快并且返回非零值,然后按ctrl-c并重置shell将使它再次变慢。

为什么会这样?在其他操作系统中,两者都接近瞬间。

当你运行时,我正在玩这个,还有VxSim:

strtod("10", 0)
strtod("10", 0)
strtod("10", 0)
strtod("10", 0)
strtod("10", 0)
strtod("10", 0)
strtod("10", 0)
strtod("10", 0)

最后一个给你:

value = 1615516944 = 0x604ad510

我在硬件上测试了这个并没有发生,因此在VxSim中可能是一个错误。

另外,编译它也不会给你带来错误。只有当您手动将这些键入VxWorks命令行并在那里运行时才会这样。

1 个答案:

答案 0 :(得分:3)

这两个数字都远高于最大可表示的有限IEEE 754双精度值,大约是1.79769e + 308。没有什么理由将“1E1000000000000000000000000000”转换为双精度,尽管在安全敏感的上下文中,当允许攻击者输入要转换为浮点的字符串时,这可能是一个很好的拒绝服务攻击之后,转换需要的时间比程序员想象的要多。

由于没有理由将“1E1000000000000000000000000000”转换为双精度,您尝试的其中一个实现没有实现包含识别这种情况的优化,并且在实现之前实际上进行了大量计算(*)这个数字远远大于可以表示的数字。而其他更聪明的实现早期检测到十进制指数太大,最终结果只能是+inf,并且提前返回。

要寻找的另一个有趣的输入是“0.000 <10000零点&gt; 1E10000”。在这种情况下,错误的“优化”版本可能会错误地返回+inf

另一个有趣的角落案例是“0E1000000000000000000”,它不应该返回除0.0以外的其他任何内容。

(*)将十进制转换为二进制浮点比大多数人意识到的更微妙。请参阅this series of blog posts