John Matthews wrote: > --- In c-prog@yahoogroups.com, "Pedro Izecksohn" <[EMAIL PROTECTED]> wrote: >> OK, I wrote a bad piece of code. Let me try to codify my problem again: >> >> #include <limits.h> >> #include <stdio.h> >> >> int main (void) { >> unsigned short int a; >> unsigned long long int b, c; >> a = USHRT_MAX; >> b = (a*a); >> c = ((unsigned int)a*(unsigned int)a); >> printf ("Why %llx != %llx ?\n", b, c); >> return 0; >> } >> >> When I execute it I get: >> Why fffffffffffe0001 != fffe0001 ? >> >> b is wrong. > > I see what you are saying - ignoring what C says should happen, and > assuming USHRT_MAX = 0xffff, you have: > > b = a * a > = 0xffff * 0xffff > = 0xfffe0001 > > So why do you get 0xfffffffffffe0001? > > Good question - my guess is that at some point the result is a > negative (ie. signed) value, and this gets sign-extended. > > For example, if you have -1 as a signed short, and want to convert it > to a signed int, the result should still be -1. But if you like at > these values in hex, you have 0xffff (short) becoming 0xffffffff > (int), which looks similar to what has happened to b in your program. > > But hopefully some can quote the relevant bit of the Standard. > > John
Wow. I totally missed that. All this time I was thinking the OP was complaining about something involving 'c' instead of 'b'. Without typecasting, _operators_ tend to behave "oddly" when differing data types are involved. At least they don't behave like you would think they should. There are a set of rules regarding these things in the Standard, but I've just found it MUCH easier to use typecasting to the types I want and then force a final typecast at the end of the procedure instead of trying to memorize the rules. b = (unsigned long long int)(((unsigned int)a) * ((unsigned int)a)); Ugly, but effective. Although, I would personally do something more along the lines of: b = (UInt64)(((UInt32)a) * ((UInt32)a)); (I'm pretty sure the rule is something like operators automatically convert from unsigned to signed unless there is a typecast involved on one of the operands, but don't quote me on that as I haven't ever tried to figure this out. My solution is to ALWAYS go overkill on typecasting in this situation to make 100% certain that the compiler will do EXACTLY what I want it to do. My approach has never failed me but it does use a lot of parenthesis.) -- Thomas Hruska CubicleSoft President Ph: 517-803-4197 *NEW* MyTaskFocus 1.1 Get on task. Stay on task. http://www.CubicleSoft.com/MyTaskFocus/