Han*_*etz 4 php floating-point arithmetic-expressions
我只是"修复"以下几行PHP中的错误:
$value = 1091.09; // the failing test case
$prop = sprintf('%013d', $value * 100);
Run Code Online (Sandbox Code Playgroud)
通过添加这些行:
$cents = $value * 100; // $cents is now 109109
$cents = round($cents, 2); // $cents is still 109109
$prop = sprintf('%013d', $cents);
Run Code Online (Sandbox Code Playgroud)
前一个块的结果是"0000000109108",而第二个块的结果"0000000109109"是正确的.
请注意,我添加了两行,以便能够分别查看调试器中的每个步骤.如果我跳过第一行,它也有效,因此写道:
$cents = round($value * 100, 2); // $cents is now 109109
$prop = sprintf('%013d', $cents);
Run Code Online (Sandbox Code Playgroud)
因此,显然,该round()函数会对值进行某些操作,使其以不同的方式工作sprintf().它是什么?
如果这是一种恰当的语言,我可能会通过查看数据类型来了解.在这里,我甚至都不知道它们是什么.
初始数据类型为float64.
乘以100后,它仍然是一个浮点数.
打印(使用echo/print_r/var_dump)该值不会打印绝对精确值(109108.9999999999999); 它会打印近似的浮点值,109109因为浮点数本身就是近似值而不是精确值.
使用sprintf将其作为int打印会触发类型转换为int,从而截断109108.9999999999999to 的值109108.
因此你的问题.
PHP支持的基本类型是使用处理程序变量和引用计数容器构造的.除此之外,他们是相当低级的东西.
没有理由认为它们比它们出现的"更复杂".我开始考虑复杂的对象而不是标量数据类型.
另外一个很大的混淆因素是(隐式)类型转换和所有类型转换规则(包括可以作为布尔值传递的所有内容).
第Ex.I:
-1 == false // true
null == false // true
-1 != null // false
Run Code Online (Sandbox Code Playgroud)
例2:
0 == false // true
0 === false // false
Run Code Online (Sandbox Code Playgroud)