定点小数(Fixed Point)

定点小数是一种用固定位数表示小数部分的数值表示方法。在定点小数中,小数点的位置是固定的,不像浮点数那样可以在数字中的不同位置浮动。

1. 存储原理

使用定点数存储小数,我们首先得先确定:

  1. 使用多少字节内存空间进行存储,1个字节、2个字节、还是其他多少个字节
  2. 这些二进制位中,符号位占多少位,整数位占多少位,小数位占多少位

假设:使用单字节(8个二进制位)存储定点小数,其中:

  1. 符号位:1
  2. 整数位:4
  3. 小数位:3

如下图所示:

此时,小数点的位置就固定了。其能够表示的数值范围为:-15 ~ 15,小数位表示的数值范围为:-0.875 ~ 0.875,所以其能表示的小数范围为:-15.875 ~ 15.875。

需要注意的是:

  1. 小数点并不占二进制位
  2. 小数点位置并没有标准规定
  3. 整数位多了,小数位则就会变少

接下来,通过一个例子来了解浮点小数 3.75 如何存储到定点数空间中:

  1. 符号位: 0
  2. 整数位:0011
  3. 小数位:110

即:浮点小数 3.75 使用定点小数存储后位:0 0011 110

定点数的存储方式更为简单,为什么计算机不默认使用这种方式?
这是由于定点数表示的数值范围太小了,进行小数运算时很容易溢出。

2. 浮点数转换

定点小数和浮点小数之间可以进行相互转换,计算公式如下:

其中

  1. (int) 表示取整操作,可以向下取整,当然也可以向上取整,当然也可以四舍五入;
  2. Q 是定点数表示中的小数位数。

例如:浮点小数 3.75 转换为 8 位(单字节)的定点小数,其中1个符号位,4个整数位,3个小数位,计算如下:

  1. \((int)3.75*2^{3}=30\),即:使用 8 位定点数表示为:30,二进制表示为:0 0011 110
  2. \((float)30*2^{-3}=3.75\),即: 使用浮点数(float32)表示为:3.75,二进制表示为:0 10000000 11100000000000000000000

需要注意:浮点数在转换为定点数的过程中会产生误差。比如:0.78 的按照前面设定的 8 位定点数表示为:6.24≈6,再将定点数转换为浮点数为:0.75,存在 0.03 的误差。

3. 相较浮点数

  1. 内存占用优势:定点数通常需要更少的内存空间来存储。
  2. 数据传输优势:定点数需要更少的位数来表示相同的数值范围和精度,这意味着在数据传输过程中需要传输的数据量更少。
  3. 计算速度优势:定点数的计算通常比浮点数更快。因为定点数的计算通常可以在硬件层面更高效地执行,而且不涉及额外的指数部分的计算。定点数的计算速度可能会更快,并且在一些硬件架构中,可能会有专门的指令集来优化定点数的计算。

我们现在对于大模型使用的量化技术,其原理也是将模型中的 float32 类型参数转换为 int8、int16 的定点小数,从而实现更小的空间占用、更快的模型推理。

未经允许不得转载:一亩三分地 » 定点小数(Fixed Point)
评论 (0)

5 + 6 =