Не получается целочисленное переполнение в Clojure? - PullRequest
7 голосов
/ 29 декабря 2011

Я запускаю Clojure 1.3.0 с La Clojure в IntelliJ IDEA при чтении Радости Clojure , а в разделе 4.1.3 (стр. 64) авторы демонстрируют целочисленное переполнение с помощью следующего кода:

(+ Integer/MAX_VALUE Integer/MAX_VALUE)
;=> java.lang.ArithmeticException: integer overflow

Однако, когда я пробую его на REPL, я получаю вместо

user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294

user=> Integer/MAX_VALUE
2147483647

Что здесь происходит?Почему мои целые числа добавляются правильно, а не переполняются?

Ответы [ 2 ]

8 голосов
/ 30 декабря 2011

В Clojure все первичные целые числа являются примитивными длинными , и документация на странице чисел ссылается на это.в версии 1.3 вам просто нужно большее число, чтобы получить переполнение.

user=> (+ Long/MAX_VALUE Long/MAX_VALUE)
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)

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

user=> (+' Long/MAX_VALUE Long/MAX_VALUE)
18446744073709551614N
8 голосов
/ 29 декабря 2011

(отредактировано) Clojure (как минимум 1.3.0) автоматически преобразует целое число в длинное при необходимости. Для получения более подробной информации об автоматическом боксе, продвижении и поддержке примитивных числовых типов в Clojure 1.3.0 проверьте документацию для Clojure 1.3.0 Numerics .

Причина, по которой вы не получаете переполнение, заключается в том, что Clojure автоматически преобразует целое число в длинное, поэтому (+ Integer/MAX_VALUE Integer/MAX_VALUE) добавляет два длинных:

user> (type Integer/MAX_VALUE)
java.lang.Long
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...