Help. Переполнение значения переменной типа unsigned long!!!!!!
- Войдите на сайт для отправки комментариев
Всем кто читает это, здравствуйте. Прошу помощи у более опытных программеров. Имею нижеприведенный скетч для сравнения текущего времени с заданным Скетч работает в составе програмного кода управления баней. byte CompTime(int HR, int MIN) //Передаваемые параметры HR, MIN Возвращаемое значение ResultTime { byte ResultTime; unsigned long InstTime = (HR * 60 * 60 + MIN * 60); //Переводим пороговое время в количество секунд от начала суток clock.getTime(); byte SEC = clock.second; MIN = clock.minute; HR = clock.hour; unsigned long NowTime = (HR * 60 * 60 + MIN * 60 + SEC); //Переводим текущее время в количество секунд от начала суток if (NowTime > InstTime) ResultTime = true; else //Если текущее время больше порогового, возвращаем логическую единицу if (NowTime < InstTime) ResultTime = false; else //Если текущее время меньше порогового, возвращаем логический ноль if (NowTime == InstTime) //Если текущее время равно пороговому, возвращаем значение "2" { ResultTime = 2; delay(750); //Ждем 750 мСек для того чтобы цикл не успел повториться в течение этой секунды } return ResultTime; }
Проблема в том что в строке 8 значение InstTime никогда не превышает 65535, т.е приблизительно в 18:12 переменная приобретает значение 0, хотя предельное значение переменной типа unsigned long равно 4 294 967 295
В строке 13 переменная NowTime имеет значение 4 294 967 295 уже приблизительно в 11:56, далее знчение становится равным 0 и отсчет начинается снова, хотя в сутках всего 86400 секунд
Путем подбора различных способов реализации алгоритма скетч трансформировался в следующий:
byte CompTime(byte HrIns, byte MinIns) //Передаваемые параметры HR, MIN Возвращаемое значение ResultTime { byte ResultTime; clock.getTime(); byte HR = clock.hour; byte MIN = clock.minute; byte SEC = clock.second; unsigned int m = HR*60; unsigned long NowTime = m * 60 + MIN*60 + SEC; //Переводим текущее время в количество секунд от начала суток unsigned long InstTime = MinIns*60 + 60*HrIns*60; //Переводим пороговое время в количество секунд от начала суток if (NowTime > InstTime) ResultTime = true; else //Если текущее время больше порогового, возвращаем логическую единицу if (NowTime == InstTime) //Если текущее время равно пороговому, возвращаем значение "2" { ResultTime = 2; delay(750); //Ждем 750 мСек для того чтобы этот цикл не успел повториться в течение этой секунды пока время 21:00 } else if (NowTime < InstTime) ResultTime = false; //Если текущее время меньше порогового, возвращаем логический ноль return ResultTime; }
Проблема с переполнением NowTime изчезла, однако InstTime победить не удалось ни таким ни другими способами.
Посоветуйте пжл что делаю неправильно. Возможно есть другой алгоритм реализации функции сравнения текущего времени с заданным
Плата Arduino Mega, пробовал компилировать в средах 1.0.6, 1.6.6, 1.8.2 с одинаковым результатом
Заранее благодарен откликнувшимся
Значение HR и Min не превышает 59. Поэтому эти переменные и объявлены как Int в строке 5
Или не про это?
Проблема с переполнением NowTime изчезла, однако InstTime победить не удалось ни таким ни другими способами.
надо так:
Иначе у вас вычисления идут в размерности byte, а не unsigned long
Спасибо громадное. Завтра попробую. Чую что вы правы.
Вставляйте сериалы, мониторьте значения переменных и результатов вычислений с ними. Где то косяк и вынырнет. Ну никак в этих формулах лонга не переполнить.
bwn, не разу не сталкивались с такой ситуацией? :) Можно конечно как советовал b707, но как тогда решить пример где все множители уже заданные переменные. Например так:
Поэтому лучше всегда объявлять тип данных для обоих половин выражений:
Поэтому лучше всегда объявлять тип данных для обоих половин выражений:
"обеих половин выражений" не совсем точно. В Вашем примере тип объявлен только для a. А вот если действительно сделать "дл половины выражения" (unsigned long) (a*b*c), то опять же будет хрень.
учим наизусть приведение типов, лучше бы это было сделать ДО того, как начинать программировать.
Самый грамотный вариант решения - у b707.
bwn, не разу не сталкивались с такой ситуацией? :) Можно конечно как советовал b707, но как тогда решить пример где все множители уже заданные переменные. Например так:
Бог миловал.))) Пока писал свой ответ, прилетели все предыдущие, прочитал их позже. Править не стал, решил, что мониторинг сериалом все равно не повредит.
А так, да, если ни разу не наступил на грабли, это еще не значит, что их нет.(((( Каюсь.
Спасибо b707 за помощь. Все получилось. Верно говорят Век живи, век учись.
Пожалуйста помогите!
Пожалуйста помогите!
Пожалуйста помогите!
Тип данных передаваемый в качестве второго аргумента функции SerPrnt стоит проверить.
Мало того что 16-битный , так ещё и знаковый.
ОГРОМНОЕ спасибо!
Слона-то я и не заметил!
Исправил на void SerPrnt(String S, unsigned long prmt) и все стало на место.
Пожалуйста помогите!
Как говорится, если человек ХАМ, то это навсегда.
Как говорится, если человек ХАМ, то это навсегда.
Хам или "Нехам" - это другое дело, но Квон тот же самый ответ написал тебе на полтора часа раньше. А "спасибо" не получил. ;))
Как говорится, если человек ХАМ, то это навсегда.
А если у кого-то с самоиронией проблемы, то это насколько?
Надеюсь, что модератор удалит этот флуд не по теме.
Твой - да.