【问题标题】:the most accurate approximation of pi in IEEE-754 float64?IEEE-754 float64 中最精确的 pi 近似值?
【发布时间】:2022-07-08 04:41:36
【问题描述】:

在 IEEE-754 float64 中可能最准确的 pi 近似值是多少?

fwiw 似乎 Javascript 和 PHP 都使用 3.141592653589793115997963468544185161590576171875 ,这可能是答案,我不知道。

【问题讨论】:

  • 假设您的意思是binary64(IEEE-754 也提供decimal64)?通过用十进制表示二进制浮点数,您已经失去了“准确性”。适合二进制 64 浮点数的最准确近似值可能最好表示为它的位,而不是十进制转换。
  • 此外,Wikipedia states“53 位有效数字精度提供 15 到 17 位有效十进制数字精度”,因此您在上面引用的任何值(据我计算约为 49 个有效数字)都将是存储在 binary64 fp num 中时显着截断。
  • @spender:用十进制表示任何二进制浮点数都不会损失准确性,除非您没有使用足够的数字或做错了。维基百科将精度描述为“15 到 17 位有效十进制数字”是nonsensical and wrong。此外,良好的 C 实现在将十进制数字转换为浮点数时不会“截断”它们;它们执行 IEEE-754 所称的“正确舍入”转换。
  • 即使 IEEE-754 也不强制使用 all 有效十进制数字。 IIRC,有效十进制数字的最小个数是 +3 将所有 binary64 往返到文本到 binary64 或 17 + 3 所需的数字.IAC,3.1415926535897931159979...的前17位数字将四舍五入到与使用超过17位数字相同的binary64。当仅使用 20 位而不是 21+ 时,其他选择文本值可能会以不同的方式舍入。但是这些文本值接近两个 binary64 值的中间值。

标签: ieee-754 pi


【解决方案1】:

是的,3.141592653589793115997963468544185161590576171875 是最接近 π 的 IEEE-754 二进制 641 数。它也可以写成十六进制浮点常量0x1.921fb54442d18p1。 (我保留了0x3.243f6a8885a308d313198a2e03707344ap0L,以便为更广泛的格式提供价值。)C 标准要求使用以二为底的浮点格式的 C 实现来正确舍入十六进制浮点常量,并且它不需要对于十进制浮点常量,因此当您使用十六进制形式时,您可能更有可能得到正确的结果。

脚注

1 IEEE-754 2008 使用“binary64”作为标准的 64 位 base-2 格式。它也被称为“双精度”。某些编程语言可能将其称为 float64Float64

【讨论】:

  • Detail: base 10 or 16: "对于 decimal 浮动常量,...,结果要么是最接近的可表示值,要么是紧邻的较大或较小的可表示值到最接近的可表示值,以实现定义的方式选择。对于十六进制浮动常量...,结果是正确舍入
  • 我检查了一下,你是对的,IEEE-754-binary64 pi 大约比实际 pi 低 0.0000000000000001,而 IEEE-754-binary64 的下一个可能增量大约是比真实 pi 高 0.0000000000000003 (这是相同数量的零,并且 3 大于 1,这意味着你是对的 :))
【解决方案2】:

@Eric 是正确的,IEEE-754-binary64 pi 大约比实际 pi 低 0.0000000000000001,而 IEEE-754-binary64 的下一个可能增量大约是比实际 pi 高 0.00000000000000003,这两者的零数量相同, 15个0,3大于1,表示Eric+Javascript+PHP都可以。 PHP测试代码证明:

  • 警告,在我的笔记本电脑(i7-8565U,2018 年中档笔记本电脑 CPU)上运行大约需要 10 分钟
  • 警告:未经同行评审,可能有问题
#!/usr/bin/env php
<?php
declare(strict_types=1);
function s($x) {
    $ret = number_format($x, bcscale(), '.', '');
    if(false!==strpos($ret, '.')) {
        $ret = rtrim($ret, '0');
        if(substr($ret, -1)==='.') {
            $ret = substr($ret, 0, -1);
        }
    }
    return $ret;
}
bcscale(100);
$realPi                = "3.141592653589793238462";
$IEEE64Pi              = "3.141592653589793115997";
$nextPossibleIncrement = "3.141592653589793560087";// $nextPossibleIncrement = "3.141592653589793560087173318606801331043243408203125"
$testIncrement         = "0.000000000000000000000001";
// var_dump(bcsub($realPi, $IEEE64Pi));die(); // IEEE64Pi this much LOWER than realPi:                          0.000000000000000122465
 var_dump(bcsub($realPi, $nextPossibleIncrement));die(); // nextPossibleIncrement this much HIGHER than realPi: 0.000000000000000321625

$test = $IEEE64Pi;
for(;;){
    $d1 = (float)$test;
    $new = bcadd($test, $testIncrement);
    $d2 = (float)$new;
    if($d1 !== $d2){
        echo "Error: $test != $new\n";
        echo "d1: ".s($d1)."\n";
        echo "d2: ".s($d2)."\n";
        break;
    }
    $test = $new;
    //echo ".";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2016-05-26
    • 2021-10-06
    • 1970-01-01
    相关资源
    最近更新 更多