稍微转向浮点(im)精度,第1部分

时间:2008-08-04 06:21:38

标签: math language-agnostic floating-point

大多数数学家都同意:

  

e πi + 1 = 0

但是,大多数浮点实现都不同意。我们如何解决这一争议?

我很想知道不同的语言和实现,以及使结果尽可能接近零的各种方法。要有创意!

10 个答案:

答案 0 :(得分:17)

并非大多数浮点实现都不同意,只是他们无法获得获得100%答案所需的准确性。而正确的答案是他们不能。

PI是一个无限的数字系列,除了符号表示之外,任何人都无法表示,而且^ ^ X是相同的,因此获得100%准确度的唯一方法就是符号化。 / p>

答案 1 :(得分:10)

这是我尝试过的一系列实现和语言的简短列表。按接近零排序:

  • 方案:(+ 1 (make-polar 1 (atan 0 -1)))
    • 0.0+1.2246063538223773e-16i(Chez Scheme,麻省理工学院计划)
    • 0.0+1.22460635382238e-16i(Guile)
    • 0.0+1.22464679914735e-16i(带有numbers鸡蛋的鸡肉)
    • 0.0+1.2246467991473532e-16i(MzScheme,SISC,Gauche,Gambit)
    • 0.0+1.2246467991473533e-16i(SCM)
  • Common Lisp:(1+ (exp (complex 0 pi)))
    • #C(0.0L0 -5.0165576136843360246L-20)(CLISP)
    • #C(0.0d0 1.2246063538223773d-16)(CMUCL)
    • #C(0.0d0 1.2246467991473532d-16)(SBCL)
  • Perl:use Math::Complex; Math::Complex->emake(1, pi) + 1
    • 1.22464679914735e-16i
  • Python:from cmath import exp, pi; exp(complex(0, pi)) + 1
    • 1.2246467991473532e-16j(CPython)
  • Ruby:require 'complex'; Complex::polar(1, Math::PI) + 1
    • Complex(0.0, 1.22464679914735e-16)(MRI)
    • Complex(0.0, 1.2246467991473532e-16)(JRuby)
  • R:complex(argument = pi) + 1
    • 0+1.224606353822377e-16i

答案 2 :(得分:7)

是否有可能解决这一争议?

我的第一个想法是寻找一种符号语言,如Maple。我认为这不算浮点数。

事实上,如何用传统的编程语言代表 i (或工程师的 j )?

也许一个更好的例子是罪(π)= 0? (或者我是否再次错过了这一点?)

答案 3 :(得分:5)

你的问题对我来说似乎有些奇怪,因为你似乎在暗示浮点数学是由语言实现的。这通常不正确,因为FP数学是使用硬件中的浮点处理器完成的。但是软件或硬件,浮点总是不准确的。这就是浮动的工作原理。

如果您需要更高的精度,则需要使用不同的数字表示。就像你在不适合int或long的数字上做整数数学一样。有些语言有内置的库(我知道java有BigInteger和BigDecimal),但是你必须明确地使用那些库而不是本机类型,并且性能会(有时显着)比使用浮点数时更差。 / p>

答案 4 :(得分:5)

我同意Ryan,你需要转移到另一个号码表示系统。解决方案超出了浮点数学的范围,因为你需要pi表示为无限长的小数,所以任何有限的精度方案都不会起作用(至少没有使用某种软糖因子来弥补丢失精度)。

答案 5 :(得分:4)

我和我最好的朋友谈论非理性数字以及其他数字之间的差异。好吧,我们俩都同意这个不同的观点:

无理数是关系,作为函数,在某种程度上,是什么方式?好吧,想想"如果你想要一个完美的圆圈,给我一个完美的pi",但圆圈与其他数字不同(4边,5,6 ... 100,200)但是......你有多少个侧面,更像是一个圆圈。如果你到目前为止跟着我,在这里连接所有这些想法是pi公式: enter image description here

所以,pi是一个功能,但永远不会结束!因为∞参数,但我想你可以拥有"实例"如果你改变一个非常大的Int的∞参数,你将有一个非常大的pi实例。

与e相同,给我一个巨大的参数,我会给你一个巨大的e。

将所有想法放在一起:

由于我们有内存限制,语言和库提供给我们巨大的无理数的实例,在这种情况下,pi和e,作为最终结果,你将有很长的时间获得0,就像@Chris提供的例子一样小丑-杨

答案 6 :(得分:4)

@Ryan Fox

事实上,如何用传统的编程语言代表i(或工程师的j)?

原生复杂数据类型远未为人所知。 Fortran在六十年代中期开始使用它,OP展示了各种其他语言,支持他们进行组织跟进。

复杂的数字可以作为库添加到其他语言中(运算符重载它们甚至看起来就像代码中的本机类型一样)。

但除非你为这个问题提供特殊情况,否则“非协议”只是表达不精确的机器算术,不是吗?就像抱怨那样

float r = 2/3;
float s = 3*r;
float t = s - 2;

以(t!= 0)结束(至少如果你使用一个足够愚蠢的编译器)......

答案 7 :(得分:3)

这是我们当前浮点计算架构的限制。浮点运算只是数字极点的近似值,如e或pi(或任何超出您的位允许的精度)。我真的很喜欢这些数字,因为他们无视分类,并且看起来比甚至素数都有更大的熵(?),这是一个规范的系列。一个比例违抗的数字表示,有时像这样简单的事情会打击一个人的心灵(我喜欢它)。

幸运的是,通过使用符号概念(类似于Lasse V. Karlsen所描述的概念),整个语言和库可专用于精确三角函数。

考虑一种库/语言,它以机器可以理解的形式描述e和pi等概念。机器是否有任何完美圆圈的概念?可能不是,但我们可以创建一个对象 - 圆圈,它满足我们赋予它的所有已知特征(恒定半径,半径与圆周的关系是2 * pi * r = C)。像pi这样的物体仅通过上述比率来描述。 r& C可以是您想要给出的任何精度描述的数字对象。 e可以定义为“因为e是唯一的实数,使得函数f(x)= ex的点x = 0处的导数值(切线的斜率)正好是{{3 }}

有趣的问题。

答案 8 :(得分:3)

数值分析告诉我们,您不能依赖大数之间微小差异的精确值。

这不仅影响这里所讨论的方程,而且可以通过求解近似的联立方程组,通过找到多项式的零,到评估log(~1)或exp(〜)来使一切变得不稳定。 0)(我甚至看到了用于评估log(x + 1)和(exp(x)-1)的特殊函数来绕过它)。

我建议你不要考虑将差异归零 - 你不能 - 而是以确保最小误差的方式进行相关计算。

对不起,自从我在大学录制这首歌以来已有43年了,即使我能记住参考文献,我也相信现在有更好的东西。我建议 this 作为起点。


如果这听起来有点光顾,我道歉。我的“数值分析101”是我的化学课程的一部分,因为当时没有多少CS。我并不真正感受到数值分析在现代CS课程中的地位/重要性。

答案 9 :(得分:3)

  

事实上,如何用传统的编程语言代表i(或工程师的j)?

在没有本机表示的语言中,通常使用OOP添加它来创建Complex类来表示ij,运算符重载以正确处理涉及其他Complex数字和/或该语言原生的其他数字原语的操作。

例如:Complex.javaC++ < complex >