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

Math 稍微转向浮点(im)精度,第1部分,math,language-agnostic,floating-point,Math,Language Agnostic,Floating Point,大多数数学家都同意: eπi+1=0 然而,大多数浮点实现都不同意。我们能怎样解决这场争端 我很想了解不同的语言和实现,以及使结果尽可能接近于零的各种方法。要有创意 下面是我尝试过的实现和语言的简短列表。它按接近零的程度排序: 方案:(+1(使极轴1(atan 0-1)) ⇒ 0.0+1.2246063538223773e-16i(Chez方案,麻省理工学院方案) ⇒ 0.0+1.22460635382238e-16i(Guile) ⇒ 0.0+1.22464679914735e-16i(带

大多数数学家都同意:

eπi+1=0

然而,大多数浮点实现都不同意。我们能怎样解决这场争端


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

下面是我尝试过的实现和语言的简短列表。它按接近零的程度排序:

  • 方案:
    (+1(使极轴1(atan 0-1))
    • ⇒ <代码>0.0+1.2246063538223773e-16i(Chez方案,麻省理工学院方案)
    • ⇒ <代码>0.0+1.22460635382238e-16i(Guile)
    • ⇒ <代码>0.0+1.22464679914735e-16i(带编号的鸡肉鸡蛋)
    • ⇒ <代码>0.0+1.2246467991473532e-16i(MzScheme、SISC、Gauche、Gambit)
    • ⇒ <代码>0.0+1.2246467991473533e-16i(SCM)
  • 通用Lisp:
    (1+(exp(复数0 pi))
    • ⇒ <代码>#C(0.0L0-5.0165576136843360246L-20)(CLISP)
    • ⇒ <代码>#C(0.0d0 1.2246063538223773d-16)(CMUCL)
    • ⇒ <代码>#C(0.0d0 1.2246467991473532d-16)(SBCL)
  • Perl:
    使用Math::Complex;数学:复杂->emake(1,pi)+1
    • ⇒ <代码>1.22464679914735e-16i
  • Python:
    来自cmath import exp,pi;exp(复数(0,pi))+1
    • ⇒ <代码>1.2246467991473532e-16j(CPython)
  • Ruby:
    要求“复杂”;复数::极坐标(1,数学::π)+1
    • ⇒ <代码>复合体(0.0,1.22464679914735e-16)(MRI)
    • ⇒ <代码>复合体(0.0,1.2246467991473532e-16)(JRuby)
  • R:
    complex(参数=pi)+1
    • ⇒ <代码>0+1.224606353822377e-16i

    • 有可能解决这一争端吗

      我的第一个想法是寻找一种象征性的语言,比如。我不认为这算是浮点数

      事实上,在传统编程语言中,如何表示i(或工程师的j)


      也许更好的例子是sin(π)=0?(还是我又错过了重点?

      我同意Ryan的观点,你需要换一个数字表示系统。这个解决方案超出了浮点数学的范畴,因为需要将pi表示为一个无限长的十进制数,所以任何有限精度的方案都是行不通的(至少在不使用某种模糊因子来弥补丢失的精度的情况下是行不通的)。

      @Ryan Fox事实上,如何表示i(或工程师的j)在传统的编程语言中

      本机复杂数据类型远非未知。Fortran在60年代中期就拥有了它,OP展示了在历史后续中支持它的各种其他语言

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

      但是除非你为这个问题提供一个特例,“不一致”只是一个不精确的机器算法的表达,不是吗?这就像是在抱怨

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

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

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

      如果需要更好的精度,则需要使用不同的数字表示。就像你对不适合整数或长整数的数字进行整数运算一样。有些语言有内置的库(我知道java有BigInteger和BigDecimal),但是您必须显式地使用这些库,而不是本机类型,并且性能会(有时明显)比使用float更差

      事实上,在传统编程语言中,如何表示i(或工程师的j)

      在没有本机表示的语言中,通常使用OOP创建一个
      Complex
      类来表示
      i
      j
      ,并使用运算符重载来正确处理涉及其他
      复杂
      数字和/或该语言本机的其他数字原语的操作


      例:,

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


      π是一个无穷大的数字系列,除了符号表示外,没有人能用其他任何东西来表示,而e^X是相同的,因此达到100%精度的唯一方法就是符号化。

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

      这不仅会影响这里讨论的方程,而且会给一切带来不稳定性,从求解一组近似奇异的联立方程,到找到多项式的零点,再到计算log(~1)或exp(~0)(我甚至看到了计算log(x+1)和(exp(x)-1)的特殊函数来解决这个问题)

      我鼓励你们不要考虑将差值归零——你们不能——而是以确保误差最小的方式进行相关计算

      我很抱歉,我在大学里已经有43年没有听到这个消息了,即使我能记得那些推荐信,我相信现在有更好的消息。我建议将作为起点


      如果这听起来有点傲慢,我道歉。我的“数值分析101”是我化学课程的一部分,因为那时没有多少CS。我对数值分析在现代计算机科学课程中的地位/重要性没有什么感觉

      这是一个限制