Floating point IEEE-754浮点精度:允许多少误差?

Floating point IEEE-754浮点精度:允许多少误差?,floating-point,glibc,floating-accuracy,ieee-754,double-precision,Floating Point,Glibc,Floating Accuracy,Ieee 754,Double Precision,我正在将sqrt函数(用于64位双精度)从移植到目前使用的模型检查器工具()。 作为我工作的一部分,我读了很多关于ieee-754标准的书,但我认为我不理解基本操作(包括sqrt)的精度保证 在测试fdlibm的sqrt端口时,我使用64位双精度上的sqrt进行了以下计算: sqrt(19770615168252036055552166161671250056589765715897211390271504986574945891719703353874178236614173837459642

我正在将
sqrt
函数(用于64位双精度)从移植到目前使用的模型检查器工具()。
作为我工作的一部分,我读了很多关于ieee-754标准的书,但我认为我不理解基本操作(包括sqrt)的精度保证

在测试fdlibm的sqrt端口时,我使用64位双精度上的sqrt进行了以下计算:

sqrt(1977061516825203605555216616167125005658976571589721139027150498657494589171970335387417823661417383745964289845929120708819092392090053015474001800648403714048.0) = 44464159913633855548904943164666890000299422761159637702558734139742800916250624.0
(这个案例打破了我测试中关于精度的一个简单post条件;我不再确定这个post条件是否适用于IEEE-754)

为了进行比较,几个多精度工具计算如下:

sqrt(1977061516825203605555216616167125005658976571589721139027150498657494589171970335387417823661417383745964289845929120708819092392090053015474001800648403714048.0) =44464159913633852501611468455197640079591886932526256694498106717014555047373210.truncated
你可以看到,左边的第17个数字是不同的,这意味着一个错误,如:

3047293474709469249920707535828633381008060627422728245868877413.0
问题1:允许出现这么大的错误吗?

标准规定,每个基本运算(+、-、*、/、sqrt)应在0.5 ulp以内,这意味着它应等于数学上精确的结果,四舍五入到最接近的fp表示(wiki表示,一些库仅保证1 ulp,但目前这并不重要)

问题2:这是否意味着每个基本操作都应该有一个错误<2.220446e-16,带有64位双精度(机器ε)?

我确实用x86-32 linux系统(glibc/eglibc)计算了同样的结果,得到了与fdlibm相同的结果,这让我想到:

  • 答:我做错了什么(但如何:
    printf
    会成为候选人,但我不知道这是否是原因)
  • 错误/精度在这些库中很常见

在二进制中,任意精度答案的前58位是1011111111111111111110101010101111111111111111111011010001

双精度值的53位有效位为

10111111111111111101010101011111111111111111111110111


这意味着双精度值被正确舍入到53个有效位,并且在1/2 ULP范围内。(错误“大”只是因为数字本身大)

IEEE-754标准要求所谓的“基本运算”(包括加法、乘法、除法和平方根)正确舍入。这意味着有一个唯一的允许答案,它是与所谓的“无限精确”运算结果最接近的可表示的浮点数

在双精度中,数字的精度为53位二进制数字,因此正确答案是精确答案,四舍五入为53位有效数字。正如里克·里根(Rick Regan)在回答中所说,这正是你得到的结果

你的问题的答案是:

问题1:允许出现这么大的错误吗?

是的,但将这一错误称为“巨大”是相当误导的。事实上,没有可以返回的具有较小错误的双精度值

问题2:这是否意味着每个基本操作都应该有一个错误<2.220446e-16,带有64位双精度(机器ε)?

否。这意味着每个基本操作都应根据当前舍入模式舍入到(唯一)最接近的可表示浮点数。这与相对误差以机器ε为界的说法并不完全相同

问题3:您使用x86硬件和gcc+libc获得了什么结果?


与您的回答相同,因为
sqrt
在任何合理的平台上都是正确的四舍五入。

一个好的经验法则是,64位双精度中大约有15-16位十进制数字的精度,因此第17位的错误是自然的结果。@sascha关于问题二:相对错误,即,(正确-近似)/正确,应该在这个范围内。例如,相对误差为6.8533701764037842e-17。