Подтвердить что ты не робот

Как добавить два java.lang.Numbers?

У меня есть два числа. Например:

Number a = 2;
Number b = 3;
//Following is an error:
Number c = a + b;

Почему арифметические операции не поддерживаются числами? Во всяком случае, как бы добавить эти два числа в java? (Конечно, я получаю их откуда-то, и я не знаю, являются ли они Integer или float и т.д.).

4b9b3361

Ответ 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)