Умножение долго оценивает?

Здесь существуют некоторые большие, эффективные решения. Однако для любого не обеспокоенного абсолютом, самым эффективным O(n) решение, я пошел бы с простой остротой O(n^2*log(n)) решение:

def unique(xs):
    return sorted(set(xs), key=lambda x: xs.index(x))

или более эффективный с двумя лайнерами O(n*log(n)) решение:

def unique(xs):
    positions = dict((e,pos) for pos,e in reversed(list(enumerate(xs))))
    return sorted(set(xs), key=lambda x: positions[x])
17
задан Aza 12 April 2013 в 00:26
поделиться

4 ответа

В Java все вычисления выполняются в самом большом типе данных, необходимом для обработки всех текущих значений. Итак, если у вас int * int, математика всегда будет выполняться как целое число, но int * long - как long.

В этом случае 1024 * 1024 * 1024 * 80 выполняется как Int, который переполняет int.

"L", конечно, заставляет один из операндов быть Int-64 (long), поэтому вся математика выполняется с сохранением значений как Long, поэтому переполнения не происходит.

39
ответ дан 30 November 2019 в 10:53
поделиться

Целочисленные литералы - это int s. Переполнение int . Используйте суффикс L .

long value = 1024L * 1024L * 1024L * 80L;

Если данные поступили из переменных, которые либо преобразуются, либо заранее присваиваются значениям long.

long value = (long)a * (long)b;

long aL = a;
long bL = b;
long value = aL*bL

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

Также не строчные буквы l в качестве суффикса можно спутать с 1 .

5
ответ дан 30 November 2019 в 10:53
поделиться

Я подозреваю, что это потому, что по умолчанию java обрабатывает литералы как целые числа, а не как длинные. Итак, без L на 80 умножение переполняется.

1
ответ дан 30 November 2019 в 10:53
поделиться

Этот код:

long value = 1024 * 1024 * 1024 * 80; 

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

Так как int 32 бита, значение переносится в оболочку и приводит к нулю.

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

1
ответ дан 30 November 2019 в 10:53
поделиться
Другие вопросы по тегам:

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