## Complete Communications Engineering

Fixed-point math is a way to represent fractional values using integers.  This is done by selecting a constant scaling factor that is implicitly applied to every value.  The scaling factor defines a step size, and the integer value defines a number of steps.  The number of steps is usually relative to zero.  Fixed-point math is commonly used for audio and video signal processing where each sample is represented by an integer, either signed or unsigned, with a fixed number of bits.  In many cases, the scaling factor is selected so the fractional range is -1.0 – 1.0 or 0 – 1.0, but other scaling factors may be used depending on the application.  The following table gives some examples:

 Type Scaling Factor Range 8-bit unsigned 1/256 0.0 – 0.99609375 16-bit unsigned 1/256 0.0 – 255.99609375 16-bit unsigned 1/65536 0.0 – 0.9999847412109375 16-bit signed 1/32768 -1.0 – 0.999969482421875

In computer programming, powers of 2 are commonly used as scaling factors because they can be applied by bit shifting.  This is required when multiplying and dividing fixed-point numbers to restore the proper scaling factor after the operation.  The following equations illustrate multiplication and division using fixed-point math:

 The actual value represented is an integer multiplied by the scaling factor. $x_f = x_i \cdot S$$x_f = x_i \cdot S$ For multiplication, the correct fractional result is obtained by multiplying the integer result by the scaling factor. $a_f \cdot b_f = c_f = (a_i \cdot S) \cdot (b_i \cdot S)= (a_i \cdot b_i ) \cdot S^{2}$$a_f \cdot b_f = c_f = (a_i \cdot S) \cdot (b_i \cdot S)= (a_i \cdot b_i ) \cdot S^{2}$$c_f = c_i \cdot S \to c_i = (a_i \cdot b_i) \cdot S$$c_f = c_i \cdot S \to c_i = (a_i \cdot b_i) \cdot S$ For division, the correct fractional result is obtained by dividing the integer result by the scaling factor. $\frac{a_f}{b_f} = c_f =\frac{a_i \cdot S}{b_i \cdot S} = \frac{a_i}{b_i}$$\frac{a_f}{b_f} = c_f =\frac{a_i \cdot S}{b_i \cdot S} = \frac{a_i}{b_i}$$c_f = c_i \cdot S \to c_i = \frac{a_i}{b_i \cdot S}$$c_f = c_i \cdot S \to c_i = \frac{a_i}{b_i \cdot S}$

In code, these operations require extra precision in the intermediate values.  The following code example demonstrates fixed-point multiplication and division in C:

fixed_point.c

 #include #include  /* Signed 16-bit integer range -1.0 – 1.0 */#define SCALE_SHIFT 15#define SCALE_FACTOR (1.0 / (double)(1 << SCALE_SHIFT)) int main(){    int16_t a, b, c;    int32_t temp;     a = 1234;   /* 0.03765869140625 */    b = 8765;   /* 0.267486572265625 */     temp = a * b;    c = (int16_t)(temp >> SCALE_SHIFT);    printf(“%d * %d = %d\n”, a, b, c);    printf(“%f * %f = %f\n”, a * SCALE_FACTOR, b * SCALE_FACTOR,                             c * SCALE_FACTOR);     temp = ((int32_t)a << SCALE_SHIFT) / b;    c = (int16_t)temp;    printf(“%d / %d = %d\n”, a, b, c);    printf(“%f / %f = %f\n”, a * SCALE_FACTOR, b * SCALE_FACTOR,                             c * SCALE_FACTOR);     return 0;}

Expected Output

 1234 * 8765 = 3300.037659 * 0.267487 = 0.0100711234 / 8765 = 46130.037659 / 0.267487 = 0.140778