PHP 0.0 和 0.00 有什么区别吗?

PHP is there any difference between 0.0 and 0.00?

提问人:jave.web 提问时间:4/6/2023 更新时间:4/6/2023 访问量:122

问:

考虑到 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 C 浮点 精度

评论

0赞 deceze 4/6/2023
为什么不允许这样的语法?无论你写什么,都会被转换为一个内部浮点值(这与你输入的内容无关),多余的小数位在这个过程中会被截断。无论你用什么方式写它,它都有零的数值,这是唯一存储在内部的东西。
0赞 jave.web 4/6/2023
因为它可能意味着浮点数的精确设置(据我所知,这在 PHP 中是固定的)。所以没有技术差异,也没有后果?
1赞 Weather Vane 4/6/2023
使用的小数位数仅与数学家或工程师有关,并意味着数据的准确性。例如,当被程序解析时,它们比更准确,但它们是相同的。1.2001.2
1赞 Eric Postpischil 4/6/2023
@deceze:这个问题没有问这种语法是否被允许;它明确指出它是有效的。它询问定义之间是否存在差异。事实上,由于 PHP 没有正式的规范,PHP 通常使用 C 实现,而 C 标准允许为不同形式的浮点文字生成不同的值,这些值名义上具有相同的值。strtod
2赞 Eric Postpischil 4/6/2023
这个问题被错误地投了反对票。它提出了一个有效的问题,其答案实际上是,不同的浮点文字可能会产生不同的值,即使它们名义上表示相同的值,因为没有规定它们必须产生相同的值。

答:

2赞 Eric Postpischil 4/6/2023 #1

PHP 没有正式的规范。因此,没有正式的规范表示和解析为相同的值。虽然这不太可能用于 和 ,但还有其他浮点文字,即使这些文字名义上表示相同的值,其解析可能会产生不同的值,如下所述。0.00.000.00.00

PHP的手动版本似乎对浮点文字的解析几乎没有什么说法。(我没有检查整个文档,只检查了“类型系统”部分的“浮点数”小节。

PHP 通常使用 C 实现。C 标准允许不同源形式的浮点文字产生不同的值,即使它们名义上指定相同的数字。这是由于 C 2018 6.4.4.2 5 中的遗漏,它说相同形式的文字产生相同的数字,“相同源形式的所有浮点常数77) 应转换为具有相同值的相同内部格式”,但省略了指定不同形式但相同标称值的“常量”转换为相同值。脚注 77 是非规范性的,它明确指出:“、 和都是不同的源形式,因此不需要转换为相同的内部格式和值。1.231.230123e-2123e-021.23L

PHP 源代码当然不是 C 源代码。但是,对于C语言的PHP实现来说,使用标准的C库工具来解析PHP源代码是很自然的。特别是,我们可能会发现用于解析浮点文字。然后,我们面临着参考上述 6.4.4.2 中的规则指定的事实。C 2018 7.22.1.3 规定 ,第 5 段说:strtodstrtodstrtod

...根据 6.4.4.2 的规则,以第一位数字或小数点字符(以先出现者为准)开头的字符序列被解释为浮点常数,...

允许不同的形式可能产生不同的值,主要是考虑到解析指数符号的历史困难。 和名义上是相同的值。但是,解析后者很困难,因为 1040 不能以通常用于硬件浮点的格式表示。它需要 81 位有效位,而普通硬件中最宽的有效位通常为 53 或 64 位。因此,像这样的文字不能仅仅通过计算有效数的值并乘以或除以指数的值来解析。因此,必须专门设计能够使用正确舍入解析浮点值的软件。在编写上面引用的 C 标准段落时,预计解析浮点数不会以产生正确舍入结果所需的严格性来完成。今天,由于学术研究,此类软件已为人所知并可用。但是,它不一定存在于标准 C 库的所有实现中。4.242000000000000000000000000000000000000000e-40

我期望并产生相同的值,正好为零,因为对有效数的解析将产生零,并且计算指数符号或非常长的有效数的结果的困难不会影响零。同样,我希望即使是适度的解析软件也能产生相同的值,因为所涉及的计算完全在所有必需值都可以用硬件浮点格式表示的范围内,前提是计算为 138 / 100 而不是 138 • .01。但是,如果这在业余软件中不成立,也就不足为奇了。0.00.001.38138e-2138e-2

但是,对于大量级的指数,只有当软件是故意为此目的使用已发布的算法编写时,我才期望相同数量的不同形式的相等。

评论

0赞 jave.web 4/6/2023
感谢您理解问题的核心 - 您是否暗示如果解析器能够解析数字 - 无论浮点数周围的前导或附加 s 始终如此。基本上,丢弃了?0
0赞 Eric Postpischil 4/6/2023
@jave.web:不,PHP手册和C标准都没有要求这样做,而且糟糕的软件可能会产生与for不同的值。4.24.2000000000000000000000000000000000000000