-1

I am using a library which has fixed point variables.The library is called libfixmath.

I am trying to see how a number gets converted from a fix16_t to a float type. I understand it uses 32 bits (16 MSB bits for integers and 16 LSB bits for decimals) to represent a number.

This is the code I tried, here "sum" is of type fix16_t.

float in_sum = fix16_to_float(sum);
printf("fix16 type sum:%u\n",sum);
printf("float type sum:%f\n",in_sum);

I display the "sum" in an unsigned integer format, again I'm not sure the best format to display the "sum" value.

A sample output I got is:

fix16 type sum:4064807395
float type sum:-3511.961426

I had a look at the conversion function:

static inline float   fix16_to_float(fix16_t a) { return (float)a / fix16_one; }

Where fix16_one is 65536.

To get a better understanding I want to be able to convert this manually, but I do not know how. I am confused with the type casting (float)a.

Another question I have is, are the 16 integer bits signed or unsigned?

ghostwar 88
  • 547
  • 1
  • 6
  • 17

1 Answers1

2

If fix16_t is an integer type, then a / 65536 would be an integer division, without any decimals. For example 65535 / 65536 is not the floating point value 0.99998, but the integer value 0.

The casting of a converts a and therefore the whole expression into a floating point division, with decimals.


Using the values:

  1. Integer division: -230159901 / 65536 will result in the integer value -3511.
  2. Floating point division: (float)-230159901 / 65536 will result in the float value -3511.961426.
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • When I use a calculator to do 4064807395 / 65536. I get 62024. Which is not what the program calculates (which is -3511). What calculation can I use to get the same as the example? – ghostwar 88 Nov 29 '18 at 11:06
  • 1
    @ghostwar88 The problem is one of *undefined behavior* in your `printf` call. The `"%u"` format is for ***unsigned*** `int`, while the type `int32_t` is ***signed*** (and should therefore use `"%d"`, or better yet `printf("fix16 type sum:"PRId32"\n", sum);`) The actual value isn't what you think it is. – Some programmer dude Nov 29 '18 at 11:10
  • Thanks I'll try it out – ghostwar 88 Nov 29 '18 at 11:11
  • using '%d' I got ' fix16 type sum:-230159901 float type sum:-3511.961426 ', but using 'PRId32', I just got 'fix16 type sum:d' – ghostwar 88 Nov 29 '18 at 11:16
  • 1
    @ghostwar88 Ah I forgot the `%`: `printf("fix16 type sum:%"PRId32"\n", sum);` It should give the same result though (`-230159901`). – Some programmer dude Nov 29 '18 at 11:16
  • Ok, I get the same result as using `%d`. Thank you for your help :) – ghostwar 88 Nov 29 '18 at 11:21
  • 2
    Re “with decimals”: Dividing binary floating-point numbers may create fractional (non-integral) values, not decimals. Consider binary floating-point data as decimal leads to incorrect and/or inaccurate reasoning about behavior. – Eric Postpischil Nov 29 '18 at 16:20