【C语言进阶日记】算法篇② 浮点数转换为定点数


一、概述

浮点数的处理需要大量的计算资源,尤其在嵌入式系统中,资源较为紧张。而定点数的计算效率高,资源占用小,因此熟悉浮点数与定点数之间的转换,对于计算机科学和嵌入式系统领域的工程师来说至关重要。

二、浮点数和定点数

浮点数包含符号位、指数和底数三部分。它能够表示非常大或非常小的数值,但计算复杂度较高。定点数则将数值分为整数部分和小数部分,表示的数值范围有限,但计算效率高,尤其适用于实时或资源限制的系统。

三、浮点数转换为定点数

通过以下简单的三步过程,我们可以将浮点数转换为定点数:

  1. 决定定点格式:format Qm.n (其中m表示整数部分位数,n表示小数部分位数)。
  2. 将浮点数乘以 2 的 n 次方(放大操作),以把要转换的浮点数移动到整数部分。
  3. 最后进行取整操作(一般采用四舍五入方法)。

四、实例

示例1:以 Q3.12 格式为例,假设我们需要转换的浮点数为 7.6。转换过程如下:

  1. 首先乘以 2 的 12 次方,得到 31129.6。
  2. 然后通过四舍五入取整,得到 31130。

因此,浮点数 7.6 在 Q3.12 格式下的表示是 31130。

示例2:以Q15的变量为例,对浮点数与定点数的转化作一番讨论:

  int16_t float_to_q15_f(double x)
  {
    return ((int16_t)((x) < 1 ? ((x) >= -1 ? (x)*0x8000 : 0x8000) : 0x7FFF));
  }

这里,如果传入的浮点数x在[-1, 1)范围内,那么就可以通过乘以32768(也就是0x8000,这代表的是2的15次方,也即是15位可以表示的最大值)转换成定点数。若x超过这个范围,则函数直接返回最大或最小的Q15可能值。

五、注意事项

  1. 转换过程中可能会出现溢出。如果浮点数的值大于定点数的最大表示范围,那么结果将产生溢出。在进行转换时,需确认浮点数的值在定点数的表示范围内。

  2. 定点数运算需要考虑运算过程中的溢出和舍入误差,必要时需要手动进行范围检测和舍入处理。

  3. 理解定点数的位移操作。位移操作主要有两种,逻辑位移和算术位移。左移是对所有位进行左移操作,左边超出的位被丢弃,右边用零填充,这等同于乘以2。右移操作有两种形式,逻辑右移和算术右移。
    逻辑右移:逻辑右移并不考虑符号位,所有位向右移动指定的位数,左边用零填充,右边的位被丢弃。这相当于无符号数的除以2操作。
    算术右移:算术右移则会考虑符号位,移动过程中,符号位不变,而其他位向右移动指定的位数,左边用符号位填充,右边的位被丢弃。这相当于有符号数的除以2操作。

  4. 在处理定点数的时候,我们需要对分数部分进行四舍五入操作,以提升精度,避免截断错误。
    例如,四舍五入操作可以通过以下步骤实现:
    将需要四舍五入的最低位设置为1(比如在Q15格式下,就是将第15位设置为1)。然后进行右移一位。这就完成了定点数的四舍五入操作。

  5. 定点数可以进行加、减、位移等基本运算,但在进行乘以、除以等运算的时候需要额外关注精度问题,务必避免溢出和除以0的情况。

六、总结

转换过程虽然简洁,却涵盖了基本的概念和原理,这也是掌握数字信号处理以及处理实时系统应用的基础。遵循这些步骤,可以有效地将浮点数转换成定点数,适用于嵌入式系统和其他资源受限或需要高性能的场景。

七、参考链接

本文结束,感谢您的阅读,希望对您有所帮助。如果有任何问题,欢迎在评论区提问讨论。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量子君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值