Содержание
Верьте или нет, Java содержит переполнение буфера Integer также. Я не уверен, что это правильное слово, чтобы описать это или нет, может быть, вы можете предложить некоторые 🙂
Хорошо, пожалуйста, посмотрите на программу ниже, эта программа выводит количество микросекунд в день.
public class JavaLongOverflow {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
System.out.println("MICROS_PER_DAY : " + MICROS_PER_DAY);
}
}
Результат
MICROS_PER_DAY : 500654080
Ох .. ответ 500654080 . Подожди .. правильный ответ? Правильный ответ должен быть 86400000000 !!! Почему Java даст мне неточный результат? откуда этот номер? Что именно произошло?
Я верю, что это вызвано переполнением «int». Да, переменная «long MICROS_PER_DAY» имеет достаточно места для большого числа, например 86400000000, но она не помещается в «int»! Максимальное число «int» — 2147483647. Обратите внимание на приведенную выше программу, вся арифметика находится в «int», результат переводится в long и присваивается переменной «long MICROS_PER_DAY». В соответствии с [JLS 5.1.2] переход от int к long указывается как расширяющее примитивное преобразование, которое сохраняет (неверное) числовое значение.
Однако мы можем избежать вышеупомянутого переполнения тихого убийцы, явно указав «long» в первом целом числе, чтобы целая операция стала длинной арифметикой.
public class JavaLongOverflow {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
System.out.println("MICROS_PER_DAY : " + MICROS_PER_DAY);
}
}
Результат
MICROS_PER_DAY : 86400000000
Выше программа печатает 86400000000, как и ожидалось
Заключение
Эту ошибку так сложно обнаружить или осознать. Иногда это даже невозможно обнаружить. Если кто-то совершает такую ошибку в финансовой системе, я просто не могу представить себе последствие. Мой единственный совет — явно приводить примитивный тип, когда имеешь дело с вычислением двух различных типов примитивного типа. Всегда избегайте автоматического расширения примитивного преобразования в любом расчете.
0.00 (0%) 0 votes




