Как добавить два java.lang.Numbers?
У меня есть два числа. Например:
Number a = 2;
Number b = 3;
//Following is an error:
Number c = a + b;
Почему арифметические операции не поддерживаются числами? Во всяком случае, как бы добавить эти два числа в java? (Конечно, я получаю их откуда-то, и я не знаю, являются ли они Integer или float и т.д.).
Ответы
Ответ 1
Вы говорите, что не знаете, являются ли ваши числа целыми или плавают... когда вы используете класс Number
, компилятор также не знает, являются ли ваши числа целыми числами, поплавками или какой-то другой. В результате основные математические операторы, такие как + и - не работают; компьютер не знал, как обрабатывать значения.
СТАРТ РЕДАКТИРОВАТЬ
Основываясь на обсуждении, я подумал, что пример может помочь. Компьютеры хранят числа с плавающей запятой как две части, коэффициент и показатель. Таким образом, в теоретической системе 001110 может быть разбит как 0011 10 или 3 2= 9. Но положительные целые числа сохраняют числа как двоичные, поэтому 001110 также может означать 2 + 4 + 8 = 14. Когда вы используете класс Number
, вы сообщаете компьютеру, которого не знаете, является ли число float или int или что, поэтому он знает, что он имеет 001110, но он не знает, означает ли это 9 или 14 или другое значение.
END EDIT
Что вы можете сделать, так это сделать небольшое предположение и преобразовать в один из типов для математики. Таким образом, вы могли бы
Number c = a.intValue() + b.intValue();
который вы могли бы также превратить в
Integer c = a.intValue() + b.intValue();
если вы готовы перенести некоторую ошибку округления или
Float c = a.floatValue() + b.floatValue();
если вы подозреваете, что не имеете дело с целыми числами, и все в порядке с возможными незначительными проблемами точности. Или, если вы предпочтете принять небольшой удар производительности вместо этой ошибки,
BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue()));
Ответ 2
Это также поможет сделать способ обработки добавления для вас. Теперь я не знаю, как это повлияет на производительность, но я предполагаю, что это будет меньше, чем использование BigDecimal.
public static Number addNumbers(Number a, Number b) {
if(a instanceof Double || b instanceof Double) {
return a.doubleValue() + b.doubleValue();
} else if(a instanceof Float || b instanceof Float) {
return a.floatValue() + b.floatValue();
} else if(a instanceof Long || b instanceof Long) {
return a.longValue() + b.longValue();
} else {
return a.intValue() + b.intValue();
}
}
Ответ 3
Единственный способ правильно добавить любые два типа java.lang.Number:
Number a = 2f; // Foat
Number b = 3d; // Double
Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) );
Это работает даже для двух аргументов с другим типом номера. Он будет (должен?) Не производить никаких побочных эффектов, таких как переполнение или потеря точности, поскольку toString() числового типа не снижает точность.
Ответ 4
java.lang.Number
- это просто суперкласс всех классов-оболочек примитивных типов (см. java doc). Используйте подходящий примитивный тип (double
, int
и т.д.) Для вашей цели или соответствующий класс-оболочку (double
, Integer
и т.д.).
Рассмотрим это:
Number a = 1.5; // Actually Java creates a double and boxes it into a Double object
Number b = 1; // Same here for int -> Integer boxed
// What should the result be? If Number would do implicit casts,
// it would behave different from what Java usually does.
Number c = a + b;
// Now that works, and you know at first glance what that code does.
// Nice explicit casts like you usually use in Java.
// The result is of course again a double that is boxed into a Double object
Number d = a.doubleValue() + (double)b.intValue();
Ответ 5
Используйте следующее:
Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type.
Или:
int a = 2;
int b = 3;
int c = 2 + 3;
Ответ 6
Я думаю, что на ваш вопрос есть две стороны.
Почему оператор + не поддерживается на Number?
Потому что спецификация языка Java. не указывает это, и нет перегрузки оператора. Существует также не естественный способ компиляции, чтобы отнести число к некоторому фундаментальному типу, и нет никакого естественного add для определения для некоторого типа операций.
Почему основные арифметические операции не поддерживаются на Number?
(Скопировано из моего комментария:)
Не все подклассы могут реализовать это так, как вы ожидали. Особенно с типами Atomic трудно определить полезный контракт, например. Добавить.
Кроме того, добавление метода будет проблемой, если вы попытаетесь добавить Long to Short.
Ответ 7
Number
- это класс abstract
, который вы не можете создать. Если у вас есть правильный экземпляр, вы можете получить number.longValue()
или number.intValue()
и добавить их.
Ответ 8
Прежде всего, вы должны знать, что Number является абстрактным классом. Что происходит здесь, так это то, что когда вы создаете свои 2 и 3, они интерпретируются как примитивы, и в этом случае создается подтип (я думаю, Integer). Поскольку Integer является подтипом Number, вы можете назначить вновь созданное Integer в ссылку Number.
Однако число - это просто абстракция. Он может быть целым числом, он может быть плавающей точкой и т.д., Поэтому семантика математических операций будет неоднозначной.
Номер не предоставляет классические операции карты по двум причинам:
Во-первых, методы-члены в Java не могут быть операторами. Это не С++. В лучшем случае они могут предоставить add()
Во-вторых, выяснение того, какой тип операции следует делать, когда у вас есть два входа (например, разделение поплавка на int), довольно сложно.
Поэтому вместо этого вы должны сделать преобразование обратно к определенному примитивному типу, который вам интересен, и применить математические операторы.
Ответ 9
Лучшим ответом будет сделать использование с двойной диспетчерской бурение до самых известных типов (посмотрите на реализацию addtition Smalltalk)