我是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)
答案 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_MAX
,FLT_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
这个有效数将被舍入,因为它太大而无法在有效位中进行编码。同样地,向此数字添加少量数量也会导致有效数字被舍入,因此不会产生增量。