Complements or the ~ operator

J

Jonny Iversen

My VC++ documentation state that this is the one complements operator

~0 = 0xFFFF aka all bits set (swapping all 0's to 1)

This means that the bit is:

0 = 0000 0000 0000 0000 0000 0000 0000 0000 = 0x00000000
~0 = 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF

If I could operate on only 4 bits then:

One complements form gives:

0000 = +0
1111 = -0


Two complements forms gives:

0000 = 0
1111 = -1

Evaluating this in C++ gives -1, but i don't understand how can I calculate
the desimal value out of this manually and why?

Any advice?

Thanks in Advance!
 
K

Kurt Krueckeberg

~0 = 0xFFFF aka all bits set (swapping all 0's to 1)

This means that the bit is:

0 = 0000 0000 0000 0000 0000 0000 0000 0000 = 0x00000000
~0 = 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF

If I could operate on only 4 bits then:

One complements form gives:

0000 = +0
1111 = -0


Two complements forms gives:

0000 = 0
1111 = -1

Evaluating this in C++ gives -1, but i don't understand how can I
calculate
the desimal value out of this manually and why?

Any advice?

Thanks in Advance!

If you want to do this by hand, convert each group of ones into a
hexadecimal digit. Then convert the hexadecimal to decimal. For example,
1010 1110 1010 would be AEA in hexadecimal, which is
(10 times 16 cubed)+(14 time 16 squared) + 14.

Then convert each group of four into a hexadecimal number
 
V

Victor Bazarov

Kurt said:
[...]
If you want to do this by hand, convert each group of ones into a
hexadecimal digit. Then convert the hexadecimal to decimal. For example,
1010 1110 1010 would be AEA in hexadecimal, which is
(10 times 16 cubed)+(14 time 16 squared) + 14.

Actually, it's

(10 times 16 squared) + (14 times 16) + 10.


V
 
J

Jonny Iversen

Following 1111 (or hexadecimal 0xF) bits is actually -1 as an result from
VC++.

But ~ is one complement operator which should give the answer:

1110 which is the one complement for -1. So when is this further converted
to the
two complements form aka 1111 or 0xF?

I don't really understand that ~0 can give -1 as the answer when ~ is said
to be one complement operator the answer should have been 1111 that's -0 in
one complement.
 
V

Victor Bazarov

Jonny said:
Following 1111 (or hexadecimal 0xF) bits is actually -1 as an result from
VC++.

But ~ is one complement operator which should give the answer:

1110 which is the one complement for -1. So when is this further converted
to the
two complements form aka 1111 or 0xF?

What does ~(-1) give you on your hardware? Why do you say that 1110 is
the 1's complement for -1? AFAIK, 1110 is a one's complement for 1, using
the commonly accepted definition of what one's complement is. I think you
confuse the -1 representation on a one's complement machine with what is
truly a one's complement to -1. And that depends on the hardware because
"one's complement" is defined as "all bits inverted". So, on a one's
complement hardware, ~(-1) will give you 1. On a two's complement machine
~(-1) gives you 0. One a sign magnitude CPU ~(-1) will give you MAX_INT.
I don't really understand that ~0 can give -1 as the answer when ~ is said
to be one complement operator the answer should have been 1111 that's -0 in
one complement.

What is your definition of "one's complement"? What, according to that
definition do you expect the operator to do to int(0)? What bit pattern
is the result?

Now, since you know the result, try interpreting it as an int in your
current hardware configuration. What does the new bit pattern represent
in your hardware? Why are you trying to interpret it in one's complement
hardware?

V
 
R

Rade

Jonny Iversen said:
Following 1111 (or hexadecimal 0xF) bits is actually -1 as an result from
VC++.

But ~ is one complement operator which should give the answer:

1110 which is the one complement for -1. So when is this further converted
to the
two complements form aka 1111 or 0xF?

I don't really understand that ~0 can give -1 as the answer when ~ is said
to be one complement operator the answer should have been 1111 that's -0
in
one complement.

First of all, is it clear what the operator ~ actually does? Taken a
sequence of bits, it converts any 0 to 1 and any 1 to 0. Full stop.
Everything else is just an interpretation of the binary sequences.

When I say 'interpretation', I mean that the same sequence of bits can have
various meanings, depending on your application. For somebody, the value
1111...1111 (all 1's) is -1, for other it may be e.g. 255 (suppose there are
eight 1's), some can interpret it as -0 (as you noticed), for yet other
people it is a Unicode code for a letter y with two dots at top of it, in MS
DOS world it represents a character which looks as a space (but is not a
space) etc.

What does happen in your case? Well, you have a conflict between two
*interpretations* for integers - "one's complement" and "two's complement".
You have a value 0000...0000, which origins from the integer 0 - in any of
these two interpretations. Then you apply operator ~ and you get
1111....1111. The result now has different interpretations: in "one's
complement" it is -0, in "two's complement" it is -1.

What actually happens is that your compiler uses the two's complement
interpretation to convert integers to binary sequences and vice versa. You
just haven't noticed the first conversion (0 -> 0000...0000), but you have
noticed the second one (1111...1111 -> -1). This interpretation is inbuilt
into the compiler.

In other words: the operator ~ just flips bits. It knows nothing about any
interpretation. It even has nothing with the "one's complement"
interpretation. What confuses you is actually the VC++ documentation,
because it mentions something like "one's complement". There are disputable
didactical reasons why this is so... perhaps the operator ~ "looks like"
operator - (minus) in the world where all integers are represented by "one's
complement" interpretation. And really, if your compiler used one's
complement, then the operator ~ would work just the same as operator -, and
you would not have a reason for its existence (it would be a duplicate).

But, alas, your compiler doesn't use the "one's complement interpretation"
(actually, it is bound by C++ standard to use "two's complement").

Note 1: Personally, I would never mention "one's complement" in an
explanation of the operator ~. Usually a definition is a reduction of
unknown to a known, not the reduction of unknown to something even less
known!

Note 2: When I say "compiler", I mean, actually, "the resulting program
generated by your compiler".

I hope this will be of help to you.

Regards,
Rade
 
A

Arijit

Jonny said:
Following 1111 (or hexadecimal 0xF) bits is actually -1 as an result from
VC++.

But ~ is one complement operator which should give the answer:

1110 which is the one complement for -1. So when is this further converted
to the
two complements form aka 1111 or 0xF?

I don't really understand that ~0 can give -1 as the answer when ~ is said
to be one complement operator the answer should have been 1111 that's -0 in
one complement.

You get ~0 as -1 because computers usually use 2's complement to
represent negative numbers. (Well, PCs do and I assume you are using a PC. )

Whenever you store 1111 in an int, it is interpreted as -1. Seeing 1111,
the computer has no was of knowing whether it is 1's complement or 2's
complement. So it treats it as 2's complement.

To convert to 2's complement, take 1's complement and add 1. For
example,1 = 0001. ~1 = 1110. So 2's complement of 1 = -1 = 1110+1= 1111.

-Arijit
 
A

Arijit

Rade said:
<snip>

What actually happens is that your compiler uses the two's complement
interpretation to convert integers to binary sequences and vice versa. You
just haven't noticed the first conversion (0 -> 0000...0000), but you have
noticed the second one (1111...1111 -> -1). This interpretation is inbuilt
into the compiler.

Shouldn't it be the architecture instead of compiler ?
In other words: the operator ~ just flips bits. It knows nothing about any
interpretation. It even has nothing with the "one's complement"
interpretation. What confuses you is actually the VC++ documentation,

N's complement and (N-1)'s complement of a base N number has a definite
meaning. ~ *is* same as 1's complement. (By that I mean their results
are exactly the same, they may be conceptually different)
because it mentions something like "one's complement". There are disputable
didactical reasons why this is so... perhaps the operator ~ "looks like"
operator - (minus) in the world where all integers are represented by "one's
complement" interpretation. And really, if your compiler used one's
complement, then the operator ~ would work just the same as operator -, and
you would not have a reason for its existence (it would be a duplicate).

But, alas, your compiler doesn't use the "one's complement interpretation"
(actually, it is bound by C++ standard to use "two's complement").

Are you sure ? I am pretty certain it is architecture dependent. C++
standard doesn't dictate it.
Note 1: Personally, I would never mention "one's complement" in an
explanation of the operator ~. Usually a definition is a reduction of
unknown to a known, not the reduction of unknown to something even less
known!

Well, as I said before, 1's conplement has a clearly defined meaning.
For a p digit binary number, it means [(2 to the power p) - 1 - number.]
Note 2: When I say "compiler", I mean, actually, "the resulting program
generated by your compiler".

I hope this will be of help to you.

Regards,
Rade

-Arijit
 
R

Rade

Arijit said:
N's complement and (N-1)'s complement of a base N number has a definite
meaning. ~ *is* same as 1's complement. (By that I mean their results are
exactly the same, they may be conceptually different)

My point is that the *expression* "1's complement" is actually ambiguous
here. It denotes the operation of flipping the bits (more precisely, in base
N, changing any digit n with N-n-1). It is also colloquially used to denote
the process how we interpret binary sequences with leading 1 as negative
integers (or analogous process for any base). I just wanted to make clear
this distinction, because it seemed to me that the source of the confusion
here is mixing these two meanings.

What you are calling "conceptually different" is another way to clarify the
same distinction.
Are you sure ? I am pretty certain it is architecture dependent. C++
standard doesn't dictate it.

IIRC, 2's complement is mentioned in K&R for C (the language reference
part), but actually I don't know if it is a part of the C++ standard too
(and I may not recall correctly - I can't check that now. I apologize if I
am wrong). Can anybody help ?

