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

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

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

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

感谢致敬

您需要了解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 *幅度,如果你需要精确到1e-3的数字,则(1 / epsilon)的倒数已经具有大约1.0的舍入误差,那么即使epsilon太大而不能除以。

有关背景信息,请参阅IEEE754和Machine 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和下一个较大数字之间的差异完全相同。

倒数

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

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

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

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

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

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

  2. 我不明白这个问题。 倒数对于什么有用吗? 我想不出他们为什么会有用的任何理由。

  3. 一般来说,除以非常小的值是一个坏主意,因为它会导致非常大的舍入误差。 我不确定添加上限是什么意思。 尽量避免用小值除以。