IQmath库是TI C28x系列DSP中使用的一个高度优化且高精度的数学库,用于使用定点算法实现浮点运算。在DSP编程中,出于性能的考虑,应尽量使用IQmath库代替ANSI C中的math库。IQmath库同时支持C和C++,此处仅讨论使用C语言的情况。
IQmath的官方使用手册为SPRC990 C28x IQmath Library
,在ControlSUITE中可以找到这份文档的最新版本。
使用方法
- 添加库文件
IQmath.lib
或IQmath_f32.lib
,后者用于带FPU单元的DSP; - 包含头文件
IQmathLib.h
; - 修改CMD文件,添加其中与IQmath相关的部分。
Q格式
Q格式是一种定点小数表示方法,具体来说,二者的转换关系为:
**定点数 = 浮点数 * 2^Q **
在C2000中,统一使用32位来表示。QN格式对应数据类型为_iqN,表示使用N位来表示小数,其余32-N位表示整数,故Q0其实就是一般的32位整数。具体的Q1~Q30的取值范围及精度见下表:
_iq
类型代表使用GLOBAL_Q
定义的精度,GLOBAL_Q
在IQmathLib.h
文件中定义,默认为:
1 |
可直接更改IQmathLib.h
文件中的定义,也可使用如下方法覆盖此定义:
1 |
常用函数
函数命名惯例为:_IQNxxx()
,其中N
代表使用的Q格式,省略的话使用GLOBAL_Q
中的定义;xxx
为函数名,如sin
、exp
等。下面列举一些常用函数,其中的N
大部分都可以省略使用GLOBAL_Q
。
格式转换
函数原型 | 说明 |
---|---|
_iqN _IQN(float F) |
将float 转为_iqN 格式 |
float _IQNtoF(_qiN A) |
将_iqN 格式转为float |
_iqN _IQtoIQN(_iq A) |
将全局_iq 格式转为_iqN 格式 |
_iq _IQNtoIQ(_iqN A) |
将_iqN 格式转为全局_iq 格式 |
long _IQNint(_iqN A) |
提取整数部分 |
_iqN _IQNfrac(_iqN A) |
提取小数部分 |
_iqN _atoIQN(char *S) |
将字符串转为_iqN 格式 |
int _IQNtoa(char *S, const *format, long x) |
将_iqN 格式转为字符串 |
算数运算
对于相同_iqN
格式的两个数之间的加减法,可以使用+
、-
直接进行,注意不要溢出即可;对于不同_iqN
格式的两个数,需要转换为相同_iqN
格式后再进行加减。
函数原型 | 说明 |
---|---|
_iqN _IQNmpy(_iqN A, _iqN B) |
基本乘法 |
_iqN _IQNrsmpy(_iqN A, _iqN B) |
带凑整(rounding)和饱和(saturation)的乘法 |
_iqN _IQNmpyI32(_iqN A, long B) |
_iqN 与long 相乘 |
_iqN _IQNdiv(_iqN A, _iqN B) |
基本除法 |
三角函数
函数原型 | 说明 |
---|---|
_iqN _IQNsin(_iqN A) |
正弦 |
_iqN _IQNcos(_iqN A) |
余弦 |
_iqN _IQNtan(_iqN A) |
正切 |
_iqN _IQNasin(_iqN A) |
反正弦 |
_iqN _IQNacos(_iqN A) |
反余弦 |
_iqN _IQNatan(_iqN A) |
反正切 |
其它常用函数
函数原型 | 说明 |
---|---|
_iqN _IQNabs(_iqN A) |
绝对值 |
_iqN _IQNexp(_iqN A) |
exp |
_iqN _IQNlog(_iqN A) |
自然对数 |
_iqN _IQNsqrt(_iqN A) |
开平方 |
_iqN _IQNisqrt(_iqN A) |
开平方后取倒数 |
_iqN _IQNmag(_iqN A, _iqN B) |
欧氏距离 |
Benchmark
完整的IQmath函数及性能评估表如下: