Tim*_*Tim 5 c floating-point computer-science loops sigfpe
目前我正在学习浮点异常。我正在写一个带有函数的循环。在该函数中,计算出的值等于0.5。随着循环的进行,输入值除以10。
循环:
for(i = 0; i < e; i++)
{
xf /= 10.0; // force increasingly smaller values for x
float_testk (xf, i);
}
Run Code Online (Sandbox Code Playgroud)
功能:
void float_testk(float x, int i)
{
float result;
feclearexcept(FE_ALL_EXCEPT); // clear all pending exceptions
result = (1 - cosf(x)) / (x * x);
if(fetestexcept(FE_UNDERFLOW) != 0)
fprintf(stderr,"Underflow occurred in double_testk!\n");
if(fetestexcept(FE_OVERFLOW) != 0)
fprintf(stderr,"Overflow occurred in double_testk!\n");
if(fetestexcept(FE_INVALID) != 0)
fprintf(stderr,"Invalid exception occurred in double_testk!\n");
printf("Iteration %3d, float result for x=%.8f : %f\n",i,x,result);
}
Run Code Online (Sandbox Code Playgroud)
前几次迭代输出是左右0.5,后来它变成了0CC。过了一会儿,这是程序的输出:
for(i = 0; i < e; i++)
{
xf /= 10.0; // force increasingly smaller values for x
float_testk (xf, i);
}
Run Code Online (Sandbox Code Playgroud)
我想知道从下溢到NaN. 因为下溢意味着数字太小,无法存储在内存中。
但是如果数量已经太少了,那么目标是NaN什么?
因为下溢意味着数字太小,无法存储在内存中。
不完全的; 在浮点中,下溢意味着结果低于可以全精度表示数字的范围。结果可能仍然相当准确。
只要x至少为 2 ?75,就会x * x产生非零结果。这可能是在浮点域,其中精度下降的部分低于正常,但实数结果x•x足够大到轮2 ?149或更高。然后,对于这些小x,(1 - cosf(x)) / (x * x)计算为零除以非零值,因此结果为零。
当x小于2 ?75,然后x * x产生零,因为实数结果x•x是如此之小,在浮点运算,它被四舍五入为零。然后(1 - cosf(x)) / (x * x)计算为零除以零,因此结果是 NaN。这就是您的迭代 22 中发生的情况。
(2 ?149是 IEEE-754 binary32 中可表示的最小正值,您的 C 实现可能将其用于float。在 2 ?150和 2 ?150之间的实数结果将向上舍入为 2 ?149。较低的结果将向下舍入为 0。假设舍入模式是舍入到最近的,并列到偶数。)
NaN是 IEEE 754 标准中定义的浮点运算概念,不是数字,与负无穷或正无穷不同,NaN用于无法表示的算术值,不是因为它们太小或太大,而是简单因为它们不存在。例子:
1/0 = \xe2\x88\x9e //too large \nlog (0) = -\xe2\x88\x9e //too small\nsqrt (-1) = NaN //is not a number, can\'t be calculated\nRun Code Online (Sandbox Code Playgroud)\n\n\nIEEE 754 浮点数可以表示正无穷大或负无穷大以及 NaN(不是数字)。这三个值是由结果未定义或无法准确表示的计算产生的。您还可以特意为其中任何一个设置浮点变量,这有时很有用。产生无穷大或 NaN 的一些计算示例:
\n
您使用这些标志的目的是符合上述标准。它指定了要记录在状态标志中的五个算术异常:
\nFE_INEXACT:结果不精确,需要舍入才能存储早期浮点运算的结果。
\n\n如果舍入(和返回)值与运算的数学精确结果不同,则设置。
\n
FE_UNDERFLOW:早期浮点运算的结果不正常,并且有精度损失。
\n\n如果舍入值很小(如 IEEE 754 中指定)且不精确(或者可能仅限于它具有非规范化损失,如 IEEE 754 的 1984 版本),则设置,返回包含零的次正规值。
\n
FE_OVERFLOW:早期浮点运算的结果太大而无法表示。
\n\n如果四舍五入值的绝对值太大而无法表示,则设置。返回无穷大或最大有限值,具体取决于使用的舍入方式。
\n
FE_DIVBYZERO:早期浮点运算中发生极点错误。
\n\n如果给定有限操作数结果为无限,则设置,返回无穷大,即 +\xe2\x88\x9e 或 \xe2\x88\x92\xe2\x88\x9e。
\n
FE_INVALID:早期浮点运算中发生域错误。
\n\n如果无法返回实值结果,例如 sqrt(\xe2\x88\x921) 或 0/0,则设置,返回安静的 NaN。*
\n
*安静的概念NaN:
\n\n安静的 NaN 或 qNaN 在大多数操作中传播时不会引发任何其他异常。例外情况是 NaN 不能简单地原封不动地传递到输出,例如在格式转换或某些比较操作中。
\n
资料来源:
\n\n\n\n\n