bitwise NOT

Started by
18 comments, last by alvaro 14 years, 4 months ago
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.
Advertisement
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)
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."

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 alvaro
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...
I'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).
Quote:Original post by visitor
I may be mistaken, but IMO bitwise operations are only meaningful for unsigned types.
It 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.
Quote:Original post by Evil Steve
Quote:Original post by alvaro
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...
I'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).


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?
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

This topic is closed to new replies.

Advertisement