943,832 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 389
  • C++ RSS
Jun 3rd, 2009
1

Weird cast error

Expand Post »
We came across a very strange behavior with a code like this (this is a simplified version; it took quite a time before we were able to identify a similar problem in our code):

unsigned int x = 10;
int a = ((int-1) * x;
int b = ((int)-1) * x / 2; // Result is not -5!!!!!
assert(a == -10); // OK
assert(a == -5);   // Assert fails!!!!!

Program was compiled with the Visual Studio 2008. Can anybody explain why 'b' is not -5? It seems like 'b' is treated as unsigned int instead of int.
Last edited by Tekmaven; Jun 3rd, 2009 at 4:02 pm. Reason: Code Tags
Similar Threads
Reputation Points: 17
Solved Threads: 0
Newbie Poster
Ray Gray is offline Offline
1 posts
since Jun 2009
Jun 3rd, 2009
0

Re: Weird cast error

1.
int a = ((int-1) * x; // this does not compile!!!!

2.
assert(a == -5); // Assert fails!!!!!

Does assert(b == -5); work??
Last edited by jencas; Jun 3rd, 2009 at 7:33 am.
Reputation Points: 395
Solved Threads: 71
Posting Whiz
jencas is offline Offline
362 posts
since Dec 2007
Jun 3rd, 2009
0

Re: Weird cast error

int a = ((int-1) * x;
I suppose you meant int a = ((int)-1) * x;
assert(a == -5); // Assert fails!!!!!
I suppose you meant assert(b == -5); // Assert fails!!!!!
Quote ...
From TCPL K&R 2nd ed, if either operand of an arithmetic operation is unsigned int, the other is also converted to unsigned int and the result is also an unsigned int. (I'm only assuming the case where both are same width, e.g. unsigned int against signed int).
consider int b = ((int)-1) * x / 2; which is actually
int b =( ((int)-1) * x )/ 2; if you care for the left associativity of the multiplication operator.
((int)-1) yields a integer -1 (note that this cast is useless). Since it is being multiplied by a unsigned int, -1 is promoted to a unsigned int. Any negative int when promoted to int will yield smallest non-negative value that is congruent to that integer, modulo one more than the largest value that can be represented in the unsigned type. So it is a very large number(4294967286 on my machine)which when multiplied by 10 yields larger number which is again demoted to fit into a unsigned int. Now you divide that number by two and you get the result.(which is still a larger number)(2147483643 on my machine.
The funny part is: all this doesn't happens in the line previous to this. That is perhaps because of your compiler's smartness, it doesn't promote -1 to int but demotes x to a int. This is done as, there is no more operation to perform.
Anyways., the correct procedure would be ((int)-1) * (x / 2); which would yield the desired result.
Note that int(-1) is same as -1.

If I were you I would have chosen a statement like this: int b = ( int(x)*(-1) ) /2;
The code tags are :
[code=cplusplus]
//code goes here
[/code]
Last edited by siddhant3s; Jun 3rd, 2009 at 7:46 am.
Reputation Points: 1486
Solved Threads: 140
Practically a Posting Shark
siddhant3s is offline Offline
816 posts
since Oct 2007
Jun 3rd, 2009
0

Re: Weird cast error

This is C++ not C, so I would have written:
c++ Syntax (Toggle Plain Text)
  1. b= -1*static_cast<int>(x)/2;

The main advantage of this is the you have an explicit bracket around the section you are casting and it is a BIG flag that you are changing type. Something that in numerical code is often such a big area of problems that the old (type) casts are often forbidden.

It also avoids nasty stuff when you convert (accidentally) from a pointer to a numeric type. Easily done when you have a long expression with pointers and multiplications.
Last edited by StuXYZ; Jun 3rd, 2009 at 1:21 pm.
Reputation Points: 732
Solved Threads: 134
Practically a Master Poster
StuXYZ is offline Offline
659 posts
since Nov 2008
Jun 3rd, 2009
0

Re: Weird cast error

Quote ...
The funny part is: all this doesn't happens in the line previous to this. That is perhaps because of your compiler's smartness, it doesn't promote -1 to int but demotes x to a int.
1. Probably you mean doesn't promote -1 to unsigned int...
2. All this happens in int a = (int)-1 * x . The funny part is: (int)-1 is the same as -1 because an integer literal already (and always) has int type. The compiler never takes into account left part type: it promotes -1 to unsigned int (max value) then multiply it to unsigned(10) (ignores integer overflow). After that the result is unsigned(4294967286) or int(-10) - the same bit pattern...
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: Game Mario (help!)
Next Thread in C++ Forum Timeline: Array/ for statment woes-Help





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC