Sign in to follow this  
xeddiex

odd binary bahavior

Recommended Posts

xeddiex    238
Just when you thought you knew it all - it decides to get all jewish on you...I'm trying to get the max range for a unsigned short but I'm having a bit of trouble. I know there's more than one way to do this ( SHRT_MAX, etc.. ) but I'm doing it this paticular way for learning purposes. My system is 32 bit and Im programming in C.
int main(int argc, char **argv)
{
	signed short signed_short = ~0; // int literals bits flipped to 1 then truncated & assigned to short.
	// visual bit pattern representation: 1111 1111  1111 1111

	// verify short is two bytes
	printf("sizeof(short) %d", sizeof(short)); // prints 2 - good

	signed_short &= 0x7fff; // mask out MSB
	// visual bit pattern representation: 0111 1111  1111 1111
	// print signed short max range:
	printf("signed short max range %d\n", signed_short); // should be: 32767 - prints: 32767 - good

	signed_short = ~0; // set all 16 bits to 1 again
	// visual bit pattern representation: 1111 1111  1111 1111

	// Now correct me if I'm wrong, in the following problem I will argue how I think mixing signed & unsigned
	// doesn't matter. Print max range for unsigned short with signed_short variable - ! mixing types !
	// continue reading...
	printf("unsigned short max range %u", signed_short); // should be: 65535 - what is printed: 4294967295
	// what is printed is the max range for an unsigned int. Now, I understand "%u" interprets signed_short
	// as an unsigned int (temporary conversion) the bit pattern for signed_short looks like
	// this: 1111 1111  1111 1111 after the "%u" conversion, it should look like 
	// this: 0000 0000  0000 0000  1111 1111  1111 1111 That's how I think it all works out and this last
	// printf call should have printed 65535 even though it's been interpreted as an int. Why? because the
	// left-most added WORD (as shown above) are all 0's and the right-most WORD are all 1's .. but it's as
	// if (or is) all the bits in the unsigned int interpretation are set to 1's:
	// 1111 1111  1111 1111  1111 1111  1111 1111 == 4294967295

	// declaring the variable as unsigned short solves the problem but I don't understand why declaring it signed
	// short should make a difference *here* since I'm not doing anything special on it like math where mixing
	// un/signed would probably make a difference. I'm only manually setting the bits and interpreting the variable
	// as an unsigned int in the last printf and it should behave as I described.

	getchar();
	return 0;
}



xeddiex

Share this post


Link to post
Share on other sites
SiCrane    11839
Integral values passed to variadic functions undergo integer promotion. Even though you wanted to pass a signed short, printf() received an int. When passing an unsigned short it undergoes promotion to a unsigned int which preserves the value you want.

Share this post


Link to post
Share on other sites
xeddiex    238
Promotion is the word I should have used, I had it in the back of my mind but anyways. SiCrane, That's exactly what I'm trying to say; "When passing an unsigned short it undergoes promotion to a unsigned int which preserves the value you want." So therefore, the bit pattern for a short like 1111 1111 1111 1111 should look like this
after integral promotion 0000 0000 0000 0000 1111 1111 1111 1111. This however, hasn't answered my question [grin]

Share this post


Link to post
Share on other sites
xeddiex    238
Quote:
Original post by Conner McCloud
I believe the header file you are looking for is limits.h, and the pertinent macros are (U)SHORT_MAX and (U)SHORT_MIN.

*edit: Nevermind, you know about this [sad]

CM


Yeah, I knew that Conner [grin] Thanks anyways.


xeddiex

Share this post


Link to post
Share on other sites
SiCrane    11839
Because integral promotion for a signed short to a signed int preserves value. Preserving value for a signed short to a signed int involves sign extension. Similarly integral promotion for a unsigned short to an unsigned int preserves value, which involves zeroing out the upper half.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by xeddiex
Promotion is the word I should have used, I had it in the back of my mind but anyways. SiCrane, That's exactly what I'm trying to say; "When passing an unsigned short it undergoes promotion to a unsigned int which preserves the value you want." So therefore, the bit pattern for a short like 1111 1111 1111 1111 should look like this
after intregal promotion 0000 0000 0000 0000 1111 1111 1111 1111. This however, hasn't answered my question [grin]

The sign of a signed value gets preserved under integral promotion...so all those zeros become ones.

CM

Share this post


Link to post
Share on other sites
iMalc    2466
Think about what happens when you do:
short a = -3; //a = 0xFFFD
int b = a; //b = 0xFFFFFFFD
The compiler knows that if the number is negative, to make the upper 16-bits ones so that the number is the same.

And be careful what you say, as you could potentially appear racist here.

Share this post


Link to post
Share on other sites
xeddiex    238
Quote:
Original post by SiCrane
Because integral promotion for a signed short to a signed int preserves value. Preserving value for a signed short to a signed int involves sign extension. Similarly integral promotion for a unsigned short to an unsigned int preserves value, which involves zeroing out the upper half.


Ok, SiCrane. I hope I got this right.


You said promotion from said types preserves value and signdness:

signed short: 1111 1111 1111 1111

After promotion to signed int: 1000 0000 0000 0000 1111 1111 1111 1111

After reading, Conner's latest post; it's as I suspected; All the bits get set but I'm not quite understanding why *all* the bits in the "promoted to signed int" are being set to 1 if the value being preserved only takes up the first half of the WORD and it should look like in the above example. Hmm, so I guess it preserves more than the value and signedess? everything after the first half, regardless if the bits are set or not are set to 1?

Share this post


Link to post
Share on other sites
SiCrane    11839
When (short)-1 gets promoted to int, the value of the int afterwards is the same, -1. The bit pattern for a 32 bit signed int that has the value -1 is 1111 1111 1111 1111 1111 1111 1111 1111. Sign extension takes the most significant bit of the short and fills the entire upper half of the bit pattern with that value. (short)-1 is 1111 1111 1111 1111, so it takes the 1 and fills the entire upper half of the int with 1. (short)7 is 0000 0000 0000 0111, so it takes the most significant bit, 0, and fills the entire upper half of the int to get (int)7, 0000 0000 0000 0000 0000 0000 0000 0111.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by xeddiex
Ok, SiCrane. I hope I got this right.


You said promotion from said types preserves value and signdness:

signed short: 1111 1111 1111 1111

After promotion to signed int: 1000 0000 0000 0000 1111 1111 1111 1111

After reading, Conner's latest post; it's as I suspected; All the bits get set but I'm not quite understanding why *all* the bits in the "promoted to signed int" are being set to 1 if the value being preserved only takes up the first half of the WORD and it should look like in the above example. Hmm, so I guess it preserves more than the value and signedess? everything after the first half, regardless if the bits are set or not are set to 1?

Look up twos-complement arithmetic. Wikipedia had an excellent article on the subject.

CM

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this