Я пытаюсь плавно перевести светодиод RGB от одного цвета к другому. В рамках логики этого у меня есть следующая функция, чтобы определить, насколько большим будет изменение (оно умножается на коэффициент f, чтобы избежать математических вычислений с плавающей запятой):

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

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

  return delta;
}

Когда я вызываю colorDelta(0, 255, 1000), я ожидаю, что результат будет -255000, но вместо этого функция возвращает 7144.

Я попытался выполнить операцию как можно более прямо для отладки, но Serial.print((0 - 255) * 1000, DEC); также записывает 7144 в последовательный порт.

Что я здесь по глупости упустил? Я бы очень хотел увидеть (плавно переходящий) свет. ;)

1
Calrion 14 Фев 2013 в 13:28
2
Похоже, вы упустили из виду, что sizeof(int) меньше, чем вы ожидали, например 2 (нет места для -255000 в 16 битах)
 – 
Anton Kovalenko
14 Фев 2013 в 13:37
Вы совершенно правы; изменение на f=100 или использование long вместо int работает должным образом. Напишите это как ответ, и я приму это.
 – 
Calrion
14 Фев 2013 в 13:44

1 ответ

Лучший ответ

Я подозреваю целочисленное переполнение: тип int не может содержать -255000. По языковым стандартам переполнение целочисленных значений со знаком является неопределенным поведением, но на практике основные части результата обычно просто выбрасываются (предупреждение: это наблюдение не предназначено для использования при написании кода < / em>, потому что неопределенное поведение остается неопределенным; это как раз для тех случаев, когда вам нужно рассуждать о программе, которая заведомо ошибочна).

Хороший способ быстро проверить это - вычислить разницу между вашим реальным результатом и ожидаемым: -255000 - 7144 = -262144. Последнее - -(1<<18), что свидетельствует о том, что мои подозрения вполне обоснованы.

3
Anton Kovalenko 14 Фев 2013 в 13:49
1
Это действительно была проблема. Я изменил свою функцию, чтобы вернуть long, и изменил предложение else на delta = ((long)to - from) * f;, и все работает, как ожидалось. Эта глупая ошибка подсказывает мне, что пора спать!
 – 
Calrion
14 Фев 2013 в 14:02