如何将浮点数的C代码转换为定点数?

14

我有一份使用double类型的C代码,想在DSP(TMS320)上运行该代码。但是该DSP不支持double类型,只支持定点数。如何最好地将代码转换为定点数?是否有一个良好的C库可用于定点数(实现为整数)?


3
这是一个相当重要的话题。在这个 Stack Overflow 的问题中有一个很好的讨论:https://dev59.com/pnVD5IYBdhLWcg3wHn2d。几乎所有的答案都有一些有用的信息。 - mtrw
1
出于好奇,DSP的编译器如何表示定点数?是用两个整数吗?例如,您如何将两个定点数相加? - chrisaycock
它们表示为32位值(long),类型中隐含了移位。例如,如果小数点后有16位(_iq16),则用底层类型中的整数65536表示定点数1.0。对于相同类型的定点数进行加减运算,可以使用标准整数运算。乘法需要额外的移位来纠正缩放。 - starblue
5个回答

14
以下代码定义了一个类型 Fixed,使用整数作为其内部表示。加法和减法直接使用 +- 运算符进行。乘法使用定义的 MULT 宏进行。
#include <stdio.h>
typedef int Fixed;

#define FRACT_BITS 16
#define FRACT_BITS_D2 8
#define FIXED_ONE (1 << FRACT_BITS)
#define INT2FIXED(x) ((x) << FRACT_BITS)
#define FLOAT2FIXED(x) ((int)((x) * (1 << FRACT_BITS))) 
#define FIXED2INT(x) ((x) >> FRACT_BITS)
#define FIXED2DOUBLE(x) (((double)(x)) / (1 << FRACT_BITS))
#define MULT(x, y) ( ((x) >> FRACT_BITS_D2) * ((y)>> FRACT_BITS_D2) )

我在我的图像处理算法中使用了上述代码来表示分数。它比使用双精度版本要快,而且结果几乎完全相同。


请查看这个库:http://www.sf.net/projects/fixedptc - Bernardo Ramos

8
TI提供了一个名为"IQmath"的定点库:http://focus.ti.com/lit/sw/sprc990/sprc990.pdf。转换需要分析您当前的代码-对于每个变量,您需要知道它可以包含什么范围以及需要什么精度。然后您可以决定将其存储在哪种类型中。IQMath提供从q30到q1的类型,范围从+/-2到+/-1000000,精度从0.0000000001到0.5不等。对于可能超出变量范围的操作,您需要添加溢出检查,并决定如何处理它-将其固定在最大值处,使用不同的比例存储,引发错误等等。实际上,没有一种方法可以在不深入了解流程数据的情况下转换为定点数。

5

大多数DSP工具链都包含用于在软件中模拟浮点运算的库。这样做速度会很慢,但您应该最初构建带有浮点支持的代码,然后进行性能测试,看是否只需要将少数几个地方转换为定点表示以获得足够的性能。在移植到定点表示时,您还需要保留浮点运算,以便进行比较,确保在此过程中没有失去任何东西。


2
如果C代码很少使用double类型,那么您可以使用浮点数模拟库而不会导致C代码运行速度变慢10倍到100倍。如果您不想承受这种性能损失,并且有大量的浮点运算,并且您知道每个实际输入的算术和存储操作所需的比例和精度,则可以手动将每个算术操作转换为使用缩放整数数据类型和操作。但是分析DSP类型代码的精度要求通常是非常困难的。有许多关于此主题的DSP和数值方法教材章节。

请详细说明最后一句话,以便使其有助于解决问题。 - jpinto3912

0

有一些库可以为您完成此操作。不过,您的设备的PSP应该包含某种数学库。它应该有文档说明。您可能需要重新编写一些代码,因为在使用由PSP提供的API时,进行基于原始浮点算术时使用的控制结构可能没有意义。

例如-您可能会将此转换

double arraysum = 0.0;
for (int i = 0; i < arraylen; i++) 
{
    arraysum += array[i];
}

到这里

psp_decimal_t arraysum;
if (0 != psp_sum_elements(&array, arraylen, &arraysum))
{
    printf("error!");
}

不幸的是,我无法在其他任何地方找到那个内容,也找不到发布它的个人。 - Ben Collins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接