为什么FLT_MIN等于零?

32

limits.h规定了非浮点数的数学类型的限制,例如INT_MININT_MAX。这些值是您可以使用int表示的最负和最正的值。

float.h中,有FLT_MINFLT_MAX的定义。如果您执行以下操作:

NSLog(@"%f %f", FLT_MIN, FLT_MAX);

你会得到以下输出:

FLT_MIN = 0.000000, FLT_MAX = 340282346638528859811704183484516925440.000000

FLT_MAX等于一个非常大的数,这是可以预料的,但为什么FLT_MIN等于零而不是一个非常大的负数呢?


1
我的机器上的FLT_MIN1.17549435e-38F - Carl Norum
3
你是如何检查数值的?在某个头文件中查找吗?使用printf吗?(如果你正在使用printf,你不会使用“%f”,对吧?你需要使用“%e”来获取指数表示法。) - Cascabel
我已经更新了问题和答案,以澄清%f printf问题。 - Nick Forge
尝试使用 printf("FLT_MIN: %.100f\n", FLT_MIN); - Slipp D. Thompson
@SlippD.Thompson 请尝试阅读现有的答案;-) - Nick Forge
@NickForge 是的,完全正确。它适用于两个答案,但包含了额外的信息,所以我把它放在这里。似乎也不需要另一个答案。 - Slipp D. Thompson
4个回答

60

实际上不是零,但如果你使用printfNSLog并使用%f进行检查,则可能看起来像零。
根据float.h(至少在Mac OS X 10.6.2中),FLT_MIN被描述为:

/* Minimum normalized positive floating-point number, b**(emin - 1).  */
注意该句子中的“正数”一词:FLT_MIN表示大于零的最小(归一化)数字。(还有比这更小的非归一化数字。)
如果您想要最小的浮点数(包括负数),请使用-FLT_MAX

这甚至对我来说都不像是一个答案 - 我以为你的问题是为什么它是零而不是非常小且正数。 - Cascabel
2
我已更新答案 - 你完全正确,它并不是零。我会更新问题以反映当你使用printf时它“看起来像”零,而不是实际上是零。 - Nick Forge
2
注释中的文本“最小规格化正浮点数,b **(emin-1)”直接来自C标准,并且对于任何C实现都是有效的(请参见ISO / IEC 9899:TC2 5.2.4.2.2 / 11)。 - James McNellis
2
@Nick:如果使用指数表示法,它看起来不像零。 - Cascabel
2
FLT_MIN 是指最小的正规化正浮点数。最小的正浮点数是一个非规约数,即2^(-149)≈ 1.4013e-45。 - Edgar Bonet
显示剩余3条评论

16

'%f'格式以固定格式打印6个小数位。 由于FLT_MIN要小得多,因此在固定点中看起来像零。 如果您使用'%e'或'%g'格式,则可以获得更好的格式化答案。 FLT_MAX同理。

#include <float.h>
#include <stdio.h>
int main(void)
{
    printf("MIN = %f, MAX = %f\n", FLT_MIN, FLT_MAX);
    printf("MIN = %e, MAX = %e\n", FLT_MIN, FLT_MAX);
    return(0);
}


MIN = 0.000000, MAX = 340282346638528859811704183484516925440.000000
MIN = 1.175494e-38, MAX = 3.402823e+38

2
每当您尝试从标准头文件float.h中打印FLT_MIN的值时,您将获得0.000000(就像您在输出屏幕上看到的那样)。这实际上并不是一个错误。您得到这个结果是因为格式说明符%f。通常,%f在小数点后打印6位数字,但在这种情况下,有符号负值很小,您需要在小数点后打印大量数字。
我使用了%.54f(与机器有关)来获得所需的结果(对于我的系统为0.000000000000000000000000000000000000011754943508222875)。
//请在您的系统上检查
#include<stdio.h>
#include<float.h>
int main()
{
    printf("Minimum signed float %.55f\n",FLT_MIN);
    printf("Minimum signed float %e\n",FLT_MIN);
    return 0;
}

//输出:

// 最小的有符号浮点数 0.0000000000000000000000000000000000000117549435082228750

// 最小的有符号浮点数 1.175494e-038

我认为现在你应该清楚为什么CHAR_MIN会得到0.000000以及如何使用相同的格式说明符获得正确的结果。虽然您可以使用%e来获得更好的格式化结果。


1

为什么FLT_MIN等于零?

它并不等于零。由于使用了"%f",它显示为0.000000,该格式在小数点后打印6个数字。
FLT_MIN通常具有约为1.17549435e-38的值。


参考资料

虽然这个问题已经被回答了,但我认为我应该发布二进制32位浮点数FLT_TRUE_MIN, FLT_MIN, FLT_MAX的确切值以及它们最近的float邻居。

// Approximate value, exact value
Before, FLT_TRUE_MIN, after
 0.00000000e+00 0.0
 1.40129846e-45 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125
 2.80259693e-45 0.0000000000000000000000000000000000000000000028025969286496341418474591665798322625605238837530315435141365677795821653717212029732763767242431640625
Before, FLT_MIN, after
 1.17549421e-38 0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875
 1.17549435e-38 0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625
 1.17549449e-38 0.00000000000000000000000000000000000001175494490952133940450443629595204006810278684798281709160328881985245648433835441437622648663818836212158203125
Before, FLT_MAX, after
 3.40282326e+38 340282326356119256160033759537265639424.0
 3.40282347e+38 340282346638528859811704183484516925440.0
            inf inf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接