【问题标题】:How do calculators work with precision?计算器如何精确工作?
【发布时间】:2011-02-12 09:46:58
【问题描述】:

我想知道计算器如何精确地工作。例如,sin(M_PI) 的值在以double 精度计算时不完全为零:

#include <math.h>
#include <stdio.h>

int main() {
    double x = sin(M_PI);
    printf("%.20f\n", x); // 0.00000000000000012246
    return 0;
}

现在我当然想在用户输入 sin(π) 时打印零。我可以轻松地在 1e–15 上的某个地方四舍五入,以使这个特定案例工作,但这是一个 hack,而不是解决方案。当我开始像这样四舍五入并且用户输入类似 1e-20 的内容时,他们得到一个零(因为四舍五入)。当用户输入 1/10 并反复按 = 键时,也会发生同样的情况 — 当他达到舍入阈值时,他得到零。

然而,有些计算器会为 sin(π) 返回纯零,同时它们可以轻松地处理诸如 (1e–20)/10 之类的表达式。诀窍在哪里?

【问题讨论】:

  • 你在说哪些计算器?
  • 例如 iPod 和 iPhone 附带的计算器。

标签: floating-point precision calculator


【解决方案1】:

可以在Calculator Precision 页面上找到一些答案。

解决方案包括:

  • 在 BCD 中工作
  • 使用查找表
  • 使用隐藏数字,使显示的数字准确

【讨论】:

  • BCD 并不比二进制更准确;优点是它模仿了纸笔计算,因此您可以得到完全相同的准确性或不准确性。
  • 对于二进制,比 BCD 更不准确的来源之一:这是结果从 base-2 到 base-10 的转换。
  • 用十进制数表示的相对精度,例如六位有效数字可能从大约百万分之一(如果尾数为 9.99999)到百万分之十(如果为 1.00000)变化近十倍。二进制浮点数的相对精度仅变化两倍。因此,为了使二进制表示在所有情况下都与十进制一样准确,在某些情况下它必须是十倍(如果不是二十倍)的准确度。但是,使用 BCD 并没有真正的帮助。以确保在所有中间计算中具有一定程度的相对精度......
  • ...在许多情况下最终需要一个“额外”数字;即便如此,精度的巨大差异通常也会导致其自身的问题。
【解决方案2】:

桌面计算器使用任意精度的数学库。这些可以配置为具有更高的两倍精度。手持计算器(传统专用和手机)使用固定精度数学库。

如果你想精确地打印零,请使用宽度说明符

printf (%12.4d, number);

【讨论】:

  • 取决于计算器。例如,Mathematica 以任意精度进行计算(如其文档所述,例如 Numeric Precision 教程)。我敢肯定还有其他计算器可以做同样的事情,还有一些使用高精度(但不是任意精度)库,也许还有一些只做常规浮点数学。
  • @Mark:嗯,问题是关于软件计算器,而 Mathematica 只是同一概念的概括。不过,无论您如何定义“计算器”,不同的计算器可能会使用不同的精度。
  • @High Performance Mark:ubuntu 上的默认计算器使用任意精度的数学库,因此我选择概括这个想法。
【解决方案3】:

如前所述,诀窍可能是计算器将使用arbitrary precision 数学库或lookup tables

我还要补充一点,由于使用了 floating point 算术,您的代码 sn-p 以这种方式工作,您可能知道这不是 true 数学,因为它不精确 - @987654324 @(实际上是 1.1000000000000001):)

【讨论】:

    【解决方案4】:

    他们可能正在使用查找表来加速他们的三角公式。在那种情况下,效果很好的特殊数字可能就在表格中。

    【讨论】:

      猜你喜欢
      • 2020-10-24
      • 2014-07-27
      • 2020-11-26
      • 2013-10-02
      • 2016-12-01
      • 1970-01-01
      • 2018-01-13
      • 2019-08-17
      • 1970-01-01
      相关资源
      最近更新 更多