We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I experienced a problem with uint32 calculations.
The following code calculates a wrong result. Has anyone found other problems with the unsigned long integer data type?
xdata unsigned int test1 = 66; xdata unsigned int test2 = 1000; xdata unsigned long int result; int main () { result=(unsigned long int)test1*(unsigned long int)test2; // result is 464 instead of 66000 // it seems that the compiler does the calculation // with 16 bit operations }
The same code works correct when using signed long int.
Your answer is 66*1000 - 65536, so they performed the evaluation using a 16-bit multiplication, loosing the overflow.
The type cast to 32-bit should have had a higher priority than the multiplication so it shouldn't matter if integer promotion was active or not. And even without integer promotion, the right-hand side was 32-bit unsigned even with broken precedence rules, in which case the C language requires that both sides gets promoted to 32-bit unsigned.
Might be time to contact Keil technical support.
Are you using the most current version of the compiler?
Are you sure?
I think the C rules are "int = int * int" then the result is promoted to long. So a cast is required. long = (long)int * int.
The problematic program _does_ contain casts to unsigned long, but the answer shows that the expression was evaluated with 16-bit and not 32-bit numbers.
I lost a lot of time having the same problem with Keil faulty libraries. No solution found yet.
Have you looked at any assembler output and verified that it is faulty libraries?
Maybe it is related to this bug.
What's New in C51 Version 8.16a http://www.keil.com/update/whatsnew.asp?p=C51&v=8.16a [Cx51 Compiler] Corrected a problem introduced in V8.15. When int numbers are multiplied and assigned to long, the result may be incorrect.
Tsuneo
You gave me hope for my next release.
I wasn't able to try using the latest version of c51. Till now I have optimised code and reduced max numbers to fit 16 bits.
cheers