PDA

View Full Version : bitwise NOT operator


Flashmatazz
11-04-2005, 05:18 AM
I was reading this: http://www.macromedia.com/devnet/flash/articles/bitwise_operators_03.html

and it says:
With a bitwise NOT operator, I would get 6 back. This is because the bitwise NOT flips each bit in the binary representation of 9 separately, so 1001 (9 in binary) becomes 0110, which is 6 in decimal.

However:


trace (~9);

traces: -10

Am I misunderstanding something here? How does this bitwise operator operate exactly??

Flashmatazz
11-05-2005, 12:50 PM
no one?

senocular
11-05-2005, 01:31 PM
Its because you're actually dealing with a full 32-bit unsigned integer with NOT. What that means is you're not simply inverting 1001 but inverting
00000000000000000000000000001001
which becomes
11111111111111111111111111110110
essentially this is the number + 1 and negated. so 9 becomes -(9+1) which is -10 or
11111111111111111111111111110110
in binary (unsigned)

Barn
11-05-2005, 02:32 PM
Its because you're actually dealing with a full 32-bit unsigned integer with NOT. What that means is you're not simply inverting 1001 but inverting
00000000000000000000000000001001
which becomes
11111111111111111111111111110110
essentially this is the number + 1 and negated. so 9 becomes -(9+1) which is -10 or
11111111111111111111111111110110
in binary (unsigned)
That makes sense. But wait! That means that (big surprise) the documentation is in error. :)

senocular
11-05-2005, 02:34 PM
That makes sense. But wait! That means that (big surprise) the documentation is in error. :)

Error? In Macromedia documentation? I DONT BELIEVE IT!
:P

Barn
11-05-2005, 02:37 PM
<Hangs head in despair.>

senocular
11-05-2005, 02:45 PM
They have gotten better ;)

Barn
11-05-2005, 03:17 PM
<perks up slightly; casts wary eye at Help menu>

Flashmatazz
11-06-2005, 05:59 AM
Its because you're actually dealing with a full 32-bit unsigned integer with NOT. What that means is you're not simply inverting 1001 but inverting
00000000000000000000000000001001
which becomes
11111111111111111111111111110110
essentially this is the number + 1 and negated. so 9 becomes -(9+1) which is -10 or
11111111111111111111111111110110
in binary (unsigned)

:puzzled: Thanks, but I'm not quite sure I understand that, sorry...
Maybe I need to do some Googling on bitwise operator tuts.

And @Macromedia: how on earth am I supposed to learn from erroneous documentation?? :bounce:

senocular
11-06-2005, 12:09 PM
Do you understand the leading 0's part? Thats where the confusion begins.

The problem is that you may want to use a binary number for a set of flags, true or false values that will exist in a 'string' of 0's and 1's in binary. For example, you could represent a group of people and flag them as being relatives like so:

Bob - false
Joe - true
Abraham - true
Jen - false

which can be written out in a list as

false, true, true, false

or numerically as

0110

Now lets say you want to invert this list, which here is essentially a binary number, so that you get

1001

or people that are not relatives. Theres one problem. In terms of numbers, there are no preceeding 0's. So what you originally had, 0110, numerically, is actually 110. If you tried to invert it then, you'd end up with

001

or simply 1 instead of the desired 1001. How the NOT operator gets around this is assuming the largets 32 bit integer possible for binary numbers which is

00000000000000000000000000000110

Note the 32 digits in that number. That way, when NOT is used, you are assured to have whatever values you require correctly inverted because it does them all.

11111111111111111111111111111001

Make any more sense?

Flashmatazz
11-07-2005, 04:52 AM
Ok, that makes a bit more sense indeed.

I still do not really get this part however:


What that means is you're not simply inverting 1001 but inverting
00000000000000000000000000001001
which becomes
11111111111111111111111111110110
essentially this is the number + 1 and negated.


