результат арифметической операции отличается от ожидаемого результата

Я пишу функцию

void Sound_Play(int frequency,int millisec)

Часть этой функции:

  counting=(millisec*frequency/1000);  //подсчет имеет тип int
  Serial.println((String)"millisec="+millisec+" frequency="+frequency+" (millisec*frequency/1000)="+(millisec*frequency/1000)+" counting set to="+counting);

Но когда я вызываю функцию с миллисекундами = 500 и частотой = 220, результат на последовательном мониторе:

millisec=500 frequency=220 (millisec*frequency/1000)=-21 counting set to=-21

Не следует считать, что вместо этого должно быть 110. Я пытался привести результат к типу int, но тщетно. Что я делаю не так и как это исправить? Спасибо! Бхувнеш

, 👍0


1 ответ


6

Еще раз пример к Почему я должен сначала изучить C/C++, прежде чем изучать Arduino.
Главное здесь: знайте свои типы данных.

Ваше вычисление миллисекунд*частота/1000 будет работать, если это будет постоянная времени компиляции, которая оценивается препроцессором. В любом другом случае это значение времени выполнения, поэтому применяются ограничения типа данных.

Если не указано иное, я предполагаю, что ваши переменные миллисекунд, частота и counting имеют тип int. int имеет ширину, зависящую от платформы. На Arduino это 16-бит. (Другие платформы имеют другую ширину)

Он также подписан, поэтому может содержать значения от -32768 до 32767. Ваш расчет миллисекунд*частота оценивается как 500 * 220 = 110000, что во много раз больше, чем значение, которое может быть представлено.

Вы можете сделать две вещи:

  • Используйте long, который является 32-битным на Arduino. Но на самом деле я бы предпочел использовать тип с очевидной шириной. Поскольку вам не нужны отрицательные значения, я бы предпочел uint32_t.

  • Если миллисекунды – это константа, вы можете сделать ее более разумной, уменьшив вычисление до деления на два (или, что еще лучше, до одного сдвига вправо).

,

Спасибо за ваш ответ. Я был немного отвлечен, не мог видеть тот факт, который Вы упомянули. Изменение миллисекунд и частоты на тип long решило проблему., @Bhuvnesh

Вы забыли знак минус в диапазоне для int. В остальном отличный ответ. Проголосовать за, @chrisl