Risposte:
I due operandi (1 e 3) sono numeri interi, quindi viene utilizzata l'aritmetica dei numeri interi (divisione qui). Dichiarare la variabile di risultato come double provoca solo una conversione implicita dopo la divisione .
La divisione intera ovviamente restituisce il vero risultato della divisione arrotondata verso zero. Il risultato di 0.333...
viene quindi arrotondato a 0 qui. (Nota che il processore in realtà non esegue alcun arrotondamento, ma puoi ancora pensarlo in questo modo.)
Inoltre, nota che se entrambi gli operandi (numeri) sono dati come float; 3.0 e 1.0, o anche solo il primo , quindi viene utilizzata l'aritmetica in virgola mobile, che ti dà 0.333...
.
DOWN
è verso lo zero. L'arrotondamento FLOOR
è verso l'infinito negativo.
1/3
utilizza la divisione intera poiché entrambi i lati sono numeri interi.
Hai bisogno che almeno uno di loro sia float
odouble
.
Se stai inserendo i valori nel codice sorgente come la tua domanda, puoi farlo 1.0/3
; il1.0
è un doppio.
Se ottieni i valori da qualche altra parte puoi usarli (double)
per trasformare il file int
in un file double
.
int x = ...;
int y = ...;
double value = ((double) x) / y;
dovresti usare
double g=1.0/3;
o
double g=1/3.0;
La divisione intera restituisce un numero intero.
Perché stai facendo la divisione intera.
Come dice @Noldorin, se entrambi gli operatori sono numeri interi, viene utilizzata la divisione intera.
Il risultato 0.33333333 non può essere rappresentato come intero, quindi al risultato viene assegnata solo la parte intera (0).
Se uno degli operatori è una double
/ float
, verrà eseguita un'aritmetica in virgola mobile. Ma avrai lo stesso problema se lo fai:
int n = 1.0 / 3.0;
Perché tratta 1 e 3 come numeri interi, quindi arrotondando il risultato per difetto a 0, in modo che sia un numero intero.
Per ottenere il risultato che stai cercando, dì esplicitamente a java che i numeri sono doppi in questo modo:
double g = 1.0/3.0;
La conversione in JAVA è abbastanza semplice ma richiede una certa comprensione. Come spiegato nel JLS per le operazioni su interi :
Se un operatore intero diverso da un operatore di scorrimento ha almeno un operando di tipo long, l'operazione viene eseguita utilizzando una precisione a 64 bit e il risultato dell'operatore numerico è di tipo long. Se l'altro operando non è lungo, viene prima ampliato (§5.1.5) per digitare long per promozione numerica (§5.6).
E un esempio è sempre il modo migliore per tradurre il JLS;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
In caso contrario, l'operazione viene eseguita utilizzando una precisione a 32 bit e il risultato dell'operatore numerico è di tipo int. Se uno degli operandi non è un int, viene prima ampliato per digitare int mediante promozione numerica.
short + int -> int + int -> int
Un piccolo esempio dell'uso di Eclipse per mostrare che anche un'aggiunta di due short
non sarà così facile:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
Ciò richiederà una fusione con una possibile perdita di precisione.
Lo stesso vale per gli operatori in virgola mobile
Se almeno uno degli operandi di un operatore numerico è di tipo double, l'operazione viene eseguita utilizzando l'aritmetica a virgola mobile a 64 bit e il risultato dell'operatore numerico è un valore di tipo double. Se l'altro operando non è un double, viene prima ampliato (§5.1.5) per digitare double per promozione numerica (§5.6).
Quindi la promozione viene fatta sul float in double.
E la combinazione di valori interi e variabili risulta in valori mobili come detto
Se almeno uno degli operandi di un operatore binario è di tipo a virgola mobile, l'operazione è a virgola mobile, anche se l'altra è integrale.
Questo è vero per gli operatori binari ma non per gli "Operatori di assegnazione" come +=
Un semplice esempio funzionante è sufficiente per dimostrarlo
int i = 1;
i += 1.5f;
Il motivo è che qui viene eseguito un cast implicito, verrà eseguito come
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
La soluzione più semplice è fare solo questo
double g = ((double) 1 / 3);
Ciò che fa, dal momento che non hai inserito 1.0 / 3.0, ti consente di convertirlo manualmente in un tipo di dati double poiché Java ha assunto che fosse una divisione Integer, e lo farebbe anche se ciò significasse restringere la conversione. Questo è ciò che viene chiamato un operatore di cast.
L'ho fatto.
double g = 1.0/3.0;
System.out.printf("%gf", g);
Usa .0 mentre esegui doppi calcoli, altrimenti Java presumerà che tu stia utilizzando numeri interi. Se un calcolo utilizza una quantità qualsiasi di valori doppi, l'output sarà un valore doppio. Se sono tutti numeri interi, l'output sarà un numero intero.
(1/3) significa divisione intera, ecco perché non puoi ottenere un valore decimale da questa divisione. Per risolvere questo problema usa:
public static void main(String[] args) {
double g = 1.0 / 3;
System.out.printf("%.2f", g);
}
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Poiché sia 1 che 3 sono interi, il risultato non è arrotondato ma viene troncato. Quindi ignori le frazioni e prendi solo interi.
Per evitare ciò, utilizza almeno uno dei tuoi numeri 1 o 3 come forma decimale 1.0 e / o 3.0.
Prova questo:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
Do "double g = 1.0 / 3.0;" anziché.
Molti altri non sono riusciti a sottolineare il vero problema:
Un'operazione solo su numeri interi esegue il cast del risultato dell'operazione su un numero intero.
Ciò significa necessariamente che i risultati in virgola mobile potrebbero essere visualizzati come un numero intero, verranno troncati (separa la parte decimale).
Cosa sta trasmettendo (typecasting / conversione del tipo) che chiedi?
Dipende dall'implementazione del linguaggio, ma Wikipedia ha una visione abbastanza completa e parla di coercizione , che è un'informazione fondamentale per rispondere alla tua domanda.
1/2
, non nella lingua di destinazione (java). Si richiama semplicemente una divisione intera, che risulterà in un risultato intero. Il Type Casting è solo a causa della conversione da int
a a double
durante l'assegnazione.
0.5
. Semplicemente, in Java, 1/2
è una divisione intera, che risulta in un numero intero zero. Puoi assegnare uno zero a un doppio, sarà comunque uno zero, anche se un 0.0
doppio.
int i = .99999999
imposta int a 0. Più specificamente, prende la parte intera e scarta il resto.