Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"offset or count might be near -1>>>1." What does it mean

Tags:

java

In java String source code, there are few places noted with the following comment:

// Note: offset or count might be near -1>>>1.

Consider the following example:

public String(char value[], int offset, int count) {
    if (offset < 0) {
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count < 0) {
        throw new StringIndexOutOfBoundsException(count);
    }
    // Note: offset or count might be near -1>>>1.
    if (offset > value.length - count) {
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.offset = 0;
    this.count = count;
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}

As we can see, offset, value.length and count are all int, thus the value might be either -1, 0, 1, or any other integers. What does the "near" and ">>>" in the comment means, am I missing something here?

like image 283
zynick Avatar asked Apr 17 '13 07:04

zynick


2 Answers

The value -1>>>1 == 2147483647 is the maximum int value you can have in Java.

In other words, -1>>>1 == Integer.MAX_VALUE. When you do maths with values close to such limits, you increase your chances of getting unexpected results. For instance, int a = (-1>>>1); System.out.println(a < a + 1); prints false because of an integer overflow, even though one could expect that code to always print true since, in pure maths, for any integer n it is true that n < n + 1.

The author of that piece of code is just explaining his (wise) decision to write

if (offset > value.length - count)

instead of the similar-looking-but-not-equivalent

if (offset + count > value.length)

This last version could cause an integer overflow, which could be a huge trouble for the code that follows. He is alerting to the fact that there's a possibility that at least one of offset or count could be a value close to Integer.MAX_VALUE, which increases the possibility of the overflow.

With the first version (the one used in the source code for String you mention), there can never be an overflow: you know for sure that both offset and count are positive or 0 because of previous checks, and value.length is also positive or 0 because the length of an array is always positive or 0 in Java, so no overflow problems can happen!

In addition to documenting the choice, the author warns other developers (including his future self) that there's a very specific reason for that line to be written the way it is, to avoid anyone who is tempted to replace it with the (possibly more natural looking) second, incorrect version from introducing a bug.

like image 130
Bruno Reis Avatar answered Sep 27 '22 20:09

Bruno Reis


You might want to look at Bitwise and Bit Shift Operators for explanation about the >>> operator:

The unsigned right shift operator ">>>" shifts a zero into the leftmost position

Say you have:

int a = -1;
a = a >>> 1;
System.out.println(a);

Then a will be 2147483647 (Which is Integer.MAX_VALUE)

Why?

Since the >>>operator fills zeros and only zeros no matter positive and negative number. So, for example, if you have:

12 >>> 2

(00000000 00000000 00000000 000011 00 >>> 2) then the result is 3.

(Which is 00000000 00000000 00000000 00000011).

So, if you'll do:

System.out.println(Integer.toBinaryString(-1>>>1));

This will print:

1111111111111111111111111111111

And of course, converting it to decimal, this is 2147483647.

As @BrunoReis (+1) explained in his answer, the reason for doing this is to prevent possible integer overflow problems.

like image 22
Maroun Avatar answered Sep 27 '22 18:09

Maroun