表示实数而不会丢失精度


10

当前浮点(ANSI C浮点数,双精度)允许表示实数的近似值
有没有办法表示实数而没有错误
这是我的一个主意,绝非完美。

例如,1/3是0.33333333 ...(以10为底)或o.01010101 ...(以2为底),也是0.1(以3为底)
是实现这个“结构”的好主意:

base, mantissa, exponent

所以1/3可能是3 ^ -1

{[11] = base 3, [1.0] mantissa, [-1] exponent}

还有其他想法吗?


12
这样您将只能表示有理数。
Andrej Bauer 2014年

您如何建议对这种表示形式的数字进行算术运算?使用对数更改底数?这将是很多比IEEE浮点运算更加昂贵。
David Zhang

好吧,我不知道。我不是工程师:)显然,我无法在硬件中实现它。可以在C中完成缓慢,效率低下的实现。这只是一个实验
2014年

Answers:


20

这完全取决于您要做什么。

例如,您所显示的是表示有理数的一种好方法。但是它仍然不能完美地表示eπË

事实上,许多语言,比如Haskell和方案已经内置了对有理数的支持,将它们存储在形式,其中ab是整数。一个b一个b

这些未得到广泛使用的主要原因是性能。浮点数有点不精确,但是它们的操作是在硬件中实现的。您提出的系统可以提高精度,但是需要执行几个步骤,而不是可以在硬件中执行的单个操作。

众所周知,某些实数是不可计算的,例如停止数。与不同,没有算法枚举其数字,只要等待足够长的时间,我们就可以计算第n个数字。πñ

如果您想要非理性或超验数字的真实精度,则可能需要使用某种类型的符号代数系统,然后以符号形式获得最终答案,您可以近似于任意数量的数字。但是,由于上面概述的不确定性问题,此方法必然受到限制。对于近似积分或无穷级数之类的问题,它仍然很有用。


我可以再问一个问题吗?如果您是80年代的英特尔工程师,您将如何“设计”您的实数格式?
骚扰2014年

3
我不是非常有资格回答这个问题,因为我不是工程师,而是理论研究人员。我认为IEEE浮点和双重标准以及现在的四倍没有什么错。我认为并没有很多应用程序需要更高精度的算法,而那些应用程序可以使用软件支持的版本。
jmite 2014年

对于精确的实数运算,符号代数不是正确的形式主义。您需要一个允许任意大尾数的表示形式。
Andrej Bauer

8
@AndrejBauer:如果想要精确表示√,那么任意大的尾数将无法保存您2
user2357112支持Monica 2014年

@jmite你太谦虚了:)
欣喜

22

如果每个数字都具有有限的表示形式,则无法无误地表示所有实数。有无数个实数,但只有无数个1和0的有限字符串可用来表示它们。


可以将要求从代表每个实数限制为仅限制那些实数,这可能是图灵机的输出。那只能是可数的实数,但仍会覆盖您要代表的每个数字。但我认为您无法使用此类数字进行有效的计算。
kasperd 2014年

3
@kasperd它们被称为可计算的实数。不幸的是,像平等之类的东西不能在可计算的实数上计算。
David Richerby 2014年

确实非常清楚,在这样的数字上计算相等性等于解决停顿问题。给定一个TM可以定义一个实数,该实数以许多小数开头,这些小数从零开始,恰好等于TM的运行时间,然后是一个。将该数字与零进行比较等效于解决原始TM的暂停问题。
kasperd 2014年

这个答案是错误的。艾伦·图灵(Alan Turing)在他的第一本关于机器的论文(发明图灵机器的论文)中谈到了将实数表示为无限的数据字符串。这导致了所谓的“ II型图灵机”的想法,并且基于该想法的实数计算理论非常成功。它也在实践中实现,请参阅我的答案。
Andrej Bauer 2014年

1
也许从技术上讲确实如此,但它遗漏了要点,那就是存在实数的完全合理的无限表示。这并不奇怪:TCP / IP连接,Skype呼叫或摄像机的视频馈送都是(可能)无限数量的数据的示例。他们可以提供多少信息没有先验限制。在有限的时间内可以从中获取多少信息只有一个限制。
Andrej Bauer 2014年

7

你的想法行不通,因为一些在基地代表与尾数和指数Ë是有理数b - Ë,因此你的工作表现恰恰有理数而不是其他。你不能代表bmebme例如 22

可计算数学的整个分支涉及精确的实数运算。已经提出了许多表示确实数的数据结构:数字流,仿射收缩流,有理柯西序列,二进位有理柯西序列,Dedekind割,缩水间隔序列等。存在基于精确实数的实现这些想法,例如:

