Author Topic: Arduino variable overflow doesn't make sense  (Read 700 times)

0 Members and 1 Guest are viewing this topic.

Offline kuzm1nsk1Topic starter

  • Contributor
  • Posts: 23
  • Country: hr
Arduino variable overflow doesn't make sense
« on: March 29, 2024, 09:38:16 pm »
This is just a demonstration code for what is happening. If I set:
Code: [Select]
uint32_t hour, minute, second; to:
Code: [Select]
uint8_t hour, minute, second or:
Code: [Select]
int16_t hour, minute, second; or basically any data type that has range up to 32767, counter overflows after 32767 and jumps to 4294934528 which doesn't make any sense to me. Why should variables: hour, minute or second be larger than 1 byte if they only store numbers up to 60? Tested on original Arduino Uno and Nano Every.


Code: [Select]
#include <Wire.h>
#include <DS3231.h>
uint32_t counter = 0;
uint32_t hour, minute, second;
DS3231 clock;
RTCDateTime dt;

void setup() {

  Serial.begin(9600);

  clock.begin();
  clock.setDateTime(2024, 3, 29, 9, 6, 0);
}

void loop() {

  dt = clock.getDateTime();
  hour = dt.hour;
  minute = dt.minute;
  second = dt.second;

  Serial.print("Hour: ");
  Serial.print(hour);
  Serial.print("\tMinute: ");
  Serial.print(minute);
  Serial.print("\tSecond: ");
  Serial.print(second);

  counter = hour * 3600 + minute * 60 + second;

  Serial.print("\tCounter: ");
  Serial.println(counter);

  delay(1000);
}

Serial monitor:
Hour: 9   Minute: 6   Second: 0   Counter: 32760
Hour: 9   Minute: 6   Second: 1   Counter: 32761
Hour: 9   Minute: 6   Second: 2   Counter: 32762
Hour: 9   Minute: 6   Second: 3   Counter: 32763
Hour: 9   Minute: 6   Second: 4   Counter: 32764
Hour: 9   Minute: 6   Second: 5   Counter: 32765
Hour: 9   Minute: 6   Second: 6   Counter: 32766
Hour: 9   Minute: 6   Second: 7   Counter: 32767
Hour: 9   Minute: 6   Second: 8   Counter: 4294934528
Hour: 9   Minute: 6   Second: 9   Counter: 4294934529
Hour: 9   Minute: 6   Second: 10   Counter: 4294934530
Hour: 9   Minute: 6   Second: 11   Counter: 4294934531
Hour: 9   Minute: 6   Second: 12   Counter: 4294934532
Hour: 9   Minute: 6   Second: 13   Counter: 4294934533
Hour: 9   Minute: 6   Second: 14   Counter: 4294934534
Hour: 9   Minute: 6   Second: 15   Counter: 4294934535
« Last Edit: March 29, 2024, 09:45:22 pm by kuzm1nsk1 »
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14490
  • Country: fr
Re: Arduino variable overflow doesn't make sense
« Reply #1 on: March 29, 2024, 09:46:25 pm »
It's due to the integer promotion rule.
 
The following users thanked this post: kuzm1nsk1

Offline kuzm1nsk1Topic starter

  • Contributor
  • Posts: 23
  • Country: hr
Re: Arduino variable overflow doesn't make sense
« Reply #2 on: March 29, 2024, 09:50:44 pm »
Is there a way to solve this because I'm using other library with functions that have parameters with size of one byte?
 

Online ejeffrey

  • Super Contributor
  • ***
  • Posts: 3727
  • Country: us
Re: Arduino variable overflow doesn't make sense
« Reply #3 on: March 29, 2024, 11:58:17 pm »
Code: [Select]
  counter = hour * 3600UL + minute * 60 + second;

or

Code: [Select]

counter = (uint32_t) hour * 3600 + minute * 60 + second;

Essentially: hour * 3600 can overflow, so one of the arguments (either one) needs to be cast to a 32 bit word before multiplication.  Once you do that, the additions get promoted to 32-bits as well, so they won't overflow.  The minute and second multiplications themselves should not overflow, so they don't need to be promoted.

The former code depends on "long" being 32 bit, which is true on arduino.
« Last Edit: March 30, 2024, 12:02:46 am by ejeffrey »
 
The following users thanked this post: kuzm1nsk1

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
Re: Arduino variable overflow doesn't make sense
« Reply #4 on: March 31, 2024, 03:50:46 pm »
Integer promotion has helped you a bit by converting the smaller types to integers before performing operations, but if integers are 16-bit long, it is not enough. Hence, you need to explicitly cast to 32-bit.

 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: Arduino variable overflow doesn't make sense
« Reply #5 on: March 31, 2024, 04:12:41 pm »
Code: [Select]
counter = hour * 3600 + minute * 60 + second;
Think twice, hour is int16, so 9*3600 + 6*60 + 15 = 32775, but the largest value it can hold is 32767.
It overflows during the calculation, before the result is transfered to counter.
You can specify the compiler to convert hour into int32 when making calculations like ejeffrey said.
This way you can keep hour, minute and second as int8.

Before using a random integer size, check the largest value it can hold.
In your case it's 23h 59min 59s = 86.399. You definitely need int32 for calculation.
« Last Edit: March 31, 2024, 04:18:51 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf