2016-03-25 10 views
12
System.out.println((byte) (1.0/0)); 
    System.out.println((short) (1.0/0)); 
    System.out.println((int) (1.0/0)); 
    System.out.println((long) (1.0/0)); 

Il risultato è:Perché la divisione da zero a numeri interi primitivi dà risultati diversi?

-1 
    -1 
    2147483647 
    9223372036854775807 

in formato binario:

1111 1111 
    1111 1111 1111 1111 
    0111 1111 1111 1111 1111 1111 1111 1111 
    0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 

Perché fusione infinito a int e interi lunghi mantiene segno po 'come "0", mentre set segno bit a "1 "per byte e interi brevi?

+3

Suppongo che stia eseguendo il casting su un 'int' e poi su un' byte' Nota: Integer.MAX_VALUE è il valore più vicino a Infinity per un 'int'. –

+0

Thx Peter, ma trasmettere Integer.MAX_VALUE a "long" ci darebbe solo "2147483647L", ho ragione? –

+0

@PeterLawrey Non sarebbe possibile che '(1.0/0)' sia valutato come 'double', e quindi la casta in byte considera gli 8 bit inferiori? Mentre IEEE 754 definisce lo standard per 'double' e' float', trovo strano che il bit di segno sia 0 per 'int' poiché i documenti non definiscono le specifiche di infinity per' int'. –

risposta

10

JLS 5.1.3:

Una conversione restringimento di un numero a virgola mobile a un tipo integrale T richiede due fasi:

Nella prima fase, il numero in virgola mobile è convertita in un lungo , se T è long o to int, se T è byte, short, char o int, come segue:

Se il numero in virgola mobile è NaN (§4.2.3), il risultato del primo passo della conversione sione è un int lungo 0.

Altrimenti, se il numero a virgola mobile non è un infinito, il valore a virgola mobile viene arrotondato a un valore intero V, arrotondando verso zero usando IEEE 754 round-toward- modalità zero (§4.2.3). Poi vi sono due casi:

Se T è lunga, e questo valore intero può essere rappresentato come un lungo, allora il risultato della prima fase è la lunga valore V.

Altrimenti, se questo numero intero valore può essere rappresentato come un int, quindi il risultato della prima fase è il valore int V.

Altrimenti, uno dei due casi seguenti deve essere vera:

il valore deve essere troppo piccola (a valore negativo di grande magnitudine o infinito negativo) e il risultato del primo passo è il più piccolo valore rappresentabile di di tipo int o long.

Il valore deve essere troppo grande (un valore positivo di grandi dimensioni o infinito positivo), e il risultato della prima fase è la più grande valore rappresentabile di int long.

Nella seconda fase:

Se T è int o lunga, il risultato della conversione è il risultato della prima fase .

Se T è byte, char, o corto, il risultato della conversione è il risultato di una conversione restringimento al tipo T (§5.1.3) del risultato della primo passo.

Quindi un valore doppio infinito è il primo getto di int ritornando Integer.MAX_VALUE, e quindi esso è anche cast byte/short, che prende il numero appropriato di byte bassi (e prende -1 come risultato). Getta a int e long non hanno quel passo in più, ma byte e short andare primo attraverso int e poi-byte/short.

+0

Anche io stavo per riferirsi a Narrowing Primitive Conversion! +1 –

Problemi correlati