单精度浮点数与机器精度(二)
NaN
上下溢出值
由浮点数的存储方式可以看出计算机所能表示的浮点数是有限的,我们把所能表示的最大正值称为上溢值,而把最接近0的正值称为下溢值。由表二我们看到上溢值为±3.40e38,下溢值为±1.40e-45。
二、机器精度
Wikipedia上机器精度Machine Epsilon是这样描述的:“Machine epsilon gives an upper bound on the relative error due to rounding in floating point arithmetic”。因为浮点数是离散的,所以实数的表示存在着误差。例如圆周率这样的无限不循环小数不可能精确地由某一个浮点数表示。
我们需要一些具体的量去刻画这种误差,以估计结果的准确性。机器精度便是其中之一:它是所有相对误差的上限。相对误差是绝对误差与精确值的比值的绝对值。例如一个精确的实数x,所有单精度浮点数中与x距离最近的数为y,绝对误差为|y-x|,相对误差即|y x||x|,而所有相对误差的上限便是单精度浮点数的机器精度。
对于32位浮点数,指数8位,尾数为23位。对于两个指数实际值为E的相同的浮点数,若它们尾数部分相差(00000000000000000000001)2,即2-23,易见它们是相邻的。那么与它们指数相同的实数x与距x最近的浮点数y之间的距离|y-x|一定小于此相邻两浮点数的距离2-23 * 2E。可以取x=1.0(或者其他任何数),此时实际指数为0,所以机器精度是2 23×201.0。
三、
C++程序实现
利用库求值
标准库中的numeric_limits类中包含了许多算数特殊值:
上溢值: std::numeric_limits::max();
规约下溢值: std::numeric_limits::min();
非规约下溢值: std::numeric_limits::denorm_min();
机器精度: std::numeric_limits::epsilon();
其中numeric_limits中float可以换成int,double等其它类型。
实际二进制存储值
复制代码
std::string get_binary(float f)
{
int index_byte, index_bit;
unsigned int byte = 0;
char ch, *p;
std::string bin_f = "";
p = (char *)(&f);
for (index_byte = sizeof(float)-1; index_byte>=0; index_byte--) {
ch = *(p+index_byte); //从最高位开始取
byte = ch; //将地址中8个二进制位赋值成十进制数
for (index_bit = 1; index_bit<=8; index_bit++) {
if (byte >=128) bin_f += "1";
else bin_f += "0"; //判断首位是1还是0
byte <<= 1; //将当前位变成首位
byte &= 255; //确保始终8个二进制位
}
}
return bin_f;
}