Лучший способ сравнить int с числом - PullRequest
1 голос
/ 02 декабря 2011

У меня есть метод с параметром Number, и я должен определить, меньше ли он int.Я придумал следующее:

Integer.valueOf(myInt) > (Integer) myNumber

Что выглядит довольно неуклюже для такой простой задачиБолее того, я не уверен, что он будет хорошо работать с BigDecimal et.al., и какие случаи мне придется проверить?

Как это можно улучшить?

Спасибо

Ответы [ 4 ]

4 голосов
/ 02 декабря 2011

Ваш код приведет к ClassCastException, если myNumber будет отличаться от Integer.

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

myInt > myNumber.doubleValue()

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

4 голосов
/ 02 декабря 2011

У вас могут возникнуть проблемы, если myNumber является экземпляром Long. У вас могут возникнуть проблемы с переполнением (что, если ваш Number на самом деле больше Integer.MAX_VALUE?).

Кроме того, ваш Number может быть double, а преобразование в int приведет к потере точности, так как ваше число будет усечено.

Преобразование вашего номера в double может быть разумным решением:

myInt > myNumber.doubleValue();
2 голосов
/ 02 декабря 2011

Сравнение становится немного сложнее, потому что BigDecimal и BigInteger также расширяют Number. Эти классы могут содержать целочисленные значения неограниченного размера (ну, ограниченные памятью на вашем компьютере).

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

Самое безопасное, что нужно сделать, это преобразовать Number в строку и затем передать эту строку классу BigDecimal для анализа.

например.

Number n = ...;
int i = ...;

BigDecimal m = new BigDecimal(n.toString());
BigDecimal j = new BigDecimal(i);

boolean result = j.compareTo(m) < 0;
// equivalent to i < n

Если вы уверены, что никогда не получите экземпляр BigInteger или BigDecimal, значение которого превышает максимальное положительное или максимальное отрицательное значение типа double, тогда будет безопасно использовать Number.doubleValue, чтобы получить число для сравнения.

Существуют дополнительные проблемы, с которыми вы можете столкнуться при возможности сравнения BigDecimals. Это потому, что BigDecimals представляют свои значения в базе 10, тогда как другие подклассы Number используют базу 2.

Как таковой new BigDecimal("0.1") не равен 0.1d или 0.1f. Это связано с тем, что числа с плавающей запятой и числа с двойными числами не могут точно представлять многие дробные числа 10 (тогда как BigDecimal может) Таким образом, получение двойного значения из BigDecimal может привести к ошибочным сравнениям. Но поскольку вы сравниваете его с целыми числами, это проблема, с которой вам не нужно сталкиваться.

2 голосов
/ 02 декабря 2011
myInt > myNumber.intValue()

Но это потеряло бы информацию.

(double)myInt > myNumber.doubleValue()
...