Bitwise op goes negative unexpectedly

Can someone please explain to me why I am getting these results?

public static int ipv4ToInt(String address) {
    int result = 0;

    // iterate over each octet
    for(String part : address.split(Pattern.quote("."))) {

        // shift the previously parsed bits over by 1 byte
        result = result << 8;

        System.out.printf("shift = %d\n", result);

        // set the low order bits to the current octet
        result |= Integer.parseInt(part);

        System.out.printf("result = %d\n", result);
    }
    return result;
}

      

For ipv4ToInt ("10.35.41.134") I get:

shift = 0
result = 10
shift = 2560
result = 2595
shift = 664320
result = 664361
shift = 170076416
result = 170076550
10.35.41.134 = 170076550

This is the same result I get when doing math myself.

For ipv4ToInt ("192.168.0.1") I get:

shift = 0
result = 192
shift = 49152
result = 49320
shift = 12625920
result = 12625920
shift = -1062731776
result = -1062731775
192.168.0.1 = -1062731775

For this, when I do the math by hand, I get 3232235521.

Interesting:
3232235521 = 11000000101010000000000000000001
And when I enter 1062731775 into my Windows calc and press the +/- button, I get:
-1062731775 = 11111111111111111111111111111111 110000001010100000000000000000000001

The function still works for my purposes, but I'm just really curious to know why the result on the ground becomes negative when I do this last bit shift?

+3


source to share


4 answers


Due to bit overflow in your case!

In Java, an integer is also 32 bits, and the range is -2147,483,648 to 2,147,483,647.

12625920 << 8

crosses the limit 2 ^ 31-1 and hence the result becomes negative ...



The result is simply reversed on the -ve-side and therefore any range left on the positive side is followed by one on the negative side !!!

As everyone suggested, you should use a variable long

to avoid overflow!

+5


source


All primitives in java are signed - they can be positive or negative. The most significant bit is used to control this, so when it is set, the number turns negative.



Try using long instead - it will give you the output you want as longs can be much larger without overflow.

+1


source


11000000101010000000000000000001

- 32 bits. The meaning it represents depends on how you interpret these bits:

  • as a 32 bit signed integer, it is negative (because the leftmost bit is 1)
  • as a 32 bit unsigned integer, it is positive (like any other unsigned integer)
  • as the least significant bits of a long (signed or unsigned), it will give a positive value (if the left bits remain 0)

Java uses signed integers, so if you print the value you will see a negative number. This does not mean that your beats are wrong.

+1


source


This is only important for printing, you can use these methods to print a positive integer:

1) change the result to long (java will do your job).

2) handle signed int as unsigned int yourself (maybe do int2string (int n) or toString (int n) method.

3) Integer.toUnsignedString (int) - you are using java 8.

As I understand your parsing the IP address, remember that java uses signed datatypes, you cannot have a 32 bit integer.

change the result for a long time to fix it.

0


source







All Articles