机器精度和双精度型的最大值和最小值

时间:2010-02-02 16:57:32

标签: c++ c

(1)我遇到过几种情况,其中将epsilon添加到非负变量以保证非零值。所以我想知道为什么不添加数据类型可以代表epsilon的最小值?这两者可以解决的不同之处是什么?

(2)我还注意到双精度类型的最大值的倒数大于其最小值,并且其最小值的倒数是inf,大于其最大值。计算其最大值和最小值的倒数是否有用?

(3)对于一个非常小的正数双重类型,计算它的倒数,当它的倒数开始没有意义时它有多小?在倒数上设置上限是否更好?绑定多少钱?

谢谢和问候

3 个答案:

答案 0 :(得分:4)

的Epsilon

Epsilon是可以添加到1.0的最小值,并产生与1.0无法区分的结果。正如Poita_暗示的那样,这对于处理舍入错误很有用。情况非常简单:正常的浮点数具有固定的精度,无论数字的大小如何。换句话说,它总是计算相同数量的有效数字。例如,double的典型实现将具有大约15位有效数字(转换为Epsilon = ~1e-15)。如果您使用的是10e-200范围内的数字,它可以代表的最小变化大约为10e-215。如果您使用的是10e + 200范围内的数字,它可以代表的最小变化大约是1e + 185。

有意义地使用Epsilon通常需要将其缩放到您正在使用的数字范围内,并使用它来定义您愿意接受的范围,因为可能是由于舍入错误,所以如果两个数字属于该范围内范围,你认为他们可能真的是平等的。例如,对于1e-15的Epsilon,您可能决定将相互之间的1e-14之间的数字视为相等(即,对于舍入而丢失了有效数字)。

可以表示的最小数字通常会小得多。使用相同的典型double,它通常约为1e-308。这相当于Epsilon 如果你使用的是固定点数而不是浮点数。例如,曾经有不少人使用定点来表示各种图形。典型版本是一个16位的整数,分为小数点前10位和小数点后6位。这样的数字可以表示从大约0到1024的数字,小数点后面有大约两个(十进制)数字。或者,您可以将其视为已签名,从(大致)-512到+512运行,再次在小数点后大约两位数。

在这种情况下,缩放因子是固定的,因此两个数字之间可以表示的最小差异也是固定的 - 即1024和下一个较大数字之间的差异与0和0​​之间的差异完全相同下一个更大的数字。

倒数

我不确定你为什么要关心计算极大或极小数字的倒数。 IEEE浮点使用非正规数,这意味着接近范围限制的数字会丢失精度。基本上,数字分为指数和有效数。指数包含数字的大小,有效数字包含有效数字。每个都用指定的位数表示。在通常的情况下,数字是标准化的,这意味着它们与我们在学校学到的科学记法模糊地相似。在科学记数法中,你总是调整有效数和指数,所以在小数点之前恰好有一个位置,所以(例如)140变为1.4e2,20030变为2.003e4,依此类推。

将此视为浮点数的“规范化”形式。但是,假设您限制了一个具有2位数的指数,因此它只能从-99到+99运行。同时假设您最多可以有15位有效数字。在这些限制范围内,您可以生成0.00001002e-99之类的数字。这允许你代表一个小于1e-99的数字,代价是失去一些精度 - 而不是15位数的精度,你使用了有效数字的5位来表示幅度,所以你只剩下10位数这真的很重要。

除了它是二进制而不是十进制之外,IEEE浮点工作方式大致如此。 当你接近范围的末尾时,数字的精度越来越低,直到(在范围的最后)你只剩下一位精度。

如果你取这个只有一位精度的数字,并取其倒数得到一个非常大的数字 - 但由于你只是从一位精度开始,结果只能有一点精度。虽然比没有结果略好,但它仍然非常接近无意义。你已经达到了比特数可以代表的极限;关于解决问题的唯一方法是使用更多位。

互惠(或其他计算)“停止有意义”的任何一点都没有。在一个结果有意义的情况下,这并不是一个强硬路线,而另一个结果则不然。相反,它是一个斜率,其中一个结果可能有15位数的精度,另外10个和三个只有1.什么“有意义”或不是主要是你如何解释这个结果。要获得有意义的结果,您需要了解最终结果中有多少位数才有意义。

答案 1 :(得分:2)

您需要了解CPU中如何表示浮点数。在数据类型中,为符号保留1位,即它是正数还是负数(是的,你可以在浮点数中有正负0),然后为有效数字保留一些位(或者尾数,)这些是浮点数中的有效数字,最后为指数保留了多个位。现在浮点数的值是:

-1 ^ sign *有效数字* 2 ^指数

  1. 这意味着最小的数字是一个非常小的值,即具有最低指数的小有效数。然而,舍入误差要大得多,并且取决于数字的大小,即具有给定指数的最小数字。 epsilon是1.0和下一个可表示的较大值之间的差值。这就是为什么epsilon用于强大的舍入错误的代码,实际上你应该使用你使用的数字的大小来扩展epsilon,如果你正确的话。最小的可表示值通常没有任何重要用途。

  2. 您正在看到规范化和非规范化最小值之间的差异。问题在于,由于使用有效数字的方式,有可能产生一个比正数更大的负指数,比如有效数字的位模式除了最后一位(即1)之外都是零,那么指数是有效的降低有效数字中的位数。最大限度的是你无法做到这一点,即使你将有效数字设置为全部,有效指数仍然只是给定的指数。即想想0.000001e-10和9.999999e + 10之间的差异,第一个比第二个大得多。第一个实际上是1e-16,而第二个是大约1e +11。

  3. 当然,这取决于浮点数的精度。在双精度的情况下,最大值和下一个较小值之间的差异已经很大(沿着10 ^ 292行),因此您的舍入误差将非常大。如果值太小,你只需要改变inf,就像你已经看到的那样。真的,没有严格的答案,这完全取决于你需要的数字的精确度。假设舍入误差大约为epsilon *幅度,则(1 / epsilon)的倒数已经具有大约1.0的舍入误差,如果你需要数字精确到1e-3那么甚至epsilon将太大而不能除以。 / p>

  4. 有关背景信息,请参阅IEEE754Machine epsilon上的这些维基百科页面。

答案 2 :(得分:1)

  1. 添加Epsilons以测试两个应该相等的值之间的相等性,但不是因为舍入错误。虽然你可以使用epsilon的最小正值,但它不是最佳的,因为它太小了。由浮点运算引起的舍入误差几乎总是超过该最小值,因此需要更大的epsilon。多大程度取决于您所需的准确度。

  2. 我不明白这个问题。倒数对于什么有用吗?我想不出它们有用的原因。

  3. 通常,除以非常小的值是一个坏主意,因为它会导致非常大的舍入误差。我不确定你的意思是添加上限。尽量避免在可能的情况下除以小值。