0

How to convert the floating point number to fixed point format fix16_14 in C. fix16_14 means 2-bit integer and 14-bit fraction? Consider an example: -0.99633 = c03c in hex (two's complement representation). Please help me with this C code logic.

user3386109
  • 34,287
  • 7
  • 49
  • 68
amit waghmare
  • 11
  • 1
  • 2
  • 1
    Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), especially ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also [take the tour](http://stackoverflow.com/tour) and [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask) and [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please learn how to create a [mcve]. – Some programmer dude Apr 23 '19 at 10:27

2 Answers2

1

The conversion is done by multiplying the float by 16384.0. Be sure to round the result. Also, since there are only 2 integer bits, the number must be in the range -2 <= x < 2. Otherwise the calculation will overflow.

Here's example code:

#include <stdio.h>
#include <inttypes.h>
#include <math.h>

int main(void)
{
    float x = -0.99633;
    short int y = round(x * 16384.0);
    printf("%#04hx\n", (unsigned short)y);
}

The output from the code is: 0xc03c

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • thanks for the logic, but why multiplication with 2^14 (16384.0) for a 14-bit fraction? – amit waghmare Apr 23 '19 at 14:54
  • @amitwaghmare The weights of binary bits are 8,4,2,1. When you have fractional binary bits, the weights continue to divide by two, so the weights are 1/2, 1/4, 1/8, 1/16, etc. So if you want to convert a number to `fix8_4`, you would multiply by 16. In general, to convert a binary fraction to a whole number, you multiply by the inverse of the weight of the least significant bit. In the case of `fix16_14`, the least significant bit has weight 1/16384, so you multiply by 16384. – user3386109 Apr 23 '19 at 17:29
0

Fixed Point Number

The shifting process above is the key to understand fixed point number representation. To represent a real number in computers (or any hardware in general), we can define a fixed point number type simply by implicitly fixing the binary point to be at some position of a numeral. We will then simply adhere to this implicit convention when we represent numbers.

To define a fixed point type conceptually, all we need are two parameters:

  • width of the number representation, and
  • binary point position within the number

We will use the notation fixed<w,b> for the rest of this article, where w denotes the number of bits used as a whole (the Width of a number), and b denotes the position of binary point counting from the least significant bit (counting from 0).

..................................

For example, fixed<8,3> denotes a 8-bit fixed point number, of which 3 right most bits are fractional. Therefore, the bit pattern:

0 0 0 1 0 1 1 0

represents a real number:

00010.1102

= 1 * 2^1 + 1 * 2^-1 + 1 * 2^-2

= 2 + 0.5 + 0.25

= 2.75

Note that on a computer, a bit patter can represents anything. Therefore the same bit pattern, if we "cast" it to another type, such as a fixed<8,5> type, will represents the number:

000.101102

= 1 * 2^-1 + 1 * 2^-3 + 1 * 2^-4

= 0.5 + 0.125 + 0.0625

= 0.6875

If we treat this bit patter as integer, it represents the number:

101102

= 1 * 2^4 + 1 * 2^2 + 1 * 2^1

= 16 + 4 + 2

= 22

Using Fixed Point Number in C

C does not have native "type" for fixed point number. However, due to the nature of fixed point representation, we simply don't need one. Recall all arithmetics on fixed point numbers are the same as integer, we can simply reuse the integer type int in C to perform fixed point arithmetic. The position of binary point only matters in cases when we print it on screen or perform arithmetic with different "type" (such as when adding int to fixed<32,6>).

Grant
  • 346
  • 2
  • 12
Mina Karam
  • 124
  • 1
  • 1
  • 10