使用php,此代码echo sprintf('%.9F',pow(3,47));
输出26588814358957501972480.000000000
像这样的其他网站所提供的3^47 = 26588814358957503287787
。PHP有什么错误吗?如何解决?
顺便说一句,我想知道 php 可以使用 pow、sprintf、fmod 进行计算的最大位数是多少。是300位数吗?
您需要使用外部程序或 PHP 扩展(库)。
我刚刚使用bcpow() / gmp_pow()函数使用BC Math和GMP对其进行了测试,它运行良好:
<?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.1或0.7,没有精确表示为以 2 为底的浮点数,无论尾数大小如何,它都在内部使用。因此,它们不能被转换成它们内部的二进制对应物,而不会有小的精度损失。这可能会导致令人困惑的结果:例如,floor((0.1+0.7)*10)通常会返回7而不是预期的8,因为内部表示将类似于 7.9999999999999991118...。
所以永远不要相信浮点数结果到最后一位,也不要直接比较浮点数是否相等。如果需要更高的精度,可以使用任意精度的数学函数和gmp 函数。
对于“简单”的解释,请参阅同样标题为“为什么我的数字不加起来?”的 浮点指南。
— http://php.net/manual/en/language.types.float.php
请注意,php.ini 配置值 'precision'在从浮点数转换为字符串时也可以修改精度。
bcpow()
(BCMath 任意精度数学库的一个函数)可以在这种情况下使用。
echo bcpow('3', '47'); //as mentioned in ComFreek's answer
//outputs 26588814358957503287787
pow
在这里不起作用的原因是因为pow()
使用float
,并且有大小限制float
。
请参阅PHP 手册的摘录:
浮点数的大小取决于平台,尽管最大约为 1.8e308 且精度约为 14 位十进制数字是常见值(64 位 IEEE 格式)
换句话说,最大可能大小可能会有所不同——即(对于 32 位和 64 位系统可能不同)。
希望这能回答你的问题!