2013-11-25 4 views
1

Я работаю над системой обмена, и пользователь устанавливает цену и сумму для обмена.Проверьте, достаточно ли Integer

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

Когда сумма обмена установлена ​​на 9 или более, даже если у меня есть чек, чтобы убедиться, что число не превышает максимального значения, оно не работает. Я сделал некоторые отладки и при определении размера до 9, а цена 2147483646 (1 меньше, чем максимальное число), он печатает это:

2.147.483.630 - 9

Это моя отладка кода, что должен Я добавляю к этому, чтобы убедиться, что этого не происходит?

public void setPrimaryAmount(int primaryAmount) { 
     int price = primaryAmount * this.price; 
     System.out.println(Misc.format(this.price * primaryAmount) + " - " + primaryAmount); 
     if (price > Integer.MAX_VALUE || 
       price == Integer.MAX_VALUE || 
       price >= Integer.MAX_VALUE || 
       price < 0 || price <= 0 || 
       price++ == Integer.MAX_VALUE) { 
      System.out.println("Attempted to set a bad amount."); 
      return; 
     } 
     this.primaryAmount = primaryAmount; 
    } 

«Пытались установить плохое количество» печатает до тех пор, пока введите сумму> = 9.

+1

Вы действительно осознаете, что тесты, такие как «цена <0 || цена <= 0' являются избыточными: 'price <= 0' вполне достаточно. Аналогично для 'price> Integer.MAX_VALUE || price == Integer.MAX_VALUE || price> = Integer.MAX_VALUE', за исключением добавленной морщин, что целая переменная может ** никогда ** быть больше, чем 'Integer.MAX_VALUE', поэтому' price == Integer.MAX_VALUE' - это все, что вам нужно. –

ответ

5

Вы не можете сохранить значение в междунар и затем проверить, чтобы увидеть, является ли это слишком большой для int. Храните его в длительном порядке.

long price = (long)primaryAmount * (long)this.price; 
+0

Обратите внимание, что переход на длинные позиции для хорошего гарантирует, что вы можете продать планету без переполнения. – Radiodef

+0

Спасибо! Это очень легко разрешило проблему. – Tyluur

+0

@Tyluur Мы принимаем в качестве ответа (выберите галочку), когда мы будем рады ответить, решает нашу проблему. –

0

При установке «цена», чтобы primaryAmount * this.price, чтобы проверить, если он находится выше или ниже Integer.MAX_VALUE Integer.MIN_VALUE, потому что это целое число он будет катиться, например, значение Integer.MAX_VALUE + = 1 станет Integer.MIN_VALUE и, наоборот, проверка не нужна. Разумеется, вы можете сделать это более крупным типом данных, а затем проверить, но есть более быстрый способ. До тех пор, как мы знаем, что this.price есть мы можем определить, что максимальное значение «primaryAmount» может быть без exeeding 2,147,483,646 раз умноженное с this.price просто делать это в обратном направлении:

int max = 2147483646/this.price 

Это значение может действовать как максимум для простая функция обрезки, чтобы гарантировать ее находится в пределах диапазона, например:

private int confirmRange(int number, int max, int min) { 
    if (number > max) number = max; 
    if (number < min) number = min; 
    return number; 
} 
1

в Java 8, один подход будет использовать

Math.addExact(int, int); 

, который, согласно Javadocs, будет вызывать ArithmeticException, если результат переполняет int. В других версиях я бы рекомендовал, что предложил Flight Odyssey, и использовать длинные, по крайней мере, для этих типов проверок.

Смежные вопросы