Keil C51 is a compiler compatible with ansi c. The ansi c Specification specifies that the default data types of decimal Integer constants are int, long int, and unsigned long Int, which of the given constants depends on the actual size of the constant. If the constant is between-32768 and ~ Between 32767 and are processed by the int type. If the processing by the int type overflows, consider the long Int or larger data type unsigned long Int. In short, the compiler always specifies the constant type based on the principle as much as possible.
However, this principle does not always work. When two constants are computed, overflow may occur. For example:
# Define sysclk 22118400 // sysclk in Hz (22.1184 MHz external crystal oscillator)
# Define slider_rest_time 100 // In MS, Slider rest time
# Define rest_delay sysclk * slider_rest_time/(65536*1000)
Unsigned char I;
I = rest_delay;
Run I as 0xe1, that is, 225, in Keil C51, instead of the expected result 22118400*100/(65536*1000) = 33.75, And the integer is 33. Cause analysis:
After the macro is replaced with: I = 22118400*100/(65536*1000);, the compiler first defines the type for 22118400, because 22118400 is not within the int expression range, the range of long Int Is-2147483648 ~ 2147483647, so 22118400 is processed by the long int type. When the product operation is performed, 100 is automatically processed by the long int type, and 22118400*100 is calculated by two signed Long Integer constants, the operation result is still a signed long integer. The hexadecimal value is 0x83d60000 and the decimal value is-2083127296. Obviously, an overflow error occurs. The Keil compiler does not provide any error or warning information (VC ++ 6.0 also provides warning
C4307: '*': Integral Constant overflow), continue to the next operation 65536*1000, the result is a signed long integer, The hexadecimal value is 0x3e80000, the decimal value is 65536000, the last two long integer division is used to calculate-2083127296/65536000 and the result is 0xffffffe1. Because I is of the character type, the lowest valid byte 0xffe1 is assigned to I, and the final value of I is 0xe1.
To solve this overflow error, a C language term is "promotion". In the above example, 22118400 is specified as an unsigned long integer, that is:
# Define sysclk 22118400ul
Note: although you only need to specify one of the four constants 22118400, 100, 65536, and 1000 as an unsigned long integer, you can get the correct results, but considering the readability and standardization, select a large integer to specify its type.
Summary: overflow error may occur during the calculation of Integer constants of the default type in the C51 compiler. You should specify the Data Type of a large integer to avoid possible operation errors.
Transferred from: Ghost Cat
Http://www.cnblogs.com/civet/archive/2011/05/31/2064959.html