Calrion
Calrion

Reputation: 3332

Unexpected integer math results on Arduino

I'm trying to smoothly transition an RGB LED from one colour to another. As part of the logic for this I have the following function to determine how big the change will be (it multiplies by a factor f to avoid floating-point math):

int colorDelta(int from, int to, int f) {
  int delta;

  if (to == from) {
    delta = 0;
  } else {
    delta = (to - from) * f;
  }

  return delta;
}

When I call colorDelta(0, 255, 1000) I expect the result to be -255000 but instead the function returns 7144.

I've tried performing the operation as directly as possible for debugging, but Serial.print((0 - 255) * 1000, DEC); also writes 7144 to the serial port.

What have I foolishly overlooked here? I'd really like to see the (smoothly transitioning) light. ;)

Upvotes: 1

Views: 1223

Answers (1)

Anton Kovalenko
Anton Kovalenko

Reputation: 21507

I would suspect an integer overflow: the int type being incapable of holding -255000. By language standard, signed integer overflow is undefined behavior, but in practice the major bits of a result are usually just thrown away (warning: this observation is not meant to be used in writing code, because undefined behavior remains undefined; it's just for those cases when you have to reason about the program that is known to be wrong).

A good way to check it quickly is computing a difference between your real result and your expected one: -255000 - 7144 = -262144. The latter is -(1<<18), which is the indication that my suspicions are well-founded.

Upvotes: 3

Related Questions