Arduino doesn't calculate correctly a simple arithmetic equation

Hello everyone,
I have the following equation to calculate :

uint16_t Rest = 1528
float L = 3570;
float Impuls = L*4096/200 - Rest;
int Impuls_rounded = round(Impuls);

The arduino is giving me the following result :

Impuls =
71585.60
Impuls_rounded =
6050

I'm wondering why am I getting such a result and how can I overcome this problem?
Thank you in advance.

The value is outside the int range and truncated. Try long instead.

1 Like
  1. In L*4096/200 - Rest;, order of operations will cause 4096/200 to be done first. With integers. Losing some precision.
  2. int has a maximum value of 32767 (it's 16bits on an AVR). int(71585.6) will not give the results you expect. Use long instead.

try this

uint16_t Rest = 1528
float L = 3570.0;
float Impuls = L*4096.0/200.0 - Rest;
int Impuls_rounded = round(Impuls);

Have a nice day and enjoy coding in C++.
Дайте миру шанс!

Thank you all for your help, I really appreciate it. Now it's working as expected.

uint16_t Rest = 1528;    //range: 0 to 65535
float L = 3570.0;    
float Impuls = L*4096/200 - Rest;      //71,585.6
int Impuls_rounded = round(Impuls);  //71,585 > 65535

See the above comments and follow post #2 @DrDiettrich to declare long int Impuls_rounded.

Not quite. The multiply and divide have the same order of precedence so they happen left to right. The subtraction has lower order so it is done last.

uint16_t Rest = 1528
float L = 3570;
float Impuls = L * 4096 / 200 - Rest;

After promoting values to a common type (change int to float when doing math with one int and one float) and order of precedence:

uint16_t Rest = 1528;
float L = 3570.0;
float Impuls = ((3570.0*4096.0) /200.0) - 1528.0;

Impuls = ((3570.0*4096.0) /200.0) - 1528.0;
Impuls = ((14622720.0) / 200.0) - 1528.0;
Impuls = (73113.6) - 1528.0;
Impuls = 71585.6;

If it worked the way you describe (4096/200 happening first) you would end up with a different answer:
Impuls = 3570.0 * (4096 / 200) - 1528;
Impuls = 3570.0 * 20 - 1528;
Impuls = 3570.0 * 20.0 - 1528;
Impuls = 71400.0 - 1528.0;
Impuls = 69872.0;

1 Like

Why not type promotion from float to int or long when rest = 1528 and L = 3570?

uint16_t Rest = 1528
float L = 3570;
float Impuls = L * 4096 / 200 - Rest;

I don't understand the question. Are you asking WHY the C++ standards promote the int to float and not the float to int?

Yes! This is my exact question.

Because it will always promote to the larger type. The whole point is to mitigate potential overflows and loss of precision.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.