[牛人杂谈] 固定点数运算你会吗?

[复制链接]
905|4
 楼主| wahahaheihei 发表于 2024-2-27 16:03 | 显示全部楼层 |阅读模式
在计算机科学中,固定点数表示一种用于表示实数的方法,它将小数点固定在某个位置上,而不像浮点数那样可以在数值中移动。在 C 语言中,固定点数通常用于实现对小数进行精确计算的需求,特别是在没有浮点处理器的嵌入式系统中。

固定点数的表示方式类似于整数,但需要额外的规则来确定小数点的位置。通常,我们将一个整数视为包含小数点右侧一定位数的小数。例如,如果我们有一个16位的整数,我们可以将其解释为包含小数点右侧4位的小数。这意味着我们可以使用该整数表示范围内的值来表示从0到最大值之间的所有小数。通过这种方式,我们可以进行固定点数的计算,而不会丢失精度。

以下是一个简单的示例,展示如何在 C 语言中进行固定点数的加法运算:
  1. #include <stdio.h>

  2. #define FIXED_POINT_SHIFT 16 // 假设小数点右移16位

  3. // 固定点数加法
  4. int fixed_point_add(int a, int b) {
  5.     return a + b;
  6. }

  7. int main() {
  8.     int fixed_a = 100 << FIXED_POINT_SHIFT; // 将整数100左移16位,表示固定点数
  9.     int fixed_b = 200 << FIXED_POINT_SHIFT; // 将整数200左移16位,表示固定点数

  10.     int result = fixed_point_add(fixed_a, fixed_b);

  11.     printf("Fixed Point Result: %d\n", result);
  12.     printf("Float Point Result: %f\n", (float)result / (1 << FIXED_POINT_SHIFT)); // 将结果转换为浮点数输出

  13.     return 0;
  14. }
在这个示例中,我们假设小数点右移16位,然后将整数100和200分别转换为固定点数。然后,我们调用 fixed_point_add() 函数对这两个固定点数进行加法运算。最后,我们将结果打印出来,同时通过除以 2 的 16 次方将其转换回浮点数进行打印。

需要注意的是,在固定点数运算中,需要小心处理溢出和精度问题。由于固定点数的表示范围有限,可能会导致结果溢出或者失去精度。因此,在进行固定点数运算时,需要确保适当地选择表示位数,并且小心处理可能出现的溢出情况。

 楼主| wahahaheihei 发表于 2024-2-27 16:03 | 显示全部楼层
  1. typedef int16_t fixed_t;

  2. #define FIXED_SHIFT 8
  3. #define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 << FIXED_SHIFT)))
  4. #define FIXED_TO_FLOAT(f) ((float)(f) / (1 << FIXED_SHIFT))

  5. fixed_t fixed_multiply(fixed_t a, fixed_t b) {
  6.     return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
  7. }
 楼主| wahahaheihei 发表于 2024-2-27 16:03 | 显示全部楼层
在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。
heisexingqisi 发表于 2024-2-27 17:02 | 显示全部楼层
降低浮点开销的方法。
幸福小强 发表于 2024-2-28 17:05 | 显示全部楼层
如果知道要保留多少其实可以先放大,再运算,舍弃掉余数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

232

主题

3223

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部