Студия Android предупреждает о целочисленном умножении, неявно приведенном к типу long. Как это исправить?

avatar
Chaitanya Karmarkar
9 августа 2021 в 04:48
181
2
0
 private static boolean isOverDate(long targetDate, int threshold) {
    return new Date().getTime() - targetDate >= threshold * 24 * 60 * 60 * 1000;
}

Я использую вышеуказанную функцию, и Android Studio предупреждает меня о:

threshold * 24 * 60 * 60 * 1000: integer multiplication implicitly cast to long 

Как это исправить? А почему предупреждает?

Источник
Truong Hieu
9 августа 2021 в 04:51
0

что вы вводите в threshold?

ישו אוהב אותך
9 августа 2021 в 04:53
0

Потому что ваш targetDate - это long?

Chaitanya Karmarkar
9 августа 2021 в 04:57
0

Я использую эту функцию в двух местах и ​​передаю ей 10 и 1 соответственно в качестве порогового значения.

chrylis -cautiouslyoptimistic-
9 августа 2021 в 05:10
0

Обратите внимание, что вашим кодом будет намного проще управлять (и этот метод будет ненужным), если вы будете использовать современные классы java.time.

Ответы (2)

avatar
Truong Hieu
9 августа 2021 в 04:55
2

Поскольку max_int равно 2 147 483 648.

Если ваш threshold больше 25 (25 * 24 * 60 * 60 * 1000 = 2.160.000.000), он будет выше, чем int. Поэтому вам нужно будет выполнить приведение к long, иначе результат может быть неверным.

Ссылка: https://coderhelper.com/a/42671759/4316327

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

Решение:

long timeToCheck = threshold * 24 * 60 * 60 * 1000L;
return new Date().getTime() - targetDate >= timeToCheck;

или одна строка (здесь отличается L после последнего числа, будет понятно, что вы измените тип на long)

return new Date().getTime() - targetDate >= threshold * 24 * 60 * 60 * 1000L;

или отливка

return new Date().getTime() - targetDate >= (long) threshold * 24 * 60 * 60 * 1000;
Chaitanya Karmarkar
9 августа 2021 в 04:58
0

Как исправить это предупреждение? Или просто приведение его к длинному исправит это?

Truong Hieu
9 августа 2021 в 05:05
0

@ChaitanyaKarmarkar всегда пожалуйста. Я только что обновил ответ еще раз, чтобы вы и люди, которые приходят позже, могли это понять.

Code-Apprentice
9 августа 2021 в 05:25
0

Вы должны рассмотреть возможность приведения первой операции к long, а не к последней.

avatar
Stephen C
9 августа 2021 в 05:05
3

Хорошо, это немного сложно распаковать.

В левой части (слева) выражения >= мы имеем:

new Date().getTime() - targetDate

Тип этого выражения — long, поскольку targetDate объявлен как long.

На правой стороне мы имеем:

threshold * 24 * 60 * 60 * 1000

Это int, потому что все операнды ints.

Однако это выражение вероятно переполнится. Значение 24 * 60 * 60 * 1000 является "довольно большим", и когда вы умножаете его на threshold, результирующее значение может оказаться слишком большим, чтобы его можно было представить как int. Если он совершит переполнение, то результат будет усечен, и тест >= даст неверный результат.

Итак... компилятор предлагает вам выполнить вычисление RHS, используя арифметику long. Простым способом было бы объявить threshold как long. Но вы также можете привести его к long, например:

((long) threshold) * 24 * 60 * 60 * 1000
Truong Hieu
9 августа 2021 в 05:08
0

Хороший ответ. Я также включил ваш ответ в другой вопрос.