c++14 - DBL_Max 和 DBL_Min 是否会出现舍入错误?
c++14 - Are DBL_Max and DBL_Min subject to round off errors?
浮点值可能存在舍入误差。例如,
double x = 1.0;
// x might be something like 1.00000000000000001
像 DBL_Max 和 DBL_Min 这样的常量是否总是保证具有它们预期具有的相同值(对于它们正在使用的任何系统)?它们是否可能受到舍入误差的影响?例如,在下面的代码中:
double x = DBL_Max;
assert (x == DBL_Max); // is this assertion guaranteed to always be true?
C 和 C++ 标准对此没有明确规定。 C 标准允许在从源代码中的浮点常量(文字)转换为内部格式(如 C 2011 [N1570] 6.4.4.2 5 中)的过程中出现错误,并且对于 DBL_MAX
的常量表达式没有明确禁止这种情况DBL_MIN
扩展为。但是,任何理智的 C 或 C++ 实现都不会有 DBL_MAX
或 DBL_MIN
.
的不准确值
C++ 标准似乎确实表示,如果浮点文字可表示,则它们必须产生准确的值。 (C++ 2017 [draft n4659] 5.13.4 1 和 2010 版本中的类似文本:“如果缩放值在其类型的可表示值范围内,则结果是可表示的缩放值,否则更大或更小的可表示最接近缩放值的值,以实现定义的方式选择。”)但是,DBL_MAX
和 DBL_MIN
被指定为常量表达式,而不是文字。我没有在 C++ 标准的规范部分找到关于浮点表达式准确性的声明,但 5.19 4 中的注释说:“虽然在某些情况下,常量表达式必须在程序翻译期间求值,但其他人可能在程序翻译期间求值程序执行。由于本国际标准对浮点运算的准确性没有施加任何限制,因此未指定在翻译过程中对浮点表达式的求值是否产生与对相同表达式(或对相同值的相同操作)的求值相同的结果) 在程序执行期间。”
因此,从技术上讲,标准不要求 x == DBL_MAX
在 double x = DBL_MAX;
之后为真,但在实践中,它应该始终为真。
如上所述,在 C++ 中,double x = 1.0;
中的 1.0
必须准确翻译,因此 x
将被初始化为没有舍入误差的 1。 C 标准没有指定这一点,但是任何理智的 C 实现都不会在 double x = 1.0;
中出现舍入错误。舍入误差是由计算中的困难或不可能引起的,而不是来自随机的人工制品。
浮点值可能存在舍入误差。例如,
double x = 1.0;
// x might be something like 1.00000000000000001
像 DBL_Max 和 DBL_Min 这样的常量是否总是保证具有它们预期具有的相同值(对于它们正在使用的任何系统)?它们是否可能受到舍入误差的影响?例如,在下面的代码中:
double x = DBL_Max;
assert (x == DBL_Max); // is this assertion guaranteed to always be true?
C 和 C++ 标准对此没有明确规定。 C 标准允许在从源代码中的浮点常量(文字)转换为内部格式(如 C 2011 [N1570] 6.4.4.2 5 中)的过程中出现错误,并且对于 DBL_MAX
的常量表达式没有明确禁止这种情况DBL_MIN
扩展为。但是,任何理智的 C 或 C++ 实现都不会有 DBL_MAX
或 DBL_MIN
.
C++ 标准似乎确实表示,如果浮点文字可表示,则它们必须产生准确的值。 (C++ 2017 [draft n4659] 5.13.4 1 和 2010 版本中的类似文本:“如果缩放值在其类型的可表示值范围内,则结果是可表示的缩放值,否则更大或更小的可表示最接近缩放值的值,以实现定义的方式选择。”)但是,DBL_MAX
和 DBL_MIN
被指定为常量表达式,而不是文字。我没有在 C++ 标准的规范部分找到关于浮点表达式准确性的声明,但 5.19 4 中的注释说:“虽然在某些情况下,常量表达式必须在程序翻译期间求值,但其他人可能在程序翻译期间求值程序执行。由于本国际标准对浮点运算的准确性没有施加任何限制,因此未指定在翻译过程中对浮点表达式的求值是否产生与对相同表达式(或对相同值的相同操作)的求值相同的结果) 在程序执行期间。”
因此,从技术上讲,标准不要求 x == DBL_MAX
在 double x = DBL_MAX;
之后为真,但在实践中,它应该始终为真。
如上所述,在 C++ 中,double x = 1.0;
中的 1.0
必须准确翻译,因此 x
将被初始化为没有舍入误差的 1。 C 标准没有指定这一点,但是任何理智的 C 实现都不会在 double x = 1.0;
中出现舍入错误。舍入误差是由计算中的困难或不可能引起的,而不是来自随机的人工制品。