Почему unsigned long переполняется?

Я хочу преобразовать час в секунды, но длина unsigned long переполнена, вот код:

#include <Wire.h>
#include <DS3231.h>

RTClib myRTC;
unsigned long seconds;
char timestr[9];

void setup() {
  Serial.begin(250000);
  Wire.begin();
}

void loop() {
  DateTime now = myRTC.now();

  snprintf(timestr, 9, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
  seconds = (now.hour() * 3600);
  Serial.println(timestr);
  Serial.println(seconds);
  delay(100);
}

И вывод консоли выглядит так:

16:33:36
4294959360

Почему это происходит?

, 👍1


1 ответ


Лучший ответ:

5

Переполняется не длина unsigned long, а вычисление, которое вы ему назначаете.

3600-целое число со знаком (по умолчанию), а now.hour () - байт unsigned long. Байт unsigned long повышается, чтобы соответствовать "самому большому" типу в вычислении - целому числу со знаком, - а затем выполняется вычисление, в результате которого получается целое число со знаком.

Это целое число со знаком затем присваивается длинному без знака, и если результат отрицательный (как это вполне может быть - 10*3600 > 32767), вы получаете огромное число.>

Простое "лечение" состоит в том, чтобы убедиться, что одно значение в вычислении является unsigned long. И лучший способ сделать это-сделать вашу константу unsigned long: добавив к ней "UL":

seconds = (now.hour() * 3600UL);
,