代码之家  ›  专栏  ›  技术社区  ›  Andre Kampling

用长双后缀L定义的浮点极限(double)

  •  6
  • Andre Kampling  · 技术社区  · 7 年前

    1. 问题:

    DBL_MAX DBL_MIN
    它们的定义见 limit.h

    #define DBL_MAX     __DBL_MAX__
    #define DBL_MIN     __DBL_MIN__
    

    __DBL_MIN__ __DBL_MAX__ 特定于编译器,可通过以下方式获得:

    $ gcc -dM -E - < /dev/null
    ...
    #define __DBL_MAX__ ((double)1.79769313486231570815e+308L)
    #define __DBL_MIN__ ((double)2.22507385850720138309e-308L)
    ...
    

    我的问题是:
    为什么这些值定义为 long double L double ?

    2.

    为什么是 __DBL_MIN_10_EXP__ 定义为 -307 -308 如上所述 DBL_最小值 宏?对于最大指数,其定义为 308 DBL_最大值

    #define __DBL_MAX_10_EXP__ 308
    #define __DBL_MIN_10_EXP__ (-307)
    

    不是问题的一部分,只是我的观察:

    DBL_最大值 DBL_最小值 和最大双倍值 DBL_最大值

    #define DBL_MAX        1.7976931348623158e+308
    #define DBL_MIN        2.2250738585072014e–308
    

    此外,Microsoft编译器设置了 长双人 a值的限制 长双人 实施

    2 回复  |  直到 7 年前
        1
  •  5
  •   Paul Floyd    7 年前

    在十进制中指定二进制浮点数有一些微妙的问题。

    为什么将这些值定义为后缀为L的长双精度,然后再转换回双精度?

    具有典型 binary64 ,最大有限值约为 1.795e+308

    179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
    

    转换为唯一值所需的位数 double 可能多达 DBL_DECIMAL_DIG (通常为17和至少10)。在任何情况下,使用指数表示法肯定是明确的,但不会过于精确。

    /*
    1 2345678901234567 */          // Sorted 
    1.79769313486231550856124...   // DBL_MAX next smallest for reference
    1.79769313486231570814527...   // Exact
    1.79769313486231570815e+308L   // gcc
    1.7976931348623158e+308        // VS (just a hair closer to exact than "next largerst")
    1.7976931348623159077293....   // DBL_MAX next largest if not limited by range
    

    细微转换差异的另一个来源,以及 这个 双重的 准确的 遵守IEEE标准。更糟糕的结果可能是 1.797...e+308 常数转换为 由于微小的转换错误,“代码到 双重的 使用双重数学 .通过转换为 long double 那些 转换误差非常小。然后转换 长双人 双重的

    简而言之,强制 L 数学确保常数不会无意中成为 无穷 .

    符合IEEE 754标准 FPU

    #define __DBL_MAX__ 1.7976931348623157e+308
    

    双重的 DBL_MAX 双重的 。这将满足许多代码的期望 双重的 长双人 但是,我没有看到任何规范要求这样做。

    定义为-307,但最小指数为-308?

    这符合 DBL_MIN_10_EXP .“…最小负整数,使10的幂在归一化浮点数范围内”非整数答案在-307和-308之间,因此范围内的最小整数为-307。

    虽然VS treats 长双人 作为一种不同的类型,其编码与 双重的 L .

        2
  •  1
  •   Paul Floyd    7 年前

    This

    指数为11位,偏移量为1023。然而,0和2047的指数是为特殊数字保留的。这意味着指数可以在2046-1023=1023到1-1023=-1022之间变化。

    因此,对于最大归一化值,我们有一个2^1023的指数。尾数的最大值略低于2(1.111等,点后52 1s,二进制),即约2*2 ^1023=约1.79e308。

    对于最小归一化值,我们有一个2^-1022的指数。最小尾数正好是1,给我们一个1*2^-10242=~ 2.22e-308的值。到目前为止很好。