Come aggiungere due java.lang.Numbers?

Ho due numeri. Per esempio:

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

Perché le operazioni aritmetiche non sono supportate su Numbers? Ad ogni modo, come aggiungerei questi due numeri in java? (Certo che li sto prendendo da qualche parte e non so se sono interi o float ecc.).

Dici di non sapere se i tuoi numeri sono interi o float … quando usi la class Number , anche il compilatore non sa se i tuoi numeri sono numeri interi, float o altre cose. Di conseguenza, gli operatori matematici di base come + e – non funzionano; il computer non saprebbe come gestire i valori.

START EDIT

Sulla base della discussione, ho pensato che un esempio potrebbe aiutare. I computer memorizzano i numeri in virgola mobile come due parti, un coefficiente e un esponente. Quindi, in un sistema teorico, 001110 potrebbe essere suddiviso in 0011 10 o 3 2 = 9. Ma interi positivi memorizzano numeri come binari, quindi 001110 potrebbe anche significare 2 + 4 + 8 = 14. Quando si utilizza il Number class, stai dicendo al computer che non sai se il numero è un float o un int o cosa, quindi sa che ha 001110 ma non sa se questo significa 9 o 14 o qualche altro valore.

FINE MODIFICA

Quello che puoi fare è fare un po ‘di ipotesi e convertirti in uno dei tipi per fare i conti. Quindi potresti avere

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

in cui potresti anche trasformarti

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

se sei disposto a subire qualche errore di arrotondamento, o

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

se si sospetta che non si abbia a che fare con numeri interi e che vada bene con possibili problemi di precisione minori. Oppure, se preferisci fare un piccolo colpo alle prestazioni invece di quell’errore,

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

Funzionerebbe anche per creare un metodo per gestire l’aggiunta per te. Ora non conosco l’impatto sulle prestazioni, ma suppongo che sarà inferiore all’utilizzo di 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()); } } 

L’unico modo per aggiungere correttamente due tipi di java.lang.Number è:

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

Funziona anche per due argomenti con un diverso numero-tipo. Dovrebbe (dovrebbe?) Non produrre effetti collaterali come overflow o perdere precisione, per quanto il toString () del numero-tipo non riduca la precisione.

java.lang.Number è solo la superclass di tutte le classi wrapper di tipi primitivi (vedi java doc ). Utilizzare il tipo primitivo appropriato ( double , int , ecc.) Per il proprio scopo o la rispettiva class wrapper ( Double , Integer , ecc.).

Considera questo:

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

Utilizza il seguente:

 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; 

Penso che ci siano 2 lati alla tua domanda.

Perché l’operatore + non è supportato sul numero?

Perché la specifica del linguaggio Java. non specifica questo, e non c’è sovraccarico dell’operatore. Non esiste anche un modo naturale in fase di compilazione per assegnare il Numero a un tipo fondamentale, e non esiste un add naturale da definire per alcuni tipi di operazioni.

Perché le operazioni aritmetiche di base non sono supportate dal numero?

(Copiato dal mio commento 🙂

Non tutte le sottoclassi possono implementarlo in un modo che ci si aspetterebbe. Soprattutto con i tipi di Atomic è difficile definire un contratto utile per esempio aggiungere.

Inoltre, aggiungere un metodo sarebbe un problema se si tenta di aggiungere un lungo a un breve.

Number è una class abstract cui non è ansible creare un’istanza. Se si dispone di un’istanza corretta, è ansible ottenere number.longValue() o number.intValue() e aggiungerli.

Prima di tutto, devi essere consapevole che Number è una class astratta. Quello che succede qui è che quando crei i tuoi 2 e 3, vengono interpretati come primitivi e in questo caso viene creato un sottotipo (penso un intero). Poiché un intero è un sottotipo di Numero, è ansible assegnare il numero intero appena creato a un riferimento Numero.

Tuttavia, un numero è solo un’astrazione. Potrebbe essere intero, potrebbe essere in virgola mobile, ecc., Quindi la semantica delle operazioni matematiche sarebbe ambigua.

Il numero non fornisce le classiche operazioni sulla mappa per due motivi:

Innanzitutto, i metodi membri in Java non possono essere operatori. Non è C ++. Nella migliore delle ipotesi, potrebbero fornire un add ()

In secondo luogo, capire quale tipo di operazione fare quando si hanno due input (ad es. Una divisione di un float con un int) è piuttosto complicata.

Quindi, è tua responsabilità riportare la conversione al tipo specifico primitivo che ti interessa e applicare gli operatori matematici.

La migliore risposta sarebbe quella di rendere utilizzabile con la doppia spedizione di drill-down per i tipi più noti (dare un’occhiata all’implementazione di implementazione Smalltalk)