在尝试了解浮点下溢情况下会发生什么时,我发现我可以使浮点数比 FLT_MIN 小得多。我在 OS 10.9 上使用 xcode 5.1。语言方言是 gnu99。
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
int main(int argc, const char * argv[])
{
float underflow = FLT_MIN * 0.0000004;
printf("Float min is %f or %e.\nUnderflow is %f or %e\nMin float exp is %d.\n", FLT_MIN, FLT_MIN, underflow, underflow, FLT_MIN_10_EXP);
return 0;
}
Prints:
浮点数最小值为 0.000000 或 1.175494e-38。
下溢为 0.000000 或 4.203895e-45
最小浮点数exp为-37。
- 有没有更有效的方法来证明数据类型的限制?
- 为什么 FLT_MIN 实际上不是最小的浮点值?我还应该使用其他常量吗?输入上一个问题后,我发现 FLT_TRUE_MIN。这个数字是多少?
达到“低于最低值”的两种可能性:
-
float
range:
Typical float
数字有 2 个范围:全精度(正常范围)从FLT_MAX
向下FLT_MIN
和第二个范围,其精度降低FLT_MIN
向下FLT_TRUE_MIN
。第二个范围称为“次正常”,通常提供大约 10^-7 以上的范围。
FLT_TRUE_MIN
是“最小正浮点数”
FLT_MIN
是“最小标准化正浮点数”
FLT_MIN_10_EXP
是“使得 10 的幂在归一化浮点数范围内的最小负整数”
C11dr §5.2.4.2.2
一般来说0 < FLT_TRUE_MIN <= FLT_MIN <= 10^FLT_MIN_10_EXP <= 10^-37
-
数学表现为double
.
printf()
隐蔽每个float
传递给它一个double
。 C 允许优化代码,以便将值传递给printf()
可能是double
的产品FLT_MIN * 0.0000004
.
float underflow = FLT_MIN * 0.0000004;
printf("%e\n", underflow);
如果输出是4.701976e-45
而不是4.203895e-45
,情况本来就是这样。
注意“次正常”。一个令人信服的理由for次正规(或非正规)数存在以下问题。
float a,b;
... // somehow a and b are set.
// Are the 2 below equivalent?
if (a == b) foo();
if ((a - b) == 0) foo();
没有次正规数,附近有 2 个几乎相同值的数FLT_MIN
会有一个非零的数学差异远低于FLT_MIN
结果将四舍五入为0.0
.
对于次正规数,每对不同的数之差float
s 可以用除0.0
. **
** 除了+0.0, -0.0
。有符号零有其自身的特点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)