Rade
 
R

Rade

Rade said:
IIRC, 2's complement is mentioned in K&R for C (the language reference
part), but actually I don't know if it is a part of the C++ standard too
(and I may not recall correctly - I can't check that now. I apologize if I
am wrong). Can anybody help ?

Definitely I am wrong about C++. I am sorry. Look at the previous discussion
in comp.lang.c++.moderated on about the same theme, started 7 Nov 2002 with
subject "int and unsigned int" and with some famous participants
(http://groups.google.com/groups?hl=...=aqenu8%248b6i5%241%40ID-14036.news.dfncis.de
- should serve as a link if you can't find it otherwise).
 
J

Jonny Iversen

Thanks for the answer, but I'm not sure when the conversion to 2'complement
form is done. I shall do some investigation by only shifting bits to left
before displaying it. It will maybe give me the answer (it will be 1100 =
1'complement or 1110 = 2'complement). Or as Rade said microsoft should never
have called this an one complements operator unless they should have mark it
clear that this depends on the underlying arcitecture (intel).

I'm trying to learn C++ and this is the very basic to achieve a full
understanding so ...

Thanks again!
 
V

Victor Bazarov

Jonny Iversen said:
Thanks for the answer, but I'm not sure when the conversion to
2'complement
form is done.

There is no "conversion to 2'complement", it's rather a conversion from the
two's complement to a string that you can see "-1".

Your PC uses two's complement to represent negative numbers. Positive
numbers are represented normally. That means that _any_ bit pattern has
_some_ representation in the number set. The number 0 (zero) has the
only representation that is pretty much well understood: all bits zero.
When you apply the operator~ to 0, you get a number which has _all_bits_
_set_. What number it is, depends on your underlying architecture, and
if it's two's complement, the number is -1. On a different architecture
"all bits set" pattern will represent a different number.
I shall do some investigation by only shifting bits to left
before displaying it. It will maybe give me the answer (it will be 1100 =
1'complement or 1110 = 2'complement). Or as Rade said microsoft should
never
have called this an one complements operator unless they should have mark
it
clear that this depends on the underlying arcitecture (intel).

It does NOT depend on the underlying architecture in what it does. And
Microsoft had NOTHING to do with naming that operator. The term is well
known and the operation performed by this operator is well defined. All
bits in the source which are 0 are changed to 1 and all bits that are 1
are changed to 0. That's the definition of "one's complement operator".
Take it or leave it.

The operator~ is NOT defined in terms of _values_ of the numbers. Only
in terms of their _representation_ in memory. So, once again, every bit
in the represetation of the source number is _flipped_. Whatever comes
out of it is what you get.
I'm trying to learn C++ and this is the very basic to achieve a full
understanding so ...

So, if you feel that you're failing to understand, don't fight it, just
learn it by heart.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,181
Messages
2,570,970
Members
47,537
Latest member
BellCorone

Latest Threads

Top