With most binary operators the narrower argument is widened to the size of the larger, and the result is cast back to the result variable type. By default integer constants are the int size, so L is necessary for longer constants
(although if an expression is compile-time optimized the constrain may not matter, but it never a sound
thing to leave the L out for long constants)
Intermediate results are not cast, only the final result, because it is the one that has to be stored
in the result variable.
int is 16 bits on many Arduinos, which catches a lot of people out - here 86400L is used because 86400 is
not a 16 bit int.
I know of one other thing the compiler fixes for you:
uint8_t low = 0x57;
uint8_t high = 0x34;
uint16_t result = high << 8 | low;
The compiler fixes it to make it work.
When writing code, show what your are doing:
unsigned long b;
b = 70000UL * 1000UL;
Then both the person reading the code and the compiler understand that it is a 'unsigned long' thing.
It can easily go wrong with a #define FACTOR 100000. Depending on how the define is used with other constants or other variables, it can be okay or it can go wrong.