不同的pi值?

Different values of pi?

ini_set('precision', 64);    
echo M_PI."<br>";
echo pi()."<br>";
echo "3.14159265358979323846264338327950<br>";

作为参考,我使用了 http://www.eveandersson.com/pi/digits/100

如果比较输出,您会得到以下结果:

3.1415926535898
3.141592653589793115997963468544185161590576171875
3.14159265358979323846264338327950

那么pi()的精度值是怎么回事呢?它似乎完全关闭了。是的,我知道 pi 是无理数,但至少要准确到 100 位有效数字?

任何人都可以确认这个问题,并且可以解释为什么在 php 中的 16 位后会出错吗?

"problem" 是 M_PI 的值(与 pi() 返回的值相同)是硬编码的。

来自 php_math.h 文件:

#ifndef M_PI
#define M_PI           3.14159265358979323846  /* pi */
#endif

更改精度不会更改已定义的常量值。此外,通常的 "how are float/double numbers are stored" 仍然适用。

在 bcmath 扩展手册页中介绍了以下内容:

//bcpi function with Gauss-Legendre algorithm
//by Chao Xu (Mgccl)

function bcpi($precision){
  $n=0;
    $limit = ceil(log($precision)/log(2))-1;
    bcscale($precision+6);
    $a = 1;
    $b = bcdiv(1,bcsqrt(2));
    $t = 1/4;
    $p = 1;
    while($n < $limit){
        $x = bcdiv(bcadd($a,$b),2);
        $y = bcsqrt(bcmul($a, $b));
        $t = bcsub($t, bcmul($p,bcpow(bcsub($a,$x),2)));
        $a = $x;
        $b = $y;
        $p = bcmul(2,$p);
        ++$n;
    }
    return bcdiv(bcpow(bcadd($a, $b),2),bcmul(4,$t),$precision);
}

echo bcpi(64);
echo "<br>3.1415926535897932384626433832795028841971693993751058209749445923";

因此,似乎 ini_set('precision',64);不会对常规 php 数学函数 (>15) 做任何有建设性的事情,但 bcmath 扩展会完全忽略该设置。

所以要精确工作 >= 16 使用 bcmath 扩展 否则 ini_set 最多 15

@Progman 的回答是 float/double 存储规则仍然适用 - 意味着小数点后 15 位有上限(即使 php 将所有浮点数存储为双精度数)