提问人:jave.web 提问时间:4/6/2023 更新时间:4/6/2023 访问量:122
PHP 0.0 和 0.00 有什么区别吗?
PHP is there any difference between 0.0 and 0.00?
问:
考虑到 PHP8.1+,所有语法都有效:
var_dump(0.0); // outputs float(0)
var_dump(0.00); // also outputs float(0)
var_dump(0.0000000); // --||--
// ...
这些定义之间是否存在任何技术差异(即使在 C 背景中)?
它是否以某种方式影响精度或根本不影响精度?- 如果不是 - 为什么允许这样的语法?
这与这是双向的有什么关系吗?:也是有效的语法...var_dump(000042.42000000);
答:
PHP 没有正式的规范。因此,没有正式的规范表示和解析为相同的值。虽然这不太可能用于 和 ,但还有其他浮点文字,即使这些文字名义上表示相同的值,其解析可能会产生不同的值,如下所述。0.0
0.00
0.0
0.00
PHP的手动版本似乎对浮点文字的解析几乎没有什么说法。(我没有检查整个文档,只检查了“类型系统”部分的“浮点数”小节。
PHP 通常使用 C 实现。C 标准允许不同源形式的浮点文字产生不同的值,即使它们名义上指定相同的数字。这是由于 C 2018 6.4.4.2 5 中的遗漏,它说相同形式的文字产生相同的数字,“相同源形式的所有浮点常数77) 应转换为具有相同值的相同内部格式”,但省略了指定不同形式但相同标称值的“常量”转换为相同值。脚注 77 是非规范性的,它明确指出:“、 和都是不同的源形式,因此不需要转换为相同的内部格式和值。1.23
1.230
123e-2
123e-02
1.23L
PHP 源代码当然不是 C 源代码。但是,对于C语言的PHP实现来说,使用标准的C库工具来解析PHP源代码是很自然的。特别是,我们可能会发现用于解析浮点文字。然后,我们面临着参考上述 6.4.4.2 中的规则指定的事实。C 2018 7.22.1.3 规定 ,第 5 段说:strtod
strtod
strtod
...根据 6.4.4.2 的规则,以第一位数字或小数点字符(以先出现者为准)开头的字符序列被解释为浮点常数,...
允许不同的形式可能产生不同的值,主要是考虑到解析指数符号的历史困难。 和名义上是相同的值。但是,解析后者很困难,因为 1040 不能以通常用于硬件浮点的格式表示。它需要 81 位有效位,而普通硬件中最宽的有效位通常为 53 或 64 位。因此,像这样的文字不能仅仅通过计算有效数的值并乘以或除以指数的值来解析。因此,必须专门设计能够使用正确舍入解析浮点值的软件。在编写上面引用的 C 标准段落时,预计解析浮点数不会以产生正确舍入结果所需的严格性来完成。今天,由于学术研究,此类软件已为人所知并可用。但是,它不一定存在于标准 C 库的所有实现中。4.2
42000000000000000000000000000000000000000e-40
我期望并产生相同的值,正好为零,因为对有效数的解析将产生零,并且计算指数符号或非常长的有效数的结果的困难不会影响零。同样,我希望即使是适度的解析软件也能产生相同的值,因为所涉及的计算完全在所有必需值都可以用硬件浮点格式表示的范围内,前提是计算为 138 / 100 而不是 138 • .01。但是,如果这在业余软件中不成立,也就不足为奇了。0.0
0.00
1.38
138e-2
138e-2
但是,对于大量级的指数,只有当软件是故意为此目的使用已发布的算法编写时,我才期望相同数量的不同形式的相等。
评论
0
4.2
4.2000000000000000000000000000000000000000
评论
1.200
1.2
strtod