English 中文(简体)
How do I convert a floating point C code to fixed point?
原标题:

I have a C code which uses doubles. I want to be able to run the code on a DSP (TMS320). But the DSP doesn t support doubles, only fixed-point numbers. What is the best way to convert the code into fixed-point? Is there a good C library for fixed-point numbers (implemented as integers)?

最佳回答

TI provides a fixed-point library called "IQmath":

http://focus.ti.com/lit/sw/sprc990/sprc990.pdf

Converting involves analyzing your current code - for each variable you need to know what range it can hold, and what precision it needs. Then you can decide which type to store it in. IQMath provides types from q30 with a range of +/-2 and a precision of 0.0000000001 to q1 with a range of ~+/- 1 million and a precision of 0.5.

For operations which can possibly overflow the range of the variables, you need to add checks for overflow, and decide how to handle it - pin it at max, store with a different scale, raise an error, etc.

There is really no way to convert to fixed point without really gaining a deep understanding of the dataflow of your process.

问题回答

The following code defines a type Fixed, using integers as its internal representation. Additions and subtractions are performed simply with the + and - operators. Multiplication is performed using the defined MULT macro.

#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) )

I was using the above code to represent fractions in my image processing algorithm. It was faster than the version which was using doubles and the results were almost exactly the same.

Most DSP toolchains include libraries for floating-point emulation in software. This will be slow, but you should initially build your code with floating-point support, then profile to see if there are just a few places that you need to convert to fixed-point to get sufficient performance. You will also need to have the floating-point stuff running to provide a comparison as you port to fixed-point, to make sure you haven t lost anything in the process.

If the C code uses doubles very seldom/sparsely, then you might be able to use a floating point emulation library without causing your C code to run 10X to 100X slower. If don t want that performance hit and there are a lot of floating point operations, and you know the scale and precision required at every arithmetic and store operation for every realistic input, then you might be able convert each arithmetic operation, manually, to used scaled integer data types and operations. But analyzing precision requirements is, in general, non-trivial for DSP type code. There are many DSP and Numerical Methods textbook chapters on the subject.

There are a few libraries out there that may do this for you. More likely, though, the PSP for your device should include some sort of math library. It should be documented. You will likely have to re-write some your code, because the control constructs you use when doing primitive-based floating-point arithmetic may not make sense when you use the API provided by your PSP.

For example - you might convert this

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

to this

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




相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签