【问题标题】:why pow(3^47) gives wrong answer? [duplicate]为什么 pow(3^47) 给出错误的答案? [复制]
【发布时间】:2013-08-06 09:32:43
【问题描述】:

使用php,这段代码echo sprintf('%.9F',pow(3,47));输出26588814358957501972480.000000000

this 这样的其他网站提供3^47 = 26588814358957503287787。 PHP有什么错误吗?如何解决?

顺便说一句,我想知道 php 可以使用 pow、sprintf、fmod 进行计算的最大位数是多少。是300位吗?

【问题讨论】:

  • 这可能来自转换为浮点数(表示问题)。
  • @ComFreek 你能帮我找一个替代品吗?
  • 这是计算机中的一个错误:除非您明确告诉他们使用十进制,否则他们有这种愚蠢的默认习惯,即使用二进制而不是十进制工作
  • @MarkBaker:这不是“错误”,而是“功能”!

标签: php


【解决方案1】:

您需要使用外部程序或 PHP 扩展(库)。

我刚刚使用bcpow()/gmp_pow() 函数对BC MathGMP 进行了测试,它运行良好:

<?php

// both output 26588814358957503287787
echo bcpow('3', '47');

echo gmp_strval( gmp_pow('3', '47') );

PHP.net 文档中有一个关于该主题的精彩部分:

浮点精度

浮点数的精度有限。虽然这取决于 系统,PHP 通常使用 IEEE 754 双精度格式, 由于顺序四舍五入,这将给出最大的相对误差 1.11e-16。非初等算术运算可能会给出更大的 错误,当然,必须考虑错误传播 几个操作是复合的。

此外,有理数可以精确表示为 以 10 为底的浮点数,例如 0.10.7,没有 精确表示为以 2 为底的浮点数,即 内部使用,无论尾数大小。因此,他们 如果没有 精度损失小。这可能会导致令人困惑的结果:对于 例如,floor((0.1+0.7)*10) 通常会返回 7 而不是 预期 8,因为内部表示将类似于 7.9999999999999991118...

所以永远不要相信浮点数结果到最后一位,也不要 直接比较浮点数是否相等。如果更高 精度是必要的,arbitrary precision math functionsgmp 功能可用。

有关“简单”的解释,请参阅» floating point guide,这也是 标题为“为什么我的数字不加起来?”
http://php.net/manual/en/language.types.float.php

注意php.ini configuration value 'precision'在从浮点数转换为字符串时也可以修改精度。

【讨论】:

    【解决方案2】:

    bcpow()BCMath Arbitrary Precision Mathematics 库的一个函数)可以在这种情况下使用。

    echo bcpow('3', '47'); //as mentioned in ComFreek's answer
    //outputs 26588814358957503287787 
    

    pow 在这里不起作用的原因是因为pow() 使用了float,并且float 有大小限制。

    查看PHP Manual的这段摘录:

    float 的大小取决于平台,但最大约为 1.8e308 且精度约为 14 位十进制数字是常用值(64 位 IEEE 格式)

    换句话说,最大可能大小可能会有所不同——即(对于 32 位和 64 位系统可能不同)。

    希望能回答您的问题!

    【讨论】:

      猜你喜欢
      • 2016-04-13
      • 1970-01-01
      • 2020-12-01
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多