浮点数是以科学计数法来保存数据的方式

科学计数法

形如 7.823E5,表示  7.823 * 10^5  =  782500


如何存储?

百度搜索 “浮点数存储”


float

总占用 32 位

根据科学计数法,需要至少存储两部分  7.823 以及 指数 5

在计算机系统中,则增加一位符号位,即正负


  • sign: 符号位, 即图中蓝色的方块
  • biased exponent: 偏移后的指数位, 即图中绿色的方块
  • fraction: 尾数位, 即图中红色的方块


float 精度问题

如上所示,尾数位的存储是23bits,所以实际表达的只有23bits,最大值为16777216(如果保留两位小数,那么就只有16万

也就是有效数字只能是这么大,再大它就表达不了,例如16777216+1 = 16777217,这个 16777217 它表达不了,测试代码如下:

int tmp = 16777216;
temp += 1;
float f = Convert.ToSingle(tmp);

// f : 16777216.0

也就是它只能表达一个近似值,再来个例子,

int tmp = 16777216;
tmp *= 10;
tmp -= 1;
float f = Convert.ToSingle(tmp);
// f : 167772160.0

如上所示,期望是 167772160-1 = 167772159 ,实际为167772160


float 转换失真问题

例如 10.84 , 到了c# 会变成 10.840000000000003

这是由于浮点数是算出来的,在计算的时候存在失真的情况,

这涉及到转换的知识点:

  • 整数转二进制:采用"除2取余,逆序排列"法
  • 小数转二进制:采用"乘2取整,顺序排列"法

以0.7为例,直接使用”乘2取整,顺序排列“后可以看到,结果为0.10接上1100的无限循环。

剩余小数乘2取整数位
0.71.41
0.40.80
0.81.61
0.61.21
0.20.40
0.40.80
0.81.61
0.61.21
0.20.40
0.40.80