是否可以在C++中下溢浮点添加
Is it possible to underflow a floating point addition in C++?
我正在查看英特尔处理器手册,卷 2A,第 3.266-3.268 页,它指出 FADD 操作可能会产生 #U(下溢)异常。理由是,结果将很小,无法在 DST 中正确表示。
我想知道是否可以在使用本机数据类型(浮点型、双精度型、长双精度型)的C++上加法下溢,或者数据类型的语言包装是否使加法操作在下溢方面是安全的。
如果添加彼此非常接近的正数和负数,产生非正常值,则设置下溢标志(如果未屏蔽下溢异常)。链接到英特尔文章异常和下溢。
示例代码(使用Microsoft编译器):
double a,b,c;
a = 2.2250738585072019e-308;
b = -2.2250738585072014e-308;
c = a + b; /* c is denormal */
printf("%28.16le %016llxn", a, a);
printf("%28.16le %016llxn", b, b);
printf("%28.16le %016llxn", c, c);
if ( std::fpclassify( c ) == FP_SUBNORMAL ) printf("c is DENORMAL");
要启用(取消屏蔽)下溢异常(Microsoft编译器),请执行以下操作:
short fcw; /* floating point control word - 16 bit */
/* enable underflow exception */
__asm{
fnstcw fcw
and fcw,0ffefh
fldcw fcw
}
当计算结果为非正态(次正规)数字时,会发生下溢情况。这正式称为渐进下溢(而不是产生零)。因此,通过添加几乎任何两个非正常数,只要结果也是异常数,就会发生下溢。例如:
pow(2.0, -1074.0) + pow(2.0, -1073.0)
此处的所有操作数均为双精度类型。
英特尔当然指的是逐渐下溢。但是,考虑到突然的下溢,仅使用加法和/或减法是不可能的。
相关文章:
- 自定义 std::fstream,std::filebuf 的溢出和下溢函数未为每个字符调用
- 带有剪裁下溢的夏亚减法
- 使用 size_t 初始化循环变量时的整数下溢
- 无锁队列实现中的虚假下溢C++
- 在减法期间将 C++ 转换为字节 (unit8_t) 不会像我预期的那样强制下溢;输出int16_t;为什么?
- C++长 int 溢出/下溢
- 上溢/下溢是执行时未定义的行为吗
- C++ 在将字符串提取到标量时处理溢出/下溢
- C/FORTRAN将双下溢设置为零
- basic_streambuf炒锅的功能溢出和下溢如何
- 为什么C++下溢/溢出行为被视为未定义
- C++下溢和溢出
- 渐变下溢程序的表示
- 指针下溢或溢出时会发生什么情况
- 溢流/下溢问题
- 如何在C语言中检测浮点下溢
- 如何检测双精度浮点溢出和下溢
- 未签名的下溢机制
- 编译器构造-如何在C++中发生堆栈下溢
- 将std::string转换为integer时,如何处理上溢/下溢