2

I read and heard that the floating point math is much slower than int math.

And I saw a converting process in here floath math to integer math

So I want to to convert my floating math calculations to integer math.

Here is the code that include floating math:

float sensval, lpf, lps;
float sensinitial; // used to store the initial sensor data
float x, y, z;
int heigh;
int dA;


void setup() {

  runSensor();
  sensval = readSensorData();
  sensinitial = sensval; // Setting the initial data
  lpf = lps = sensval;
}


void loop() {
  sensval =  readSensorData();
  heigh = (float)44330 * (1 - pow(((float) sensval/sensinitial), 0.190295));
  lpf = lpf + (sensval - lpf) * 0.1;
  lps = lps+ (sensval - lps) * 0.05;
  x = (lps - lpf) * 50;
  y = x+ (z - y) * 0.1;
  z = constrain(y, -500, 500);
  dA += z * 100 + 2000;
}

readSensorData(); returns 7 decimals maximum(752.4543 for example)

There is pow calculation too.

So how can I convert floath math to int math?

Any optimization code are welcome.

  • 2
    The general idea is that you look at your calculations and decided how many binary places (binary equivalent of decimal places) you need in your calculations, or at different stages of the calculations, and do your calculations in an order and/or with a word length that will avoid overflows. You will be using integer data types thoughout your calculations, mentally keeping track of the binary point at each stage of the calculation. Search for Fixed Point Arithmetic to find a lot of information. – JRobert Apr 17 '16 at 21:59
  • overflow is not problem, ı just want to convert my floating point calculations to integer calculations to speed up arduino little bit. – sir mordred Apr 17 '16 at 22:44
  • Have you actually noticed that it is running too slow? Don't try and optimize without a benchmark handy. – BrettAM Apr 17 '16 at 23:11
4

What you are asking for is not simple, especially since you have this power function that can be hard to approximate.

First, you have to figure out the range and the required precision of each of the floating point numbers you are manipulating. You wrote that readSensorData() returns 7 decimals. If by that you mean that you require a relative accuracy of 10−7, then I predict it will be extremely hard to optimize this as a fixed point calculation. If you can live with a much lower relative accuracy (say, around 10−3 or 10−4), then it may be worth trying something.

I would start by writing the expression of height as

height = f(sensval/sensinitial-1)

where

f(x) = 44330 * (1 - pow(1+x, 0.190295))

I would expect sensval and sensinitial to be close to one another, which would imply that x is small. At this point you should try to estimate the likely range for x, because the feasibility of what follows strongly depends on it. Next step is to approximate f() by a polynomial. A simple Taylor expansion gives:

f(x) ≈ -x*(8435.78-x*(3415.25-x*2060.2))

You may start by trying this, just to see if it looks kind of OK or completely hopeless. You will notice that the above approximation is great when |x| is tiny, but it very quickly degrades as |x| increases. This is why you don't use Taylor expansions in real approximations, I showed it to you only to give you an idea of the feasibility of a polynomial approximation.

To do better than Taylor, you must specify the range of x, then you can scale that range to [−1, 1] and expand on the basis of the Chebyshev polynomials. And then you could fine-tune to get the optimal polynomial, but it's likely to be only marginally better than the Chebyshev expansion.

If all this works with a reasonable polynomial degree (say, no more than 5), then you can start converting to integer math. If it doesn't, you may try a different type of approximation, like interpolating over tabulated values. If the problem is the range of x being too large, you may instead write the power function as

ab = 2b × log2a

and write polynomial approximations to the base-2 exponential and logarithm (the polynomials only needs to cover one octave). If you try a rational fraction approximation, beware that divisions are slow on the AVR platform.

If all the above looks like too complex, or too much work, then just get a faster CPU, or try to live with your program being slow.

1

Since you are dealing with fractions, you can use fixed point arithmetic. For example, you can use unsigned short _Accum for readSensorData() if you only need 8 bits for the fraction part. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf tells you about fixed point types in c.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.