php 浮点数、对象和精度

php floats, objects and precision

进行一些计算并发现了一些奇怪的事情。这是存储在对象中的一些计算数字的转储。

  ["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 做了一些非常非常奇怪的事情。而我 ini_set("precision", 14) 和 php 仍在砍掉小数位。

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

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

Here's a dump of ...

您看到的是数字的字符串表示形式,它们实际上以称为“浮点数”的复杂二进制格式存储。

显示的数字 不是 PHP 内部用来计算更多值的数字。

I've used ini_set("precision", 14)

如果您计算所示示例中的“有效数字”(任何前导零之后),您会发现它们都正好是 14,如您所要求的。

manual page for that setting 说:

The number of significant digits displayed in floating point numbers. -1 means that an enhanced algorithm for rounding such numbers will be used.

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

计算中使用的实际精度是不可配置的,它是PHP的一部分,如果不先理解“浮点数”是什么意思,不容易理解.请参阅标题为“Is floating point math broken?”的参考问题。