5分钟聊聊浮点数的底层存储

Posted nzsm0bfi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5分钟聊聊浮点数的底层存储相关的知识,希望对你有一定的参考价值。

浮点数的二进制表示,基本上就是用二进制的科学计数法来表示。

一个十进制的数0.75,用科学计数法表示是+7.5*10^-1,分为3个部分,正负号、7.5和-1。

其中小数点前的部分,一定是一个1-9之间的数。也就是你不能写成+75*10^-2。

好了,换成2进制(以下均以float类型为例),由于它占用的位数有限(一般是32位),因此我们需要仿照十进制科学计数法的方式,把这些位切分为3部分。

符号只有正负,因此用1位表示。

指数和尾数部分的划分决定了数字能表示的最大值和精度。IEEE的标准,指数位是8位,剩下是尾数位。

8位可以表示的范围是0到255,或者-127到+128,为了能表示2^-1的概念,选择后者。

尾数的精髓在于跟十进制的表示一样,刚才说十进制的小数点之前是1-9,那么二进制的小数点之前一定有一个1。
二进制转十进制

以下面这一串比特位为例:

0-01111110-10000000000000000000000

0是符号位,代表正数。

中间是指数位,写成十进制是126,减去127之后得到-1。

最后是尾数,忽略末尾的0,同时在小数点前补1,得到1.1,转成十进制是1.5。

我们把三个部分拼起来,得到+1.5*2^-1=0.75
十进制转二进制

以2.75为例子,先把小数点前后都写成二进制形式,得到10.11。

10.112^0不满足要求,为了让小数点前的数是1,所以我们向左挪一下小数点,得到1.0112^1。

(上面这步和把7510^0写成7.510^1是一个意思)

最后我们把3个部分提取出来,分别是符号位0,指数位1+127=10000000,尾数位0110…

以上是关于5分钟聊聊浮点数的底层存储的主要内容,如果未能解决你的问题,请参考以下文章

IEEE浮点数floatdouble的存储结构

OpenGL:为啥我不能将单个浮点数从顶点着色器传递到片段着色器?

单精度浮点数操作

什么是浮点数格式?

内部格式为 GL_RGBA8 的纹理在片段着色器中显示为浮点数

C++浮点数误差是啥