Skip to content

Instantly share code, notes, and snippets.

@rasgo-cc
Last active August 29, 2015 14:24
Show Gist options
  • Save rasgo-cc/52773a91a4ac96a62bbb to your computer and use it in GitHub Desktop.
Save rasgo-cc/52773a91a4ac96a62bbb to your computer and use it in GitHub Desktop.
Fixed-point multiplication and division
// http://theramblingness.com
#include <stdio.h>
#include <stdint.h>
#define Qn 15 // Q-format
// These types should be defined according to CPU bitness
#define FXPLONG int64_t
#define FXPSHORT int32_t
int main()
{
// Variables
uint32_t scaler = (uint32_t)(1<<Qn);
FXPLONG tmp = 0;
FXPSHORT op1 = 0, op2 = 0;
FXPSHORT res;
double res_f;
double f_op1 = 0.654321;
double f_op2 = 0.123456;
double f_mul_res = f_op2*f_op2;
double f_div_res = f_op1/f_op2;
printf("f_op1: %f\n", f_op1);
printf("f_op2: %f\n", f_op2);
printf("f_mul_res: %f\n", f_mul_res);
printf("f_div_res: %f\n", f_div_res);
printf("Qn: %u\n", Qn);
printf("scaler: %u\n", scaler);
printf(" -- Fixed-point multiplication: (op2)^2\n");
op2 = (FXPSHORT)(f_op2*(double)scaler);
op1 = op2;
printf("op1: %d\n", op1);
printf("op2: %d\n", op2);
// Multiplication
// (the cast may also be applied to each operand individually)
tmp = (FXPLONG)op1*(FXPLONG)op2;
// Rounding
tmp = tmp + (FXPLONG)(1 << Qn);
// Truncation
tmp = tmp >> Qn;
// Discard the upper-half bytes of tmp to get the final result
res = (FXPSHORT) tmp;
res_f = (double)res/(double)scaler;
printf("res: %d (%f)\n", res, res_f);
printf("err: %f\n", res_f - f_mul_res);
printf(" -- Fixed-point division: op1/op2\n");
op1 = (FXPSHORT)(f_op1*(double)scaler);
op2 = (FXPSHORT)(f_op2*(double)scaler);
printf("op1: %08X %d (%f)\n", op1, op1, f_op1);
printf("op2: %08X %d (%f)\n", op2, op2, f_op2);
// Convert dividend to Q(2*n) format
tmp = ((FXPLONG)op1 << Qn);
// Round by summing half the divisor
tmp += op2 >> 1;
// Division
tmp /= (FXPLONG)(op2);
res = (FXPSHORT) tmp;
res_f = (double)res/(double)scaler;
printf("res: %08X %d (%f)\n", res, res, res_f);
printf("err: %f\n", res_f - f_div_res);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment