need to cast operands when doing long math

Hi folks,

I’m doing some long (32 bit) math.

unsigned long int tt = 365 * 24 * 60 * 60 ;
Serial.println(tt) ;

yields 13184, should be 31536000.

With static cast it calculates correctly.
tt = (unsigned long int) 365 * (unsigned long int) 24 * (unsigned long int) 60 * (unsigned long int) 60 ;
Serial.println(tt) ;

seems that the interim math is 16 bit not 32 bit.

I would have thought that gcc would have given me a warning about this. (Are we not running with -Wall? )

This particular problem was easy to find/fix but this sort of problem can make one question the foundations and general slow development down.

Can I pass -Wall (or some other recommended switches) to gcc so that nasties are flagged? or other suggestions?

Thx,
Bruce

– code –

#include <Time.h>  
#include <stdio.h>

void setup() {
  Serial.begin(9600); 
  unsigned long int  tt =  365 * 24 * 60 * 60 ;
  time_t time  = 365 * 24 * 60 * 60 ;
  Serial.println("Init");
  Serial.println(time) ;
  Serial.println(tt) ;
  tt=60 ;
  Serial.println(tt) ;
  tt*=60 ;
  Serial.println(tt) ;
  tt*=24 ;
  Serial.println(tt) ;
  tt*=365 ;
  Serial.println(tt) ;
  tt =  (unsigned long int) 365 * (unsigned long int) 24 * (unsigned long int) 60 * (unsigned long int) 60 ;
  Serial.println(tt) ;
}

void loop() {
  delay(1000) ;
}

– serial port –
Init
13184
13184
60
3600
86400
31536000
31536000

Instead of unsigned long int tt = 365 * 24 * 60 * 60 ;

try:

unsigned long int tt = 365UL * 24UL * 60UL * 60UL ;

Lefty

seems that the interim math is 16 bit not 32 bit

That's because the native "int" for the Arduino is 16 bits.

Thanks for the replies!

in 32 bit gcc 4.3.4 I do not get a warning message with the equivalent:

unsigned int tts2 = (unsigned short) 365 * (unsigned short)24 * (unsigned short) 60 * (unsigned short)60 ;

sooo... I guess it's one of those things to remember.

BTW, this does print a nice warning by default ( with 32bit gcc, no -Wall needed) :

unsigned short int tts = 365UL * 24UL * 60UL * 60UL ; testcase.cpp:6: warning: large integer implicitly truncated to unsigned type

bcaldwellma: BTW, this does print a nice warning by default ( with 32bit gcc, no -Wall needed) : unsigned short int tts = 365UL * 24UL * 60UL * 60UL ; testcase.cpp:6: warning: large integer implicitly truncated to unsigned type

That's because a short is always 16 bits, just as a long is always 32 bits (at least on most computers I've encountered).

However, the int is special - it's considered the most convenient size for the processor to use, and that's why it varies so much - some computers use it for 16 bit wide value, some 32.