результат арифметической операции отличается от ожидаемого результата
Я пишу функцию
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, но тщетно. Что я делаю не так и как это исправить? Спасибо! Бхувнеш
@Bhuvnesh, 👍0
1 ответ
Еще раз пример к Почему я должен сначала изучить C/C++, прежде чем изучать Arduino
.
Главное здесь: знайте свои типы данных.
Ваше вычисление миллисекунд*частота/1000
будет работать, если это будет постоянная времени компиляции, которая оценивается препроцессором. В любом другом случае это значение времени выполнения, поэтому применяются ограничения типа данных.
Если не указано иное, я предполагаю, что ваши переменные миллисекунд
, частота
и counting
имеют тип int
. int
имеет ширину, зависящую от платформы. На Arduino это 16-бит. (Другие платформы имеют другую ширину)
Он также подписан, поэтому может содержать значения от -32768 до 32767.
Ваш расчет миллисекунд*частота
оценивается как 500 * 220 = 110000
, что во много раз больше, чем значение, которое может быть представлено.
Вы можете сделать две вещи:
Используйте
long
, который является 32-битным на Arduino. Но на самом деле я бы предпочел использовать тип с очевидной шириной. Поскольку вам не нужны отрицательные значения, я бы предпочелuint32_t
.Если миллисекунды – это константа, вы можете сделать ее более разумной, уменьшив вычисление до деления на два (или, что еще лучше, до одного сдвига вправо).
- Как вызвать функции C из скетча ардуино?
- max7219 связанный дисплей, показывающий зеркальный текст
- Ошибка Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
- Пиринговая коммуникация
- Запуск С для ардуино
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Прерывание ардуино при смене контакта
- GSM-модуль IOT-GA6 Arduino + ошибка CME 58
Спасибо за ваш ответ. Я был немного отвлечен, не мог видеть тот факт, который Вы упомянули. Изменение миллисекунд и частоты на тип long решило проблему., @Bhuvnesh
Вы забыли знак минус в диапазоне для
int
. В остальном отличный ответ. Проголосовать за, @chrisl