代码之家  ›  专栏  ›  技术社区  ›  Tim unnamed eng

机床精度及双精度型的最大值和最小值

c c++
  •  1
  • Tim unnamed eng  · 技术社区  · 15 年前

    (1)我遇到过一些情况,epsilon被加到一个非负变量上,以保证非零值。所以我想知道为什么不添加数据类型可以表示的最小值而不是epsilon?这两个能解决的不同问题是什么?

    (2)同时我注意到双精度类型的最大值的逆大于其最小值,其最小值的逆为inf,远远大于其最大值。计算其最大值和最小值的倒数有用吗?

    (3)对于非常小的双倍型正数,要计算其倒数,当倒数开始没有意义时,它有多小?在倒数上加一个上界好吗?装订多少钱?

    谢谢和问候

    3 回复  |  直到 15 年前
        1
  •  2
  •   wich    15 年前

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

    -1^符号*有效位*2^指数

    1. 这意味着最小的数字是一个很小的值,即指数最低的小有效位。然而,舍入误差要大得多,取决于数值的大小,即具有给定指数的最小数值。epsilon是1.0和下一个可表示的较大值之间的差。这就是为什么epsilon被用在对舍入错误具有鲁棒性的代码中,如果你做得对的话,你真的应该根据你使用的数字的大小来调整epsilon。最小的可表示值通常不具有任何实际意义。

    2. 你看到了规范化和非规范化最小值之间的区别。问题是,由于有效位的使用方式,有可能使负指数大于正指数,即有效位的位模式是除最后一位(即一位)外的所有零,然后指数有效地降低了有效位中的位数。对于最大值,您不能这样做,即使您将有效位设置为所有有效位,有效指数仍将仅为给定的指数。也就是说,想想0.000001e-10和9.999999e+10之间的差别,第一个比第二个小得多。第一个实际上是1e-16,而第二个大约是1e+11。

    3. 当然,这取决于浮点数的精度。在双精度的情况下,最大值和下一个较小值之间的差异已经很大(沿着10^292的直线),因此舍入误差将非常大。如果该值太小,您只需得到inf,正如您已经看到的那样。真的,没有严格的答案,这完全取决于你需要的数字的精度。假设舍入误差约为epsilon*量级,则(1/epsilon)的倒数已经有约1.0的舍入误差如果您需要数字精确到1e-3,则即使epsilon也太大而无法除以。

    查看这些维基百科页面 IEEE754 Machine epsilon 一些背景信息。

        2
  •  4
  •   Jerry Coffin    15 年前

    ε

    epsilon是可以添加到1.0的最小值,并产生可与1.0区分的结果。正如poita_u所暗示的,这对于处理舍入误差很有用。这种情况非常简单:一个普通的浮点数的精度是固定的,不管它的大小。换言之,它总是计算相同数量的有效数字。例如,一个典型的 double 大约有15个有效数字(转换为epsilon=~1e-15)。如果您使用的是10e-200范围内的一个数字,它可以表示的最小变化将是10e-215左右。如果您使用的是10e+200范围内的一个数字,它所代表的最小变化将是1e+185左右。

    有意义地使用epsilon通常需要将其缩放到您正在使用的数字的范围,并使用该范围来定义一个您愿意接受的范围,这可能是由于舍入误差所致,因此,如果两个数字在该范围内,您假设它们可能真的相等。例如,当epsilon为1e-15时,您可能决定将彼此在1e-14范围内的数字视为相等(即在有效数字上舍入)。

    可以表示的最小数字通常会大大小于这个数字。同样的典型 双重的 ,通常在1e-308左右。这相当于epsilon 如果 您使用的是定点数字而不是浮点数字。例如,有一段时间相当多的人使用固定点绘制各种图形。一个典型的版本是16位整数,在小数点前10位,小数点后6位。这样的数字可以表示大约0到1024之间的数字,小数点后大约有两位(十进制)数字。或者,您可以将其视为有符号的,从(大约)512到+512,小数点后大约有两位数字。

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

    倒数

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

    把它看作浮点数的“标准化”形式。然而,假设你的指数是有限的,只有两位数,所以它只能从-99到+99。还假设您最多可以有15个有效数字。在这些限制内,您可以生成0.0000102E-99这样的数字。这让你可以表示一个小于1e-99的数字,以牺牲一些精度为代价——你用了有效位的5位数来表示大小,而不是15位数的精度,所以你只剩下10位真正有意义的数字。

    除了它是二进制的,而不是十进制的,ieee浮点基本上就是这样工作的。 当你接近范围的末尾时,数字的精度越来越低,直到(在范围的最末端)你只剩下一点精度。

    如果你取一个只有一位精度的数字,取其倒数,你会得到一个非常大的数字——但是由于你只从一位精度开始,结果也只能有一位精度。虽然总比没有结果好一点,但它仍然几乎毫无意义。你已经达到了位数所能表示的极限;解决这个问题的唯一方法就是使用更多的位数。

    实际上,没有任何一个点的倒数(或其他计算)“停止有意义”。一个结果有意义,另一个没有意义,这并不是一条硬线,而是一个斜率,其中一个结果可能有15位数的精度,另一个10位数,第三个只有1位数。“有意义”与否主要是你如何解释这个结果。为了得到有意义的结果,你需要知道你最终结果中有多少数字是真正有意义的。

        3
  •  1
  •   Peter Alexander    15 年前
    1. 添加epsilons是为了测试两个应该相等的值之间的相等性,但不是因为舍入错误。虽然你可以用最小的正值来表示epsilon,但它不是最优的,因为它太小了。浮点运算引起的舍入误差几乎总是超过最小值,因此需要较大的epsilon。多大取决于你想要的准确度。

    2. 我不明白这个问题。回报对什么有用吗?我想不出他们为什么有用。

    3. 一般来说,用很小的值来划分是个坏主意,因为这样会导致很大的舍入误差。我不知道你加上界是什么意思。只要尽可能避免被小值分割。