I can see why you would have to negate the number, but why is it 'the number + 1' ?? I find this very confusing and do not see the logic behind that :(

senocular
11-07-2005, 09:45 AM
its just a correlation between the flip and binary and the resulting value. The whole negate plus 1 part you could just have well never known. But in comparing the original number with its result after NOT, thats what you get. It just so happens that

11111111111111111111111111110110 = -(00000000000000000000000000001001 + 1)

And that will be true for any value you use ~ with. So, in simple mathematical terms without thinking binary at all, you can see ~n as being the same as -(n++).

Flashmatazz
11-09-2005, 04:53 PM
Pretty confusing stuff. Anyway, thanks a lot for your explanations, I appreciate it. :)

Now I guess it will just have to sink in...

benswift
11-09-2005, 05:07 PM
after reading through this - I grasp the concept, but i can't seem to imagine a use for this? am I missing the bigger picture?

senocular
11-09-2005, 05:42 PM
It has to do signed and unsigned too. Either way you look at it, the possible values of a 32 bit integer is the same. When introducing a sign you would think that there would then be twice as many values (since youd have the original positive plus the negative). But what you really get is a shift of all the possitive values originally part of the unsigned number to have half in the negative and half in the positive. So for example, using a smaller number, 256 (an 8-bit integer) represented with unsigned values of 0 - 255, when signed, becomes -128 to 127. You're still dealing with 256 values, just now half are negative.

When dealing with numbers like

11111111111111111111111111110110

in the NOT operation perceptually (flipping values), you're dealing with a positive unsigned value (32-bit integers, 4294967296 values; unsigned: 0 to 4294967295). However, taking a look at what ~ does numerically, with -(n++), you're getting a negative number as a result. This shifts things around and means you're dealing with an signed number.

So where

11111111111111111111111111110110

is really

4294967286

in the world of unsigned, in the world of signed (32-bit integers, -2147483648 to +2147483647) it cannot be because values simply don't reach that high. So what happens is that you instead get this wrap around where 4294967286 exceeds the signed 2147483647 limit and goes into the negative. For that its simply a matter of subtracting the available number of values for 32-bit integers, 4294967296, from the number thats too large for the positive range for signed values throwing it back in the negative.

4294967286 - 4294967296

which gives -10. The "value" is technically the same, you're just going between signed and unsigned values.

senocular
11-09-2005, 06:00 PM
after reading through this - I grasp the concept, but i can't seem to imagine a use for this? am I missing the bigger picture?

the binary flagging I mentioned before with the relatives is really probably the best example. Consider 6 boolean variables you have - just true or false values which represent different things - doesnt matter what they are. Usually booleans are "flags" but it can be anything really, whether categorized as a "flag" or not. Terminology is not important. The deal is you have 6 variables which can be either true or false.

Now lets say you want to send these values from a server to your Flash application (or something, anything) but need to optimize these values as much as possible. Something not optimized would include:

"value1=true,value2=false,value3=false,value4=true, value5=true,value6=false"

You can improve this by droping the variable references and just using their values since you would be able to separate them by order.

"true,false,false,true,true,false"

Going further, you can just use 1s and 0s for true and false

"100110"

Now, if you'll notice, the result is a binary number - a string of 1's and 0's that represent true and false values. In its binary form, using bitwise operators you are able to easy manipulate these values with simple operations, one being NOT which would flip the values to their opposites

"011001"

All with one simple ~. Imagine doing that manually with 6 separate values. It would be much more work.

Of course it all depends on what you're doing and often you wont need to use them. But, I can think of one practical example where bitwise operators have their place, and that is when dealing with hex color values. Because colors are represented as a hex value in the form 0xRRGGBB, bitwise operations can help you easily separate the Rs, Bs and Gs to get their respective values, all without more complicated string parsing mechanisms.

Now, stepping back to the whole optimizing concept, because binary numbers are numbers, "100110" can be shortened further into its decimal representation of 38 - thats only two characters. And if you want to go even further, you can use its ascii value which is a single "&" character. So what was 74 letters to represent 6 values now becomes 1. :beam:

benswift
11-09-2005, 06:49 PM
whoa. thanks!

Flashmatazz
11-11-2005, 05:43 AM
I'm beginning to see the light :)

Thanks a lot!

TheCanadian
11-11-2005, 06:05 AM
Well Senocular, that was a great explanation :thumb:.