在这些iRRAM中,最成熟,最有效的。马歇尔在一个实验性项目中,而第三个是学生项目,也是最容易访问的项目。它有一个很好的介绍,解释了有关实数计算的问题,我强烈建议您看一下。

我说一句话。有人会反对一个无限的对象不能用计算机来表示。从某种意义上说是正确的,但从另一个意义上讲则不是。我们永远都表示整个实数,我们只需要有限的逼近在计算的每个阶段。因此,我们只需要一个可以代表任何给定精度的实数的表示。当然,一旦我们用完了计算机内存,我们就会用完计算机内存-但这是计算机的限制,而不是表示本身。这种情况与编程中的许多其他情况没有什么不同。例如,人们在Python中使用整数,即使它们不能超过可用内存的大小,他们也会认为它们是“任意大”的。有时,无穷大是非常大的有限数的有用近似。

此外,我经常听到有人声称计算机只能处理可计算的实数。这错过了两个要点。首先,计算机可以访问来自外部世界的数据,因此我们还必须做出(不可验证的)假设,即外部世界也是可计算的。其次,我们需要区分计算机可以计算的实物和计算机可以代表的实物。例如,如果我们选择数字流作为实数的表示,则完全有可能表示一个不可计算的实数:如果有人将其提供给我们,我们将知道如何表示它。但是,如果我们选择将实数表示为计算数字的源代码片段,那么显然我们无法表示不可计算的实数。

无论如何,最好通过进一步阅读来解决该主题。


+1,但我反对您不能按照问题的要求,通过有限近似表示无限字符串而又不损失精度。当然,您可以根据需要获得尽可能多的精度-通过有理数近似即可-但这并不是问题所要解决的。可以说,这是问题的问题,而不是答案的问题。
David Richerby 2014年

2
关键是我们不是用有限的字符串表示。我们用无限字符串表示,但在计算的每个阶段,我们只需要无限字符串的有限部分即可。或者换一种说法:由于数据结构保存了全部信息,因此不会损失精度,但是当然您不能一次访问或处理所有信息:数据结构可为您提供所需的精度。瓶颈不在数据结构方面,而是在希望从中获取信息的“消费者”方面。
Andrej Bauer 2014年

@AndrejBauer但是,在某些情况下,您必须立即访问或处理所有信息,例如,这是符号计算的功能,方法是捕获数量的“本质”或性质,而不是像其他任何数字流一样。如果您告诉符号计算包验证,它将立即输出true。如果使用您似乎描述的方法,则取2的平方根的前k个数字,对于任何k,您将得出22=2k2 k因为您的结果将(对于任何有限k)等于1.99 ...,这是错误的答案。计算是有限的。222k1.99...
托马斯

2
@Thomas:符号计算不代表实数,但通常代表实数的某些子字段,通常是由基本函数和多项式的根生成的子字段。这些子字段不完整(在柯西序列的限制范围内关闭),也不能计算完整(在柯西序列的可计算范围内关闭)。除非您可以表示所有(可计算的)实数,否则表示不是实数的表示:符号计算无法满足此条件。
安德烈·鲍尔

1
这些关于可数性的评论是无关紧要的,因为可计算的实数不是可计算的可数。
安德烈·鲍尔

7

有许多有效的有理数实施,但是连续分数是提出了很多次,甚至可以很好地处理一些非理性的实现。

引用达伦·科林斯的续篇

定理5-1。-当且仅当实数是有理数时,实数的连续分数表达式是有限的。

来自Mathworld的报价-定期续小数

...连续分数是周期的,前提是它是二次多项式的根。

即,所有根都可以表示为周期性连续分数。

π还有一个精确的连续分数,这使我感到惊讶,直到@AndrejBauer指出实际上并非如此。


您的最后一句话令人误解。没有有限的(或周期性的)连续分数。π的连续分数是无限且非周期性的。ππ
DW

J. Vuillemin不久前提出实数的连续分数表示作为精确实数运算的一种实现。事实证明,由于数字很快就会变得相当大,而且很难缩减规模,因此效率并不高。
Andrej Bauer

连续分数甚至在表示有理数方面也存在一些计算问题-尽管可以使用字典顺序的变体比较它们,并且操作单个连续分数很容易,但是CF的(二进制)加法和乘法都是相当复杂的操作实行。
Steven Stadnicki 2014年

5

注释中有许多“完全真实”的建议(例如,连续分数,线性分数变换等)。典型的陷阱是,尽管您可以计算公式的答案,但是等式通常是不确定的。

但是,如果您只对代数数感兴趣,那么您很幸运:实数封闭域的理论是完整的,o极小且可确定的。Tarski在1948年证明了这一点。

