7

How does ~i work in C++?

I just noticed it is equivalent to i != -1, but I'm not certain about that.

int arr[3] {1, 2, 3};
int n = 3;
for (int i = n - 1; ~i; i--) {
    cout << arr[i] << ' ';
}

It printed the array in reverse.

GSerg
  • 76,472
  • 17
  • 159
  • 346

3 Answers3

14

~ is the bitwise NOT operator. ~i is 0 if and only if i has 1 in all its bits. Whether -1 has all bits 1 depends on how signed numbers are represented on the system. In two's complement representation, -1 is represented with all bits 1, so on such systems ~(-1) == 0. Neither in one's complement, nor in sign-and-magnitude does that hold true.

Therefore, the answer is no; not on all systems. That said, two's complement is fairly ubiquitous in modern machines (everything made since the 90's), and on such systems, the answer is yes. Regardless of the sign representation however, i != -1 is much more readable.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • N.B. https://stackoverflow.com/a/56589637/560648 Different operation I know but almost certainly the same applies. That is, guaranteed as-if-it-were-two's-complement from C++20, and pretty-much-implied-to-be-required-anyway before that – Lightness Races in Orbit Jun 26 '19 at 13:28
  • @LightnessRacesinOrbit What do you mean by "pretty-much-implied-to-be-required-anyway"? There's no requirement for operations to behave as-if-it-were-two's-complement other than operations on fixed width integers until C++20. – eerorika Jun 26 '19 at 13:34
  • Please click on the link provided – Lightness Races in Orbit Jun 26 '19 at 13:51
  • @LightnessRacesinOrbit Can you be more specific. I cannot find the part that explains it. Except for the quote from `[basic.fundamental]`, which has the wording from C++20 that doesn't apply to pre C++20. – eerorika Jun 26 '19 at 14:10
  • There are two large paragraphs explaining the C++11 behaviour. You can find them beginning with the text "In C++11, " – Lightness Races in Orbit Jun 26 '19 at 14:24
  • @LightnessRacesinOrbit And which part of it explains "pretty-much-implied-to-be-required-as-if-it-were-two's-complement"? – eerorika Jun 26 '19 at 14:26
  • The part that gives the definition of how signed integers were required to work? – Lightness Races in Orbit Jun 26 '19 at 15:09
  • @LightnessRacesinOrbit The one that applies equally well to most signed number representations that I know of, rather than only to 2's complement? – eerorika Jun 26 '19 at 15:12
5

~i is bitwise NOT operator. I.e. it inverts every bit in i. -1 is represented binary as every bit of number being set to 1, inverting every bit to 0 gets you 0. And when checking integer in place where bool is expected 0 is treated as false and any other number as true.

So, in this particular case yes, ~i is equivalent with i != -1.

sklott
  • 2,634
  • 6
  • 17
  • 3
    You should mention that the integer representation is implementation dependent... There are no guarantees `-1` is represented with all bits set to 1. – BiagioF Jun 26 '19 at 12:25
  • 1
    It's represented like that in a 2's complement system. C++ (still) supports other number representations (though those aren't common anymore). I suggest you expand on that point a bit. – StoryTeller - Unslander Monica Jun 26 '19 at 12:27
0

Because your i variable from for loop is of type int, which is defined as signed integer, and as such in twos complement, its binary representation of value -1 is all bits set, what means all bits are 1. On other side, bitwise negation of all ones is all zeros, and that is what you need, loop to execute until i>=0 or i!=-1, since you decrementing i. In that context of bitwise operations on sign values on system has twos complement binary representation of int, yes, it is the same.

Boki
  • 637
  • 3
  • 12