Playing with some 12bit ADCs and I'd like to experiment with some linearisation functions involving squares/cubes.
I want to scan these ADCs as fast as possible, so trying to avoid floats.
X^2 is fine because max value for 12bit signed is 2048, which means it's square can only reach 4,194,304 and that fit's into an int32_t. No problem there.
But a X^3 could be 8,589,934,592 which could blow out an int32.
The linearisation functions usually finish off with a division, and if I move that to the other side, this can help ...e.g
int16_t x; // 12bit input
int16_t n = x / 16;
int32_t y = n * n * n;
..but this results in a substantial loss of precision.
Also I was sticking with multiplication as I've read it can be 10 times faster than Math.pow().
How is this situation normally handled efficiently?
if you do that the right side of the assignment n * n * n is calculated using int16_t (so with overflow) and only then converted in a 32 bit value. so it won't work unless you cast the values for the multiplication (at least the first one) to int32_t
if you divide first before taking the cube you need to divide by the cubic root . was the divisor 4096 and that's why you used 16?
say x = 16n + r when you divide by 16 you only get n and looses the r ➜ as the early division is also conducted in integral numbers you loose part of the decimals raised to the cube.
now it's just a matter of developing this into separate factors
(a + b)3 = a3 + 3a2b + 3ab2 + b3
so you get
n3 + 3n2r/16 + 3nr2/256 + r3/4096
the part 3n2r/16 + 3nr2/256 + r3/4096 is your approximation error (and you could calculate that fast enough, dividing by 16, 256 or 4096 are simple bit shifts)