float存储原理

法国女足世界杯 3303

float占用4字节(32位),各bit的用途

31位:符号位,正数为0,负数为1。

23~30位:(指数部分,共8位):值减掉127后,表示小数点移动位数。比如:129表示小数点左移2位,124表示小数点右移3位。值为255有特殊用途,用于表示Infinity。

0~22位:(尾数部分,共23位)

0(111 1111 1)000 0000 0000 0000 0000 0000表示+Infinity

1(111 1111 1)000 0000 0000 0000 0000 0000表示-Infinity

浮点数十进制转二进制过程

1,整数部分除2取余,直到商为0,然后逆序排列得到的余数,如:十进制12

12/2=6 余0

6/2=3 余0

3/2=1 余1

1/2=0 余1,商为0,停止

得到的2进制就是1100

2,小数部分乘2取整,直到小数部分为0,然后顺序排列得到的整数。

有可能小数部分一直不为0,那就根据精度来终止计算。如:十进制0.125

0.125*2=0.25 整数部分0

0.25*2=0.5 整数部分0

0.5*2=1 整数部分1,小数部分0,停止

得到的2进制就是001

3,将1和2得到的数据拼接。1的结果放在小数点左边,2的结果放在小数点右边。

如:12.125的结果:1100.001

4,转为科学计数法。

1100.001小数点左移3位,1.100001*(23)

5,得出最终二进制

符号位:正数,所以是0

指数部分:小数点左移了3位,所以是3+127=130,二进制为1000 0010

尾数部分:取小数点右侧的那部分(.100001),不足23位的补0,得到:1000 0100 0000 0000 0000 000

最终结果:0 (100 0001 0)(100 0010 0000 0000 0000 0000)

根据二进制求出十进制float

例如:0(100 0001 0)(000 0100 0000 0000 0000 0000)

1)符号位(31位)

0,即正数

2)求出指数(23~30位)

指数=指数部分的值-127:1000 0010 - 127 = 130 - 127 = 3

3)尾数转小数:首位补1(为了节省空间,转换时去掉了首位的1,还原时需要补回来)

1.000 0100 0000 0000 0000 0000

4)拼接小数和指数,即用科学计数法表示:

1.000 0100 0000 0000 0000 0000*(23)

即小数点右移3位:1000. 0100 0000 0000 0000 0000

整数部分:1000 = 1*23 + 0*22 + 0*21 + 0*20 = 8

小数部分:.01 = 0*(2-1) + 1*(2-2) = 1/4 = 0.25

所以结果为8+0.25=8.25

float转二进制工具函数

/// float整数部分的二进制

public static string GetFloatBinString(int i)

{

var sb = new StringBuilder();

while (i > 1)

{

int bit = i % 2;

i /= 2;

sb.Insert(0, bit);

}

sb.Insert(0, i);

return sb.ToString();

}

/// float小数部分的二进制

public static string GetFloatBinString2(string floatStr, int bitNum)

{

int index = floatStr.IndexOf('.');

if (index > 0)

{

int lastIndex = floatStr.Length - 1;

char lastChar = floatStr[lastIndex];

if ('f' == lastChar)

lastIndex--;

if (index + 1 <= lastIndex)

{

string s = floatStr.Substring(index + 1, lastIndex - index);

var sb = new StringBuilder();

int n = int.Parse(s);

int n2 = (int)Math.Pow(10, s.Length);

for (int i = 0; i < bitNum; ++i)

{

n = n * 2;

if (n > n2)

{

sb.Append('1');

n -= n2;

}

else

{

sb.Append('0');

}

if (0 == n)

break;

}

return sb.ToString();

}

}

return "";

}

参考

【C#】浮点数存储原理浅析 - 知乎

float类型在内存中的存储方式_float在内存中如何存储-CSDN博客

float在内存中如何存储? - 彼岸Elan - 博客园

关于lua的math.huge有多大的问题-CSDN博客

lua number上限值 lua number 精度_mob64ca14137e4f的技术博客_51CTO博客

C# float浮点数与二进制相互转换(IEEE754) - 冰封百度的学习笔记 - SegmentFault 思否

C#浮点数的表示和基本运算_C#教程_脚本之家