Daz_Genetic
Certified Guru
I'm not a very good coder, but I came across something today that I thought I should share.
I have been doing my maths with 32bit(16:16) fixed point numbers, but in certain cases my multiply and divide macros would return 0. I'm guessing that the numbers got shifted too far. If I changed my type to a 64bit int, everything would be fine. But this was very noticably slower.
My solution. I kept the 32bit fixed point numbers, but created a second 64bit type and a secondary macro for my multiplies and divides.
typedef long long int fxd64;
#define fxd_mul64(x,y) (((fxd64)(x)*(y))>>16)
#define fxd_div64(x,y) (((fxd64)(x)<<16)/(y))
In cases where 32bit operations don't work, I call fxd_mul64/fxd_div64 instead. All these do is cast the first number to a 64bit int, then carry out the operation on that. Of course that is slower, but I don't use it everywhere, only the places that really need it. Everything else is carried out on 32bit ints, so there is less data being passed around. And since I am mostly using incremental maths, most of my inner loops are filled with 32bit +'s and -'s. The slower mul's and div's are carried out in the function's initialisation.
By changing my fixed type back to 32bit, My program actually runs just about twice as quick. That is pretty major, so it is important to avoid 64bit operations as much as you avoid using floating point ones.
I am still trying to make the whole thing a little more elegant, so if anyone has any advice that would make the above redundant, please feel free to help.
I have been doing my maths with 32bit(16:16) fixed point numbers, but in certain cases my multiply and divide macros would return 0. I'm guessing that the numbers got shifted too far. If I changed my type to a 64bit int, everything would be fine. But this was very noticably slower.
My solution. I kept the 32bit fixed point numbers, but created a second 64bit type and a secondary macro for my multiplies and divides.
typedef long long int fxd64;
#define fxd_mul64(x,y) (((fxd64)(x)*(y))>>16)
#define fxd_div64(x,y) (((fxd64)(x)<<16)/(y))
In cases where 32bit operations don't work, I call fxd_mul64/fxd_div64 instead. All these do is cast the first number to a 64bit int, then carry out the operation on that. Of course that is slower, but I don't use it everywhere, only the places that really need it. Everything else is carried out on 32bit ints, so there is less data being passed around. And since I am mostly using incremental maths, most of my inner loops are filled with 32bit +'s and -'s. The slower mul's and div's are carried out in the function's initialisation.
By changing my fixed type back to 32bit, My program actually runs just about twice as quick. That is pretty major, so it is important to avoid 64bit operations as much as you avoid using floating point ones.
I am still trying to make the whole thing a little more elegant, so if anyone has any advice that would make the above redundant, please feel free to help.