PHP 浮点数、对象和精度

php floats, objects and precision

提问人:uPrompt 提问时间:10/29/2021 最后编辑:AbraCadaveruPrompt 更新时间:10/30/2021 访问量:76

问:

玩一些计算,注意到一些奇怪的事情。下面是存储在对象中的一些计算数字的转储。

  ["julianTime"]=>
  float(0.92518518518519)
  ["julian"]=>
  float(2459516.4251852)
  ["j2000"]=>
  float(2021.8245727178)
  ["b1950"]=>
  float(2021.8247835323)
  ["j1900"]=>
  float(2021.8245727178)
  ["delta"]=>
  float(72.316207312938)
  ["terrestrial"]=>
  float(2459516.4251852)
  ["universal"]=>
  float(2459516.4243482)

它似乎正在砍掉小数点以适应特定的长度。使用 JS 在同一台机器上计算相同的数字,我得到这个:

"julianTime": 0.9251851851851852,
"julian": 2459516.4251851854,
"j2000": 2021.8245727178246,
"b1950": 2021.8247835323352,
"j1900": 2021.8245727178246,
"delta": 72.3162073129384,
"terrestrial": 2459516.4251851854,
"universal": 2459516.4243481923,

现在我知道我已经看到 php 和 js 用精确度和 JSON 做了一些非常非常奇怪的事情。而 Ive ini_set(“precision”, 14) 和 php 仍在砍掉小数位。

这是因为它存储在对象中吗???

PHP 对象 精度

评论

0赞 Nico Haase 10/29/2021
你是怎么生成它们的?是什么让你认为JS做完全相同的计算?

答:

1赞 IMSoP 10/30/2021 #1

您的问题中有两个重要的短语:

这是一个垃圾场......

你所看到的是一个数字的字符串表示形式,这些数字实际上以一种称为“浮点”的复杂二进制格式存储。

显示的数字不是 PHP 内部用来计算进一步值的数字。

我用过 ini_set(“precision”, 14)

如果计算所示示例中的“有效数字”(在任何前导零之后),您将看到它们都正好有 14,正如您要求的那样。

该设置的手册页显示:

浮点数中显示的有效位数。-1 表示将使用增强算法对此类数字进行四舍五入。

因此,如果您尝试,您可能会看到不同的结果。不过,它不会更改计算的实际值,只会更改显示。ini_set("precision", -1)

计算中使用的实际精度是不可配置的,它是PHP的一部分,如果不首先了解“浮点”的含义,就不容易理解。请参阅标题为“浮点数学是否损坏?”的参考问题。

评论

0赞 uPrompt 10/30/2021
我假设 ini 设置反映了数字的十进制精度,而不是整数的精度。显然,这意味着如果我的精度为 14 和一个具有 12 个整数的数字,我只能得到 2 个小数点。这对我来说毫无意义。
0赞 IMSoP 10/30/2021
@uPrompt “有效数字”是一个相当普遍的概念,并非PHP所独有。相对而言,0.00000000000002 是 0.000000000000001 的两倍,但 123456789012.002 仅比 123456789012.001 高出百分之一。浮点数的概念使用类似的权衡 - 可以表示的幅度范围更大,但以精度为代价。如果需要高精度数学,则需要使用 GMP 或 BCMath 等库。