Зачем использовать отрицательный int для работы mod в методе toString класса Integer в java src

когда я прочитал исходный код java версии 1.7.0_09, я обнаружил, что реализация метода toString класса Integer использует отрицательный int для вычисления операции mod, есть ли смысл в этом? код выглядит следующим образом:

public static String toString(int i, int radix) {

    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        radix = 10;

    /* Use the faster version */
    if (radix == 10) {
        return toString(i);
    }

    char buf[] = new char[33];
    boolean negative = (i < 0);
    int charPos = 32;

    if (!negative) {     
        i = -i;                //***** change i to negative
    }

    while (i <= -radix) {
        buf[charPos--] = digits[-(i % radix)];   //***** change back to positive after 
                                                 //***** mod operation
        i = i / radix;
    }
    buf[charPos] = digits[-i];

    if (negative) {
        buf[--charPos] = '-';
    }

    return new String(buf, charPos, (33 - charPos));
}

Ответ 1

В соответствии с алгоритмом вам нужен поток небольших (< radix) неотрицательных целых чисел, которые заполнят буфер символов цифрами справа налево. Стандартный способ начальной школы для этой работы состоит в том, чтобы поместить знак в начале номера, а затем напечатать абсолютное значение числа.

Но представьте, было ли правило, что i всегда положительно в этом цикле:

if (negative) {
    i = -i; // change i to positive
}

Если i оказывается Integer.MIN_VALUE, то -i также оказывается Integer.MIN_VALUE. Две дополнительные переменные могут хранить ровно еще одно отрицательное целое число, целые. Однако, если вместо этого инвариант i всегда является отрицательным абсолютным значением, он всегда будет соответствовать int.

Почему бы просто не использовать блок Math.abs() или if? Естественно, целые числа очень часто конвертируются в строки во многих компьютерных программах, поэтому полезно toString максимально быстро. Проблема в том, что операторы Math.abs() и if, скорее всего, будут скомпилированы для использования инструкций ветвления при компиляции в машинный код. Branches имеют тенденцию вмешиваться в конвейерная обработка инструкций; поэтому, обращая внимание на производительность, вы можете выбрать, если возможно, инструкции if из циклов.

ПРИМЕЧАНИЕ. Такая оптимизация редко бывает хорошей идеей! Увеличение производительности минимально, если ваш код не очень часто называется (например, этот код), или вы создаете библиотеку с большим количеством пользователей и немного читателей/модификаторов (например, этот код), и это делает код более сложным для чтения, понимания и изменение. Сделав эту оптимизацию, инженеры Java могут немного ускорить ваш код, но если вы введете такие методы в код, который вы пишете, ваш коллега/грейдер, возможно, не будет склонен задавать переполнение стека, почему ваш код так трудно понять.:)

TL; DR: Просто образованная догадка, но это комбинация двух дополнений и оптимизации кода.