Hello, I have to port following 2 code lines from floating to fixed point: ytotmax = MAX( yampl[c1], ytotmax ); yampl[c1] = MAX( G * ytotmax, yampl[c1] ); All variables are floatings, yampl is a buffer, ytotmax is a temp variable and G a weighting factor. For the further problem explanation, ul always stands for unsigned long. For scaling from floating point to fixed point, I do following: First, I looked at lots of our test files and searched for the biggest floating point value to scale underneath smaller 1. So, the biggest floating point value is 1042056.6 which I scale with 0x0100000h to 0.99378263950347900: temp_d = y_ampl[x] / Divisor = 1042056.6 / 0x0100000h = 0.99378263950347900 This value, stored as a double, will be scaled to fixed-point with #define LVHF_MAX_32 0x07FFFFFFF: temp_ul = temp_d * LVHF_MAX_32 = 0.99378263950347900 * 0x07FFFFFFF = 2134131967 Everything is OK. Now the problem, the G-value, which is 0.5 and which could also be expressed as a division by 2 value: double_G = float_G / Divisor = 0.5 / 0x0100000h = 4.7683715820312500e-007 ul_G = double_G * LVHF_MAX_32 = 1023 Fine. But when I do now a max-comparison, it won't work right, because ybuf_ul[x] = MAX( G * aValue_ul, ybuf_ul[x] ); the expression G * aValue_ul is now different, in floating point G was 0.5 and the result of the multiplication was always smaller then the former aValue_float, but now, it's a multiplication by 1023 and aValue_ul is not smaller, it's a bigger value then before. OK, the radix-point has changed and the range of values is different, but how to take this into account? OK, I remember some expressions like (for the TI C55xx platform): MAC uns(*AR0-),*CDP, AC2 :: MAC uns(*AR1-),*CDP, AC3 MAC *(AR0-T1), *CDP+, AC2>>#16 :: MAC *(AR1-T1), *CDP+, AC3>>#16 where after an multiply/accumulate the results was shifted to the right, so is this my problem in understanding, in G * aValue_ul I also have to do a right-shift? But which one, OK if G is 0.5 it's a right shift by 2, but G can also be 0.1, 0.6, 1.754, ... Thanks a lot for understanding and helping in my problem. Lovely greetz from Stefan
multiplication (by 0.1, 0.5, 0.7, 1.3 ...) in fixed point arithmetic
Started by ●August 25, 2004
Reply by ●August 27, 20042004-08-27
Hello. The first thing I found in your description was that convertig G as a weighting factor to fixed point is wrong. Your conversion by using the scheme fixed = float /0x0100000 *0x7FFFFFFF would result for G*value in (fixed)G*value = (float)G * (float)value /0x100000^2 *0x7FFFFFFF^2. That's where your multiplication error comes from. I have a question concerning your task: why fixed point? Do you have to port the task on a fixed point CPU? If so, there are floating point libraries for some fixed point processors available in the internet. I know of projects using open libraries for the PIC processors. But be careful, these are using a large amount of programming memory. The other way could be to develop your own floating point format, either by using the float-format with exponent and mantissa or by putting a virtual comma into your 32Bit-word. The bits left from the comma are the integer part of your number, the right hand part is the fraction. There are a lot of methods to be found describing this. Hope this helps. -------------- Heiko Marx DSP Engineer www.sinusmess.de
Reply by ●August 31, 20042004-08-31