bitwise NOT
hi,
well, i'm not really sure if this goes here but...
why does
~(260) = -261
in "~" , 0's are changed to 1's and 1's are changed to 0's
260 in 32 bits is:
0000 0000 0000 0000 0000 0001 0000 0100
~260 would be.... well, a lot of 1's.
I read that i should use "two's complement", but all the examples i read are for 8 bits. But in this case, i dont really understand how to solve this.
Can somebody explain it to how ~260 = -261 ??
thanks a lot.
I may be mistaken, but IMO bitwise operations are only meaningful for unsigned types. (Where all bits are equal and one is not more significant than the others.)
In signed types, the first bit indicates sign. So if that is not set initially, flipping it makes the number negative.
Then it also follows from the two's complement, that when you flip all bits in a positive signed integer, you get basically -(n + 1)
In signed types, the first bit indicates sign. So if that is not set initially, flipping it makes the number negative.
Then it also follows from the two's complement, that when you flip all bits in a positive signed integer, you get basically -(n + 1)
260 in 32 bits is as you said:
0000 0000 0000 0000 0000 0001 0000 0100
However, you need to understand how the 2s-complement works. In that notation, the most significant (leftmost) bit is the sign value for signed types. Also, it is designed in a way to aid addition.
I assume you believe the following value to equal 0:
1000 0000 0000 0000 0000 0000 0000 0000
It does not. What that value equals is:
0111 1111 1111 1111 1111 1111 1111 1111 + 1
That is the scenario where you have the largest possible value and it "rolls over" to the negative value.
1000 0000 0000 0000 0000 0000 0000 0000 actually equals the largest negative value: -2,147,483,648.
So, -1 would actually be:
1111 1111 1111 1111 1111 1111 1111 1111
And when you add one, you get all zeroes. I think this explains why -260 is "a lot of 1s."
I suppose it depends on what you are trying to do. I don't think it is any more or less meaningful.
0000 0000 0000 0000 0000 0001 0000 0100
However, you need to understand how the 2s-complement works. In that notation, the most significant (leftmost) bit is the sign value for signed types. Also, it is designed in a way to aid addition.
I assume you believe the following value to equal 0:
1000 0000 0000 0000 0000 0000 0000 0000
It does not. What that value equals is:
0111 1111 1111 1111 1111 1111 1111 1111 + 1
That is the scenario where you have the largest possible value and it "rolls over" to the negative value.
1000 0000 0000 0000 0000 0000 0000 0000 actually equals the largest negative value: -2,147,483,648.
So, -1 would actually be:
1111 1111 1111 1111 1111 1111 1111 1111
And when you add one, you get all zeroes. I think this explains why -260 is "a lot of 1s."
Quote:I may be mistaken, but IMO bitwise operations are only meaningful for unsigned types. (Where all bits are equal and one is not more significant than the others.)
I suppose it depends on what you are trying to do. I don't think it is any more or less meaningful.
Quote:Original post by BlackWind
~260 would be.... well, a lot of 1's.
Indeed it is!
Quote:but all the examples i read are for 8 bits
The examples of two's complement may be for eight bits, but there's nothing special about the extension to 32 bits. Here's -10 as an eight-bit signed integer.
11110110
Now, here's the same number, but as a 16-bit signed integer.
1111111111110110
Here's the same number as a 100-bit signed integer.
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110110
Get the point?
Quote:Original post by visitor
I may be mistaken, but IMO bitwise operations are only meaningful for unsigned types. (Where all bits are equal and one is not more significant than the others.)
The C or C++ standards probably don't specify the results of bitwise operations on signed types, but in assembly there is no difference between signed and unsigned, so the compiler will just do the naive thing.
Also, some bits are more significant than others in unsigned types. I don't know why you would think otherwise...
Quote:Original post by alvaroI'd be surprised if that were the case - there's plenty of reasons you'd want to do bitwise arithmetic on signed numbers (Packing a signed 32-bit fixed point value into 16 bits for instance).
The C or C++ standards probably don't specify the results of bitwise operations on signed types, but in assembly there is no difference between signed and unsigned, so the compiler will just do the naive thing.
Also, some bits are more significant than others in unsigned types. I don't know why you would think otherwise...
Quote:Original post by visitorIt depends on what you mean by "meaningful". The numeric result of a bitwise operation on two unsigned integers is deterministic and platform-independent, whereas the numeric result of a bitwise operation on two signed integers is deterministic but platform-dependent (because the C-standard allows for several signed integer representations). There's no simple, elegant relationship between bitwise boolean operations and conventional arithmetic operators, but several long-standing ASM techniques (which I shall refer to as "stupid bit tricks") rely on bitwise operations to accomplish mathematically meaningful results. These often depend on a particular representation of numbers.
I may be mistaken, but IMO bitwise operations are only meaningful for unsigned types.
Quote:Original post by Evil SteveQuote:Original post by alvaroI'd be surprised if that were the case - there's plenty of reasons you'd want to do bitwise arithmetic on signed numbers (Packing a signed 32-bit fixed point value into 16 bits for instance).
The C or C++ standards probably don't specify the results of bitwise operations on signed types, but in assembly there is no difference between signed and unsigned, so the compiler will just do the naive thing.
Also, some bits are more significant than others in unsigned types. I don't know why you would think otherwise...
You'd be surprised if what were the case?
i might be missing something, but i'm not sure if i get it.
260 in 32 bits is:
0000 0000 0000 0000 0000 0001 0000 0100
so ~260 is:
1111 1111 1111 1111 1111 1110 1111 1011
so then, i use twos complement, right?
if so, i get:
0000 0000 0000 0000 0000 0001 0000 0101
which would be 261. But becasue when i did ~260, the leftmost bit was 1, which represents a negative value, the result would be -261.
is the process ok?
260 in 32 bits is:
0000 0000 0000 0000 0000 0001 0000 0100
so ~260 is:
1111 1111 1111 1111 1111 1110 1111 1011
so then, i use twos complement, right?
if so, i get:
0000 0000 0000 0000 0000 0001 0000 0101
which would be 261. But becasue when i did ~260, the leftmost bit was 1, which represents a negative value, the result would be -261.
is the process ok?
Dont forget
~2 != -2
~2 = 0x11111101 0xFD
-2 = 0x11111110 0xFE
so -(~2) != 2
and
~0 != -0
~0 = 0x11111111
-0 = 0x00000000
Can somebody explain it to how ~260 = -261 ??
bitwise ~x = -(x+1)
260 = 0000 0001 0000 0100
~260 = 1111 1110 1111 1011
261 = 0000 0001 0000 0101
-261 = 1111 1110 1111 1011
~2 != -2
~2 = 0x11111101 0xFD
-2 = 0x11111110 0xFE
so -(~2) != 2
and
~0 != -0
~0 = 0x11111111
-0 = 0x00000000
Can somebody explain it to how ~260 = -261 ??
bitwise ~x = -(x+1)
260 = 0000 0001 0000 0100
~260 = 1111 1110 1111 1011
261 = 0000 0001 0000 0101
-261 = 1111 1110 1111 1011
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement