我正在寻找有关如何以独立于架构的方式查找浮点数的大小(以位为单位)和范围的建议。代码可以使用不同的标志在各种平台(AIX、Linux、HPUX、VMS,也许是 Windoze)上构建 - 所以结果应该会有所不同。符号,我只看到了一点,但是如何测量指数和尾数的大小?
5 回答
由于您正在考虑构建多个系统,因此我认为您可能正在考虑使用 GCC 进行编译。
关于浮点的一些很好的信息 - 这是几乎所有现代架构都使用的: http ://en.wikipedia.org/wiki/IEEE_754
这详细说明了可能出现的一些差异 http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html
当您按照之前评论中建议的链接进行操作时,您可能会看到对每个计算机科学家应该了解的浮点运算的参考。无论如何,花时间阅读这篇论文。当讨论浮点数时,它会随处弹出。
查看 中定义的值float.h
。那些应该给你你需要的价值观。
它相对容易找到:
十进制或二进制;
myfloat a = 2.0,
b = 0.0;
for (int i=0; i<20; i++)
b += 0.1;
(a == b) => decimal, else binary
原因:所有二进制系统都可以表示 2.0,但是任何二进制系统都会有一个表示 0.1 的错误项。通过累积,您可以确定这个错误项不会像舍入那样消失:例如 1.0 == 3.0*(1.0/3.0) 即使在二进制系统中
尾数长度:
Myfloat a = 1.0,
b = 1.0,
c,
inc = 1.0;
int mantissabits = 0;
do {
mantissabits++;
inc *= 0.5; // effectively shift to the right
c = b+inc;
} while (a != c);
您正在添加递减项,直到达到尾数的容量。它为浮点数返回 24 位,为双精度返回 53 位,这是正确的(尾数本身仅包含 23/52 位,但由于第一位始终是标准化值的一位,因此您有一个隐藏的额外位)。
指数长度:
Myfloat a = 1.0;
int max = 0,
min = 0;
while (true) {
a *= 2.0;
if (a != NaN && a != Infinity && whatever) // depends on system
max++;
else
break;
}
a = 1.0;
while (true) {
a *= 0.5;
if (a != 0.0)
min--;
else
break;
}
您正在向左或向右移动 1.0,直到到达顶部或底部。通常 exp 范围是-(max+1) - max
.
如果min
小于-(max+1)
,则您有(如浮点数和双精度数一样)次正规。通常正值和负值是对称的(可能有一个偏移量),但您可以通过添加负值来调整测试。
用于将每个字段存储在浮点数中的位数不会改变。
Sign Exponent Fraction Bias
Single Precision 1 [31] 8 [30-23] 23 [22-00] 127
Double Precision 1 [63] 11 [62-52] 52 [51-00] 1023
编辑:正如 Jonathan 在评论中指出的那样,我省略了long double类型。我将把它的位分解作为练习留给读者。:)