разбор длинных на отрицательные числа - PullRequest
3 голосов
/ 18 октября 2010

код:

public class Main{
    public static void main(String[] a){
        long t=24*1000*3600;
        System.out.println(t*25);
        System.out.println(24*1000*3600*25);
    }
}

Это печатает:

2160000000

-2134967296

Почему?


Спасибо за все ответы.

Является ли единственный способ использовать L после числа?

Я пробовал (long)24*1000*3600*25, но это тоже отрицательно.

Ответы [ 7 ]

18 голосов
/ 18 октября 2010

Вы достигли максимума типа int, который равен Integer.MAX_VALUE или 2 ^ 31-1.Из-за этого он обернут, показывая вам отрицательное число.

Для мгновенного объяснения этого см. Этот комикс:

alt text

11 голосов
/ 18 октября 2010

Чтобы объяснить это ясно,

System.out.println(24*1000*3600*25);

В приведенном выше утверждении на самом деле int литералы.Чтобы относиться к ним как к буквальному значению long, необходимо добавить суффикс к L.

System.out.println(24L*1000L*3600L*25L);

Caveat, также будет достаточно небольшого l, но это выглядит как прописные I или 1, иногда.Капитал I здесь не имеет особого смысла, но чтение этого слова как 1 действительно может привести к трудностям.Более того, даже если для одного значения с L получится long.

6 голосов
/ 18 октября 2010

В первом случае вы печатаете long, а во втором вы печатаете его как int.

И int имеет диапазон от -2 ^ 31 до 2 ^31 - 1, что немного ниже того, что вы рассчитываете (int max: 2147483647 you: 2160000000), поэтому вы переполняете int до отрицательного диапазона.

Вы можете также заставить второй использовать long:

System.out.println(24L*1000*3600*25);
3 голосов
/ 18 октября 2010

Вы должны добавить суффикс числа к 'l'.Проверьте фрагмент ниже:

   public static void main(String[] a){
        long t=24*1000*3600;
        System.out.println(t*25);
        System.out.println(24l*1000l*3600l*25l);
    }
2 голосов
/ 18 октября 2010

Интегральные литералы по умолчанию обрабатываются как тип int. 24*1000*3600*25 больше Integer.MAX_VALUE, поэтому переполняется и оценивается как -2134967296. Вам нужно явно сделать один из них long, используя суффикс L, чтобы получить правильный результат:

System.out.println(24L*1000*3600*25);
1 голос
/ 18 октября 2010

Если вы хотите выполнять математические операции с большими числовыми значениями без переполнения, попробуйте класс BigDecimal.

Допустим, я хочу умножить

200 000 000 * 2 000 000 000 000 000 000L * 20 000 000

int testValue = 200000000;
System.out.println("After Standard Multiplication = " +
                                                       testValue * 
                                                       2000000000000000000L * 
                                                       20000000);

Значение операции будет -4176287866323730432, что неверно.

Используя класс BigDecimal, вы можете исключить отброшенные биты и получить правильный результат.

int testValue = 200000000;        
System.out.println("After BigDecimal Multiplication = " +
                              decimalValue.multiply(
                              BigDecimal.valueOf(2000000000000000000L).multiply(
                              BigDecimal.valueOf(testValue))));

После использования BigDecimal умножение возвращает правильный результат, который равен

80000000000000000000000000000000000

0 голосов
/ 19 декабря 2016
(int)Long.valueOf("2345678901").longValue();
...