Microcontroller Aritmetic

Status
Not open for further replies.

akahrim

Member
Hello All,

I am trying to do math on a microcontroller. I'm using an 8bit micrcontroller from Atmel. I've read several articles on Fixed Point arthmetic and I am still a little confused on Fixed Point Arithmetic in regards to microcontrollers. The articles do not go into depth as to what happens in the microcontroller. Do microcontrollers without Floating point capability only understand integers? If so, Is the answer to Y=3/4 equal to zero in the microcontroller?

The other question I had is what happens if you have two 8bit integers (Y=100, X=100) and you multiply them ( Z=100x100, Z is also 8 bits). This creates an overflow but what actually happens when a variable overflows? I've googled it and I've seen explanations from "Undefined Behaviours" to wrapping. Any feedback would be greatly appreciated.
 
What language are you working in?

In fixed point you just move the decimal point around. So to find the circumference of a circle with radius 123 you would do 123 * 314 / 100 = 386 because 314 is Pi*100 so you need to divide after the multiply. Implementation depends on the language used.

Mike.
 
Hello Mike,

I'm working in C++.

Amir
 
In C it's up to you to ensure that integer maths is done correctly. Doing 123*314/100 will give the correct answer, doing 123/100*314 will give a wrong answer due to rounding (assuming left to right calculation). Likewise, overflow shouldn't be able to happen. Just use variables that are big enough that overflow won't occur.

Mike.
 

If you have three unsigned 8-bit integers:

uint8_t a = 100;
uint8_t b = 100;
uint8_t result;

and you multiply them
a * b;

What happens is, both variables are "promoted" to 16-bit integers and the multiplication is performed. The result is a 16 bit integer 10000 (decimal).
Which in binary form is: 0b00100111 00010000

Now, if you assign the result into an 8 bit integer only the lower 8 bits are saved:
result = a*b;

Result now contains the lower byte 0b00010000, which in decimal is 16.
 
Last edited:
Thanks for the reply Mike.
 
Hello MisterT, Thanks for the explanation. Makes perfect sense.

Amir
 

That is so easy to say. In reality fixed point math is full of traps.

Here is a fixed point macros that I used/wrote 5 years ago (There was one good source that I used, but I don't remember it). I don't remember if there was any serious bugs..
I also have square root and trigonometric functions, if somebody is interested.
C:
/* Some usefull constants (6.10 format only)*/
#define FPZERO        (0x0000)
#define FPONE        (0x0400)
#define FPTEN        (0x2800)
#define FPPI        (0x0c91)
#define FP2PI        (0x1922)
#define FPHALFPI    (0x0648)
#define FPSQRT2        (0x05a8)

/* M.N fixed point format */
#define M (6)
#define N (10)
#define NMASK (0x3ff)

typedef int16_t fp_t;
typedef int32_t fpdbl_t;

/*
* *****************************************************************************
* Public function prototypes and macros
* *****************************************************************************
*/
#define max(a,b) (((a)>(b)) ? (a):(b))
#define min(a,b) (((a)<(b)) ? (a):(b))
//#define abs(a)   (((a)<(0)) ? -(a):(a))
#define sign(a)  (((a)<(0)) ? -1 : (a)>0 ? 1 : 0)

/* Addition and subtraction */
#define fpadd(a,b) ((a)+(b))
#define fpsub(a,b) ((a)-(b))

/* Multiplication */
#define fpmul(a,b) ((fp_t) ((((fpdbl_t)(a)) * ((fpdbl_t)(b))) >> N))

/* Division (a/b) */
#define fpdiv(a,b) ((fp_t) ((((fpdbl_t)a)<<N) / b))

/* Multiplication and division (v*m)/d */
#define fpmuldiv(v,m,d) ((fp_t)((((fpdbl_t)(v)) * ((fpdbl_t)(m))) / d))

/* Integer to fixed point and vice versa */
#define int2fp(a) (((fp_t)a)<<N)
#define fp2int(a) ((x)>>N)

/* Floating point to fixed point and vice versa */
#define float2fp(a) ((fp_t)((a) * (1<<N)))
#define fp2float(a) (((float)(a)) / (1<<N))

/* Extract the fractional part */
#define fpfract(x) ((x) & NMASK)
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…