¿Cómo agregar dos java.lang.Numbers?

Tengo dos números. P.ej:

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

¿Por qué las operaciones aritméticas no son compatibles con los números? De todos modos, ¿cómo agregaría estos dos números en java? (Por supuesto que los obtengo de algún lado y no sé si son enteros o float, etc.).

Dice que no sabe si sus números son enteros o flotantes … cuando usa la clase Number , el comstackdor tampoco sabe si sus números son enteros, flotantes o alguna otra cosa. Como resultado, los operadores matemáticos básicos como + y – no funcionan; la computadora no sabría cómo manejar los valores.

INICIAR EDITAR

Basado en la discusión, pensé que un ejemplo podría ayudar. Las computadoras almacenan números en coma flotante como dos partes, un coeficiente y un exponente. Entonces, en un sistema teórico, 001110 podría dividirse como 0011 10 o 3 2 = 9. Pero los números enteros positivos almacenan los números como binarios, por lo que 001110 también podría significar 2 + 4 + 8 = 14. Cuando usa el Number clase, le está diciendo a la computadora que no sabe si el número es un flotador o un int o qué, entonces sabe que tiene 001110 pero no sabe si eso significa 9 o 14 o algún otro valor.

FIN EDITAR

Lo que puedes hacer es hacer una pequeña suposición y convertirte a uno de los tipos para hacer los cálculos. Entonces podrías tener

 Number c = a.intValue() + b.intValue(); 

que bien podría convertirse en

 Integer c = a.intValue() + b.intValue(); 

si está dispuesto a sufrir algún error de redondeo, o

 Float c = a.floatValue() + b.floatValue(); 

si sospecha que no está tratando con números enteros y está de acuerdo con posibles problemas menores de precisión. O bien, si prefiere dar un golpe de rendimiento pequeño en lugar de ese error,

 BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue())); 

También funcionaría crear un método para manejar el agregado por ti. Ahora no sé el impacto en el rendimiento que esto causará, pero supongo que será menor que con BigDecimal.

 public static Number addNumbers(Number a, Number b) { if(a instanceof Double || b instanceof Double) { return new Double(a.doubleValue() + b.doubleValue()); } else if(a instanceof Float || b instanceof Float) { return new Float(a.floatValue() + b.floatValue()); } else if(a instanceof Long || b instanceof Long) { return new Long(a.longValue() + b.longValue()); } else { return new Integer(a.intValue() + b.intValue()); } } 

La única forma de agregar correctamente dos tipos de java.lang.Number es:

 Number a = 2f; // Foat Number b = 3d; // Double Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) ); 

Esto funciona incluso para dos argumentos con un tipo de número diferente. No (¿debería?) No producir efectos secundarios como desbordamientos o pérdida de precisión, en la medida en que toString () del tipo de número no reduzca la precisión.

java.lang.Number es solo la superclase de todas las clases contenedoras de tipos primitivos (ver java doc ). Use el tipo primitivo apropiado ( double , int , etc.) para su propósito, o la clase contenedora respectiva ( Double , Integer , etc.).

Considera esto:

 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(); 

Use lo siguiente:

 Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type. 

O:

 int a = 2; int b = 3; int c = 2 + 3; 

Creo que hay dos lados en tu pregunta.

¿Por qué el operador + no es compatible con Number?

Porque la especificación de lenguaje de Java. no especifica esto, y no hay sobrecarga del operador. Tampoco hay una forma natural en tiempo de comstackción para convertir el Número a algún tipo fundamental, y no hay un complemento natural para definir para algún tipo de operaciones.

¿Por qué las operaciones aritméticas básicas no son compatibles con Number?

(Copiado de mi comentario 🙂

No todas las subclases pueden implementar esto de la manera que cabría esperar. Especialmente con los tipos Atomic es difícil definir un contrato útil para, por ejemplo, agregar.

Además, un método add sería un problema si intentas agregar Long a Short.

Number es una clase abstract la que no puedes hacer una instancia. Siempre que tenga una instancia correcta, puede obtener number.longValue() o number.intValue() y agregarlos.

En primer lugar, debe tener en cuenta que Number es una clase abstracta. Lo que sucede aquí es que cuando creas tus 2 y 3, se interpretan como primitivas y se crea un subtipo (creo que un entero) en ese caso. Como un entero es un subtipo de número, puede asignar el entero recién creado a una referencia numérica.

Sin embargo, un número es solo una abstracción. Podría ser un número entero, podría ser un punto flotante, etc., por lo que la semántica de las operaciones matemáticas sería ambigua.

El número no proporciona las operaciones clásicas del mapa por dos motivos:

Primero, los métodos miembro en Java no pueden ser operadores. No es C ++. En el mejor de los casos, podrían proporcionar un complemento ()

Segundo, averiguar qué tipo de operación hacer cuando tienes dos entradas (por ejemplo, una división de un flotante por un int) es bastante complicado.

Por lo tanto, en su lugar, es su responsabilidad hacer que la conversión vuelva al tipo primitivo específico en el que está interesado y aplicar los operadores matemáticos.

La mejor respuesta sería hacer una perforación de envío doble a la mayoría de los tipos conocidos (eche un vistazo a la implementación de Smalltalk addtition)