Vic*_*tor 6 c floating-point gnu99
试图看看在浮动下溢的情况下会发生什么,我发现我可以使浮点数比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;
}
Run Code Online (Sandbox Code Playgroud)
打印:
Float min为0.000000或1.175494e-38.
下溢为0.000000或4.203895e-45
Min float exp为-37.
获得"低于最低"的2种可能性:
float 范围:
典型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);
Run Code Online (Sandbox Code Playgroud)
如果产出4.701976e-45不是4.203895e-45,那就是这种情况.
注意"次正常".一个令人信服的理由为低于正常(或反规范)数字主要表现在以下问题.
float a,b;
... // somehow a and b are set.
// Are the 2 below equivalent?
if (a == b) foo();
if ((a - b) == 0) foo();
Run Code Online (Sandbox Code Playgroud)
如果没有次正规数,则近似相同的2个数值FLT_MIN将具有非零的数学差异,FLT_MIN并且结果将舍入到0.0.
对于次正规数,每对不同floats 的差异可以用其他东西表示0.0.**
**除外+0.0, -0.0.签名零有自己的特点.
简单来说,浮点数存储为 0.xxxxx x 2^yyyyyy。“正常”数字要求在 xxxxx 部分没有前导零。所以你能做的最小数字是 0.10000 x 2^-111111。但是,如果您“作弊”并对数字进行非规范化,您可以制作一个像 0.000001 x 2^-111111 这样的数字,它更小但有效数字更少。
见http://en.wikipedia.org/wiki/Denormal_number