C中浮子溢出的行为

时间:2017-05-15 20:46:44

标签: c

我是C的新手,到目前为止,我只使用过OOP语言而且从不必过多关注内存或位工作方式,我需要帮助围绕这里发生的事情。

我必须通过将变量初始化为数据类型的最小值/最大值并尝试添加或减去1来测试C中每种数据类型的最小和最大界限。我已经超过了整数类型现在我对Float类型的行为感到困惑。很多我一直在阅读的内容有点过头了,如果有人能帮我理解这些类型是如何工作的,我真的很感激。

这是我测试Float的原因:

void DisplayFloatMinimumAndMaximum()
{
// Declare variables
float fltMinimum = 0;
float fltMaximum = 0;

// Set min/max values
fltMinimum = -3.4e38;
fltMaximum = 3.4e38;

printf("Float Minimum and Maximum\n");
printf("------------------------------------------------\n");
printf("Float Minimum : %.10e\n", fltMinimum);
printf("Float Maximum : %.10e\n", fltMaximum);
printf("\n");

fltMinimum -= 1.0f;
fltMaximum += 1.0f;

printf("Confirmation\n");
printf("Float Minimum : %.10e\n", fltMinimum);
printf("Float Maximum : %.10e\n", fltMaximum);
printf("\n");
}

我得到的结果是:

Float Minimum and Maximum
------------------------------------------------
Float Minimum : -3.3999999521e+38
Float Maximum : 3.3999999521e+38

Confirmation
Float Minimum : -3.3999999521e+38
Float Maximum : 3.3999999521e+38

似乎根本没有发生任何事情 这是正确的行为吗?如果是这样,为什么?如果没有,为什么?

(我使用的是Visual Studio 2015)

2 个答案:

答案 0 :(得分:6)

由于数据的浮点性质,在这样一个大数字上加/减1没有任何作用,因为该值被“吸收”(如天气评论,在添加两个操作数之前,它们必须被标准化以便两个mantissae表示为2的相同幂。在这样做的情况下,如果较小的操作数滚降到0,则其所有重要性都将丢失)

值保持不变,无法达到溢出/下溢。

http://www.fact-index.com/f/fl/floating_point_1.html

要更改数字而添加的最小值由machine epsilon

决定

使用限制玩具的最佳方式是不添加,而是乘以(1+FLT_EPSILON)(相当于添加次数FLT_EPSILON

#include <float.h>
#include <stdio.h>

int main()
{
 float f = FLT_MAX;

 f *= (1+FLT_EPSILON/2);
 printf("%f\n",f);

return 0;
}

这打印数字,不变。吸收忽略了乘法。

现在这样做:

#include <float.h>
#include <stdio.h>

int main()
{
 float f = FLT_MAX;

 f *= (1+FLT_EPSILON);
 printf("%f\n",f);

return 0;
}

,输出

1.#INF00

FLT_MAX的情况下,在我的机器上,为触发溢出而添加的限制数超过1:它是40564816789451702000000000000000.000000

答案 1 :(得分:2)

浮点数限制

有定义限制的宏。 FLT_MAXFLT_MIN分别是float类型的最大值和最小值。

还有其他宏,例如FLT_MAX_EXP(根据FLT_RADIX定义的最大指数,通常值为2)和FLT_MAX_10_EXP(基数10中定义的最大指数) )。

float中可表示的最小数字是浮点epsilon,在FLT_EPSILON宏中定义,值为1E-5

可以在float.h

中找到这些宏

精密

注意:在本说明中,为了便于说明,我将使用10的基数。但是,C使用由上面提到的FLT_RADIX宏定义的基数(通常值为2)。

浮点数通过有效数和指数表示:

1234 = 1.234 x 10^3

在C中,单精度浮点数将为您提供24位有效数字,为指数提供8位。这意味着如果您的有效数字的位数多于有效位中可编码的数字,则会开始失去精度。

非常大的数字将带有有效数和指数。

1000000000000001将成为1.000000000000001 x 10^15

这个有效数将被舍入,因为它太大而无法在有效位中进行编码。同样地,向此数字添加少量数量也会导致有效数字被舍入,因此不会产生增量。