Hello everybody,

I am trying to convert data from float to fr16, do some arithmetic with the fr16 and then convert back to float as a test. I am using VisualDSP++5.0 with the Family Compiled Simulator.

Here is my code:

#include <math.h>

#include <stdio.h>

#include <fract2float_conv.h>

#include <fract_typedef.h>

int main(void)

{

float floatnumber, floatnumber2, addedfrac16fl;

fract16 frac16number, frac16number2, addedfrac16fr;

floatnumber=0.001234;

floatnumber2=0.001234;

//convert to fr16

frac16number=float_to_fr16(floatnumber);

frac16number2=float_to_fr16(floatnumber2);

//addition test

addedfrac16fr=add_fr1x16(frac16number,frac16number2);

//convert to float

addedfrac16fl=fr16_to_float(addedfrac16fr);

printf("addedfrac16fl= %f\n", addedfrac16fl);

return 0;

}

Print statement shows: addedfrac16fl= 0.002441

Why is it that adding 0.001234+0.001234=0.002441?? Doesn't the datatype fr16 have enough significant digits so that there shouldn't be any error?? Or is the add_fr1x16 not doing what I think it is doing?

Thanks!!

Hi,

You are correct, for a fract16 (1.

15format), the smallest resolution is 2^-15.To convert from float to fract16, the equation is x16 = (int) (xfloat * 2^15).

For xfloat = 0.001234, this would equate to:

x16 = (int) (0.001234 * 32768) = (int) (40.435712) = 40 = 0x28

To convert from a fract16 to a float, the equation is: xfloat = x16 / (2^15).

Thus x16 = 0x28 would equate to: xfloat = 40.0 / 32768.0 = 0.0012207;

For a fract32 (1.31 format), the same rules will apply, except that 2^15 and 2^-15 should be replaced with 2^31 and 2^-31 respectively.

The best way to think about fractional numbers is in terms of hex patterns since this maps to the way fractional numbers are organized:

1.15 => | 2^0 (==sign bit) | 2^-1 | 2^-2 | 2^-3 | .... | 2^-15 |

1.31 => | 2^0 (==sign bit) | 2^-1 | 2^-2 | 2^-3 | .... | 2^-15 | ... |2^-31|

For example:

------- fract16 ---------

float integer hex binary

-1 -32768 0x8000 [1000 0000 ...] = -1 * 2^0 = -1

-0.5 -16384 0xc000 [1100 0000 ...] = -1 * 2^0 + 2^-1 = -0.5

-0.375 -12288 0xd000 [1101 0000 ...] = -1 * 2^0 + 2^-1 + 2^-3 = -0.375

0 0 0x0000

3.0517578e-005 1 0x0001 [0000 0000 ... 0001] = 2^-15 = 0.000030517578125

0.001234 40 0x0028 [0000 ... 0010 1000] = 2^-10 + 2^-12 = 0.001220703125

0.5 16384 0x4000 [0100 0000 ...] = 0 * 2^0 + 2^-1 = 0.5

(1-(2^-15)) 32767 0x7fff [0111 1111 ...] = 0 * 2^0 + 2^-1 + 2^-2 + 2^-3 ... + 2^-15 = 0.9999695

In my experience, it works best printing fractional numbers as hexadecimals using printf("0x%4.4hx", x16). For a fract32 the equivalent would be printf("0x%8.8x", x32).

What I meant by granularity is that if you have a number like 0x6488 (=pi/4), a change in the least significant bit will not change the value by much: 0x6489 = 0.7854287 (compared to 0.7853982). However for a number like 0x28, the same change will have a more profound impact: 0x29 = 0.0012512 (compared to 0.0012207). In effect, the smaller a number the more significant the change (compared to the total value) between two adjacent numbers.

Hope this helps.

Andreas