# Subtraction with doubles returning zero erroneously

I have a function that takes as parameter some doubles and does a subtraction operation on it. However I'm getting a result of 0 when one of the parameter is 0 for some reason.

``````int calcPID(double current, double desired, double k){
double diff;
diff = desired - current;
Serial.print("desired = ");
Serial.print(desired);
Serial.print(", current = ");
Serial.print(current);
Serial.print(", diff = ");
Serial.println(diff);
int r = (int)diff;
return r;
}
``````

Output

``````desired = 250.00, current = 1.69, diff = 248.31
desired = 250.00, current = 0.00, diff = 0.00
``````

When the current is 0.00 the result (diff) is also 0.00, when it should be 250. Can someone tell me what's going on?

I can't reproduce that.

``````int calcPID(double current, double desired, double k) {
double diff;
diff = desired - current;
Serial.print("desired = ");
Serial.print(desired);
Serial.print(", current = ");
Serial.print(current);
Serial.print(", diff = ");
Serial.println(diff);
int r = (int)diff;
return r;
}

void setup ()
{
Serial.begin (115200);
Serial.println ();
calcPID (1.69, 250, 42);
calcPID (0, 250, 42);
}  // end of setup

void loop ()
{
}  // end of loop
``````

That gives expected output of:

``````desired = 250.00, current = 1.69, diff = 248.31
desired = 250.00, current = 0.00, diff = 250.00
``````

I strongly suspect you are passing NaN (not a number) or Inf (infinity) instead of zero. If you add another test line like this:

`````` calcPID (1.0 / 0, 250, 42);
``````

Then you get the result:

``````desired = 250.00, current = inf, diff = inf
``````

Now I know you reported getting zero, but earlier versions of the IDE printed 0 for NaN or Inf. I suggested a change to the way the libraries handle that which has been implemented in more recent versions.

Here, for example.

If this doesn't answer your question, please post a Minimal, Complete, and Verifiable example - like I did above.

• I think NaN is probably it because when I compare current > 1 and current <= 1 both came out to false. – bakalolo Jan 28 '17 at 3:01
• dang it i was such a poopoohead before now i get it thnx – bakalolo Mar 17 '17 at 1:48

You are not providing the input values in the correct type:

``````calcPID(0.00, 250, 0.0);
``````

will return 0, while

``````calcPID(0.00, 250.0, 0.0);
``````

will return 250

UPDATE

Here you can get a working test case: it's running on a different processor, so don't expect to behave exactly as the 8bit MCU at Arduino's core.

• Is this based on a test, or a source-code reading, or what? What's the name of the library .cpp and .h files you looked at? How do you account for implicit type conversion not occurring? – James Waldby - jwpat7 Jan 26 '17 at 2:46
• @jwpat7 I didn't look at any library, I just looked at the above code and the only viable option I was able to find is if the OP is expecting type conversion to occur in C as if it was Java. When I posted my answer there was only the `calcPID` function reported, but now, looking at the updated example I'm more convinced about my answer, so much I updated it with a test. – Roberto Lo Giacco Jan 26 '17 at 16:57

@Roberto Lo Giacco The difference is, that on Arduino (IDE) are headers for *.ino done before standard C++ compilation

``````#include <stdio.h> // on *.ino it is done in IDE hidden way
int calcPID(double current, double desired, double k) ; // forward definition, for *.ino it is done in Arduino IDE hidden way
int main()
{
calcPID (1.69, 250, 42);
calcPID (0, 250, 42);
calcPID (0.0, 250.0, 42);
return 0;
}

int calcPID(double current, double desired, double k) {
double diff;
diff = desired - current;
printf("desired = %5.2f, current = %5.2f, diff = %5.2f, true = %i\n", desired, current, diff, diff > 0);
int r = (int)diff;
printf("desired = %5.2f, current = %5.2f, diff = %i, true = %i\n", desired, current, r, r > 0);
return r;
}
``````

This compiles and executes on your machine well a gives correct result same as @Nick Gammon have.

Without the definition `int calcPID(double current, double desired, double k) ;` standard C assumes definition with `ints` and makes different conversions, which leads to your "incorrect" result. So the result depends on forward definition, which Arduino does behind scene. But for *.cpp and *.h it may be different, so it would be interesting, how `bakalolo` organized his code.