在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命令行并在那里运行时才会这样。
答案 0 :(得分:3)
这两个数字都远高于最大可表示的有限IEEE 754双精度值,大约是1.79769e + 308。没有什么理由将“1E1000000000000000000000000000”转换为双精度,尽管在安全敏感的上下文中,当允许攻击者输入要转换为浮点的字符串时,这可能是一个很好的拒绝服务攻击之后,转换需要的时间比程序员想象的要多。
由于没有理由将“1E1000000000000000000000000000”转换为双精度,您尝试的其中一个实现没有实现包含识别这种情况的优化,并且在实现之前实际上进行了大量计算(*)这个数字远远大于可以表示的数字。而其他更聪明的实现早期检测到十进制指数太大,最终结果只能是+inf
,并且提前返回。
要寻找的另一个有趣的输入是“0.000 <10000零点&gt; 1E10000”。在这种情况下,错误的“优化”版本可能会错误地返回+inf
。
另一个有趣的角落案例是“0E1000000000000000000”,它不应该返回除0.0
以外的其他任何内容。
(*)将十进制转换为二进制浮点比大多数人意识到的更微妙。请参阅this series of blog posts。