Как я могу проверить, если умножение двух чисел в Java вызовет переполнение?

Я использовал NUnit в течение 2 лет. Все в порядке, но я должен сказать, что система Единицы в VS довольно хороша, потому что это в Gui и может более легко сделать тест для закрытой функции, не имея необходимость бездельничать. Кроме того, Поблочное тестирование VS позволило Вам сделать покрытие и другой материал, который NUnit один не может сделать.

94
задан Steve McLeod 28 August 2017 в 08:26
поделиться

7 ответов

, возможно, это вам поможет:

/**
 * @throws ArithmeticException on integer overflow
 */
static long multiply(long a, long b) {
    double c = (double) a * b;
    long d = a * b;

    if ((long) c != d) {
        throw new ArithmeticException("int overflow");
    } else {
        return d;
    }
}
1
ответ дан 24 November 2019 в 06:05
поделиться

Может быть:

if(b!= 0 && a * b / b != a) //overflow

Не уверен в этом "решении".

Редактировать: Добавлено b! = 0.

Перед тем, как вы проголосуете против : a * b / b выиграли не быть оптимизированным. Это будет ошибка компилятора. Я до сих пор не вижу случая, чтобы ошибка переполнения могла быть замаскирована.

1
ответ дан 24 November 2019 в 06:05
поделиться

Есть ли в Java что-то вроде int.MaxValue? Если да, попробуйте

if (b != 0 && Math.abs(a) > Math.abs(Long.MAX_VALUE / b))
{
 // it will overflow
}

отредактировать: в вопросе замечено Long.MAX_VALUE

4
ответ дан 24 November 2019 в 06:05
поделиться

Я не уверен, почему никто не смотрит на решение вроде:

if (Long.MAX_VALUE/a > b) {
     // overflows
} 

Выберите, чтобы из двух чисел было больше.

2
ответ дан 24 November 2019 в 06:05
поделиться

Использовать логарифмы чтобы проверить размер результата.

5
ответ дан 24 November 2019 в 06:05
поделиться

Если a и b оба положительны, вы можете использовать:

if (a != 0 && b > Long.MAX_VALUE / a) {
    // Overflow
}

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

long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE;

if (a != 0 && (b > 0 && b > maximum / a ||
               b < 0 && b < maximum / a))
{
    // Overflow
}

Вот небольшая таблица, которую я создал, чтобы проверить это, делая вид, что переполнение происходит при -10 или +10:

a =  5   b =  2     2 >  10 /  5
a =  2   b =  5     5 >  10 /  2
a = -5   b =  2     2 > -10 / -5
a = -2   b =  5     5 > -10 / -2
a =  5   b = -2    -2 < -10 /  5
a =  2   b = -5    -5 < -10 /  2
a = -5   b = -2    -2 <  10 / -5
a = -2   b = -5    -5 <  10 / -2
59
ответ дан 24 November 2019 в 06:05
поделиться

Вместо этого можно использовать java.math.BigInteger и проверить размер результата (код не тестировался):

BigInteger bigC = BigInteger.valueOf(a) * multiply(BigInteger.valueOf(b));
if(bigC.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
  c = Long.MAX_VALUE;
} else {
  c = bigC.longValue()
}
6
ответ дан 24 November 2019 в 06:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: