Not getting the correct answer

When I put the following in a calculator I get 258.93.

.0000152 * (180^3) - .0105225 * (180 ^ 2) + 2.8190984 * 180 + 3.7777778 = 258.93

But when I run the following

int bad_ang = 180; float ang;

void setup() { Serial.begin(115200); }

void loop() { ang = .0000152 * (bad_ang ^ 3) - .0105225 * (bad_ang ^ 2) + 2.8190984 * bad_ang + 3.7777778; Serial.println(ang); delay(500); }

it gives me 509.30. Could someone tell me what I need to do to get he correct answer of 259, does not have to be exact. Thank you for your time.

The ^ symbol is presumably the exponentiation operator on your calculator. In C/C++ there is no exponentiation operator. The ^ symbol in C/C++ means the exclusive OR logical operator. Try this:

ang = .0000152 * (bad_ang * bad_ang * bad_ang) - .0105225 * (bad_ang * bad_ang) + 2.8190984 * bad_ang + 3.7777778;

Pete

Thank you!

Your calculator is much smarter than ANY Arduino ever be. Look up int range and long range.

Also calculator 180^3 = Arduino 180 * 180 * 180

As Vaclav has indirectly pointed out, there's a problem with multiplying integers on the Arduino. Change this:

int bad_ang = 180;

to this:

float bad_ang = 180.;

so that the square and cube of bad_ang will work properly.

Pete

do not forget Horners Rule for polynomes

ang = .0000152 * (bad_ang ^ 3) - .0105225 * (bad_ang ^ 2) + 2.8190984 * bad_ang + 3.7777778;

==>

ang = ((0.0000152 * bad_ang - 0.0105225) * bad_ang + 2.8190984) * bad_ang + 3.7777778;

now it is no problem that bad_ang is an int.

Be aware that float has only ~7 significant digits

robtillaart: do not forget Horners Rule for polynomes

ang = .0000152 * (bad_ang ^ 3) - .0105225 * (bad_ang ^ 2) + 2.8190984 * bad_ang + 3.7777778;

==>

ang = ((0.0000152 * bad_ang - 0.0105225) * bad_ang + 2.8190984) * bad_ang + 3.7777778;

now it is no problem that bad_ang is an int.

Be aware that float has only ~7 significant digits

Unless I'm missing something, you have completely changed the calculations by altering the grouping of terms in a way that will give a completely different result....

Regards, Ray L.

Vaclav: Your calculator is much smarter than ANY Arduino ever be.

And yet you don't see too many Casios controlling and stabilising multicopters.

RayLivingston: Unless I'm missing something, you have completely changed the calculations by altering the grouping of terms in a way that will give a completely different result....

Regards, Ray L.

Think you are missing something ... Check - https://en.wikipedia.org/wiki/Horner's_method -

or/and run this test

 long bad_ang = 180;
float ang;

void setup()
{
  Serial.begin(115200);
  ang = .0000152 * pow(bad_ang, 3) - .0105225 * pow(bad_ang, 2) + 2.8190984 * bad_ang + 3.7777778;
  Serial.println(ang);

  ang = ((0.0000152 * bad_ang - 0.0105225) * bad_ang  + 2.8190984) * bad_ang + 3.7777778;
  Serial.println(ang);
}

void loop(){}

Calculating bad*bad*bad and then bad*bad and then bad requires 3 multiplications, before you even start with the other literal multiplication.

float bad= 1234.0 ;
float bad2=bad*bad ;
float bad3=bad2*bad ;

//  calculate expression

requires only 2 multiplications.

Using the pow( ) function here, is ridiculous.

Somewhat OT here but just a datapoint for calculator vs arduino. About 8 months ago I wrote an algebraic parser for the Teensy3/3.1 (both of which have a lot more sram than a Nano/UNO) and one of the things I implemented with it was an integral evaluator which uses Simpson's rule. My calculator is a Sharp EL-W516X which also uses Simpson's rule to evaluate integrals. I timed how long it took to calculate the integral of sin(x*x) from zero to pi using 100 intervals. It takes 23 seconds. The same thing on a 96MHz Teensy3 takes 10.6ms and on a 96MHz Teensy3.1 takes 7ms (I think the T3.1 has a bigger cache than the T3 which improves the execution time).

Pete

Vaclav: Your calculator is much smarter than ANY Arduino ever be. Look up int range and long range.

Also calculator 180^3 = Arduino 180 * 180 * 180

I like to add By itself the reference to int and long is OK.

In the context of the application I would suggest to use float variables since your constants are floats. Just to be consistent if for nothing else.

However, there is seldom mentioned / used feature of C called "automatic conversion " which SHOULD take care of variable "mismatch" as just experienced. But the rules for automatic conversion are pretty specific, and if not followed will make things worse rather than better