浮点环境
浮点环境是与浮点异常和浮点舍入方向相关的操作的集合。
#define STDC FENV_ACCESS 实参
实参
为 ON
OFF
和 DEFAULT
其中之一。注意大写。
当 #define STDC FENV_ACCESS ON
的时候,告诉编译器,程序会访问或修改浮点环境,因此某些由编译器进行的可能修改浮点环境的优化会被禁用。
浮点异常
有以下五种浮点异常:
1. 定义域错误 FE_INVALID
当某个在数学上未定义的运算发生时,产生这个异常。比如:
0.0 / 0.0
log(-1.0)
(对非正数取对数)或sqrt(-1.0)
或pow(-1.0, 0.5)
(给负数开方)等;asin(2)
或acos(2)
(众所周知,反正弦函数和反余弦函数的定义域是 )或acosh(0.5)
(众所周知,反双曲余弦函数的定义域是 )等;fmod(2, 0.0)
(取余运算的第二个操作数为 0)等;INFINITY / INFINITY
或INFINITY * 0.0
- 任何涉及信号 NaN (Signaling NaN, sNaN) 的操作;
- 某些涉及静默 NaN (Quiet Nan, qNan) 的操作(如
NAN > 1.0
)等;
示例:
c
#include <stdio.h>
#include <fenv.h>
#include <math.h>
#pragma STDC FENV_ACCESS ON
int main() {
double result;
feclearexcept(FE_ALL_EXCEPT);
result = sqrt(-1.0);
result = 0.0 / 0.0;
result = log(-1.0);
result = asin(2);
result = pow(-1, 0.5);
result = INFINITY / INFINITY;
result = INFINITY * 0.0;
if (fetestexcept(FE_INVALID)) {
printf("FE_INVALID (Invalid operation) flag is set.\n");
} else {
printf("FE_INVALID flag is NOT set.\n");
}
printf("Result: %f\n", result);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
只保留一条对 result
的赋值操作并运行代码,如果打印出 FE_INVALID (Invalid operation) flag is set.
,则产生了 FE_INVALID
异常。
2. 向上溢出 FE_OVERFLOW
3. 向下溢出 FE_UNDERFLOW
4. 除以零 FE_DIVBYZERO
5. 精度损失 FE_INEXACT
浮点异常的相关操作
浮点舍入方向
浮点数在计算机中是用有限的位数来表示的,不能精确地表示所有实数。当一个真实的数值或计算结果落在两个可表示的浮点数之间时,就必须选择其中一个来近似它,这个过程称为舍入。
关于可表示的浮点数,参见 IEEE 754。
有以下四种浮点舍入方向: