Вопрос

I am tring to implement C/C++ atoi function in Java, below is the code snippet

    for (int j = 0; j < s.length(); j++) {

        int digit = Character.digit(s.charAt(j), 10);
        if (sum < limit/10) {
            if (neg) return Integer.MIN_VALUE;
            return Integer.MAX_VALUE;
        }

        sum *= 10;
        if (sum < limit + digit) {
            if (neg) return Integer.MIN_VALUE;
            return Integer.MAX_VALUE;
        }
        sum -= digit;
    }

For line "if (sum < limit + digit) {", which is correct, however, if I use "sum - digit < limit", it will get wrong result, e.g. input "-2147483649", wrong result 2147483647, should be -2147483648.

I figured this out, cuz sum - digit might be overflow, so this come to another question:

    int sum = Integer.MAX_VALUE;
    System.out.println(sum < Integer.MAX_VALUE + 1);

Why this prints false? What is the behind logic?

Это было полезно?

Решение

Integer.MAX_VALUE + 1 is equal to Integer.MIN_VALUE, which will be more obvious if you look at them in hexadecimal:

Integer.MAX_VALUE = 0x7fffffff
                1 = 0x00000001
                    ---------- +
                    0x80000000

And 0x80000000 is also known as Integer.MIN_VALUE.

Obviously there's no int lower than Integer.MIN_VALUE.

Also, attempting to test whether a number has overflowed by seeing if it's bigger than the biggest possible value is fundamentally misguided. It can't be bigger than the biggest possible value, that's what "biggest possible" implies. Also, you can't take a number, look at it, and determine whether it has overflowed or not, because every number can be the result of a non-overflowing computation (and indeed of just writing it down as a constant) and as the result of a computation that overflowed. You need to know how you got that number.

Другие советы

If you add Integer.MAX_VALUE and 1, then that sum will overflow, so sum won't be less than the resultant "sum", Integer.MIN_VALUE, so it's false.

To get that to work properly, you can cast Integer.MAX_VALUE as a long so overflow won't occur, and the comparison will work properly.

System.out.println(sum < (long) Integer.MAX_VALUE + 1);

Output:

true

FYI: Integer.parseInt(String) does what you are writing.


Why this prints false? What is the behind logic?

System.out.println(sum < Integer.MAX_VALUE + 1);

This prints false, because Integer.MAX_VALUE + 1 == Integer.MIN_VALUE. So this is equivalent with

System.out.println(sum < Integer.MIN_VALUE);

There is nothing smaller than the minimum value.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top