但是有一个陷阱。您不想使用Tarski的算法,因为它属于复杂性类NONELEMENTARY,这与不切实际的算法所能解决的一样不切实际。最近有更多方法可以将复杂度降低到DEXP,这是我们目前所知的最好方法。

请注意,此问题是NP难题,因为它包含SAT。但是,尚不知道(或认为是)NP。

编辑我将尝试进一步解释这一点。

理解所有这些的框架是一个决策问题,称为可满足性模理论,简称SMT。基本上,我们想为基于经典逻辑的理论求解SAT。

因此,我们从一阶经典逻辑与相等性测试开始。我们要包括哪些功能符号以及它们的公理决定了该理论是否可判定。

SMT框架中表达了许多有趣的理论。例如,存在用于帮助证明程序正确的数据结构理论(例如列表,二叉树等)以及欧几里得几何学。但出于我们的目的,我们正在研究不同种类的数论。

Presburger算术是自然数加法理论。这个理论是可以决定的。

Peano算术是具有加法和乘法的自然数论。正如哥德尔(Gödel)著名地证明的那样,这一理论是不可判定的。

Tarski算术是所有字段操作(加,减,乘和除)的实数理论。有趣的是,这种理论是可以决定的。当时,这是非常违反直觉的结果。您可能会认为,由于它是自然数的“超集”,因此“难”,但事实并非如此。例如,将有理数上的线性规划与整数上的线性规划进行比较。

满足感似乎并不是您所需要的,但事实就是如此。例如,如果要测试2的正平方根是否等于3的实立方根,则可以将其表示为可满足性问题:

XX>0X2-2=0X3-3=0

ËX

{Xπ|X=0}

ËXË一世X


阿尔弗雷德·塔斯基(Alfred Tarski,1948年),《基本代数和几何的一种判定方法》


2

通过将它们视为多项式的根,可以精确地表示非常大的一类数字,即代数

πË


ËË一世Xcos{X[R|X=0}

@Pseudonym这看起来真的很有趣,但是我认为我没有数学背景可以正确理解它……“足够接近整数”是什么意思?
更多斧头

我将修改我的答案以进行解释。
别名2014年

1

π2


这个答案是错误的。精确实数运算的整个区域说明了如何用计算机表示实数。实数必须由有限字符串表示的假设是错误的。我们还可以使用无限字符串。艾伦·图灵(Alan Turing)已经在他的第一篇论文中写了这一点,他在那篇论文中发明了图灵机!
Andrej Bauer 2014年

您能否链接到有关如何在实际计算机中存储和处理无限字符串的论文,因为那将是对所提问题的解答。同样不是他的第一篇论文,第一篇出版物是1936年,
那篇

没错,这是1937年的论文。若要查看如何操作无限字符串,例如,可以查看TCP / IP协议。我从来没有说过,整个真实必须存储在计算机中。
Andrej Bauer 2014年

-1

您不能代表计算机中的所有实数,但是可以代表许多。您可以使用分数表示比浮点​​数更多的数字。您还可以做一些更复杂的事情,例如将数字表示为多项式的根,并且近似值在牛顿法下将收敛到数字。


这又是一个愚昧无知的错误答案。精确实数运算的整个领域研究如何通过合适的数据结构表示所有实数。
Andrej Bauer 2014年

@AndrejBauer因此,您建议存在一个可以表示任何实数的数据结构?任何此类数据结构都必须使用不可计数的无限数量的位来表示任何数字。
爱丽丝·赖尔

1
首先,数量可观的位就足够了,而且由于您一次也不需要所有位,也无法一次处理所有位,因此它们既可以存储在时间上,也可以存储在空间中。
Andrej Bauer 2014年

@AndrejBauer这个答案是正确的,尽管您的信息少了很多,但您说的还是同一个。您不能代表计算机中的所有实数。您可以代表任何实数,但不能一次全部代表。如果有的话,我会质疑您可以代表“许多”,因为您只能在任何给定的计算机中代表有限的很多,而在抽象计算机中(与数学计算模型等效),在数学意义上几乎没有代表(图灵机器等效)。
吉尔(Gilles)'所以

-1

通过将输入存储为一串操作,就可以精确地表示可表示输入的任何数字,例如,您存储1/31 divided by 3,通过处理操作的取消,可以简化下一个操作以给出确切的答案(1/3) * 3。这也可以处理已知的非理性情况,例如π将其保留在计算中。

但是,每个数字都需要增加存储量,并且-假设您的简化器并不完美-可能需要为不断增加的数值而不断增加的存储量。


5+26-2=3
本·米尔伍德

确实。实际上,完全成功地自动化可能实际上是不可能的。但是,即使您没有使用最简单的表示形式,结果也将保持精确。
杰克·艾德利
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.