2012-03-27 17 views
107

È possibile farlo?Come verificare se un doppio è un numero intero

double variable; 
variable = 5; 
/* the below should return true, since 5 is an int. 
if variable were to equal 5.7, then it would return false. */ 
if(variable == int) { 
    //do stuff 
} 

so il codice probabilmente non va qualcosa di simile, ma come fa è andata?

+1

C# ma simile in Java: http://stackoverflow.com/a/4077262/284240 ([Integer.MAX_VALUE] (http://docs.oracle.com/javase/1.4.2/docs/api/java /lang/Integer.html#MAX_VALUE)) –

+1

Cosa vorresti ottenere da questo? 'double' e' int' sono rappresentati in memoria in modo diverso, e userete uno o l'altro in base al contesto della gestione della memoria. – Makoto

+0

if (num% 1 == 0) –

risposta

95
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) { 
    // integer type 
} 

Questo controlla se il valore arrotondato del doppio è uguale al doppio.

La variabile può avere un valore int o doppio e ha sempre un valore int, quindi se la variabile è uguale a Math.floor(variable), deve avere un valore int.

Anche questo non funziona se il valore della variabile è infinito o negativo infinito, quindi aggiungendo 'finché la variabile non è inifinita' alla condizione.

+3

"Se l'argomento è NaN o infinito o zero positivo o zero negativo, il risultato è lo stesso dell'argomento." http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#floor%28double%29 –

+2

@TimSchmelter: buona cattura. Vale anche la pena notare che NaN non è uguale a nulla (incluso se stesso) ma +/- Inf è uguale a se stesso - quindi ci sono due casi limite! – maerics

+0

Sia Skon che Fouad hanno inviato risposte molto migliori. –

15
public static boolean isInt(double d) 
{ 
    return d == (int) d; 
} 
0
public static boolean isInteger(double d) { 
    // Note that Double.NaN is not equal to anything, even itself. 
    return (d == Math.floor(d)) && !Double.isInfinite(d); 
} 
+0

Un'implementazione più corretta restituirebbe false e dovresti scrivere un altro metodo che accetta int come argomento e restituisce true. : D – alfa

+0

@alfa: lol, bravo =) – maerics

63

Guava: DoubleMath.isMathematicalInteger. (Divulgazione: l'ho scritto.) Oppure, se non stai già importando Guava, x == Math.rint(x) è il modo più veloce per farlo; rint è misurabilmente più veloce di floor o ceil.

+2

Non conoscevo Math.rint Hai ragione. È molto più veloce di Math.floor –

+3

Questa dovrebbe essere una risposta accettata. – leventov

+0

Questo è in qualche modo preferibile all'esempio di casting di Eng.Fouad? –

153

Oppure si potrebbe usare l'operatore modulo:

(d % 1) == 0

+1

Amo davvero la semplicità di questa soluzione. È facile da leggere e da implementare. – krispy

+1

Soluzione molto intuitiva –

+2

In termini di calcolo, è più veloce di 'Math.rint (d)'? – iTurki

0

si potrebbe provare in questo modo: ottenere il valore intero del doppio, sottrarre questo dal valore doppio originale, definire un intervallo di arrotondamento e test se il numero assoluto del nuovo valore doppio (senza la parte intera) è maggiore o minore dell'intervallo definito. se è più piccolo puoi intenderlo è un valore intero. Esempio:

public final double testRange = 0.2; 

public static boolean doubleIsInteger(double d){ 
    int i = (int)d; 
    double abs = Math.abs(d-i); 
    return abs <= testRange; 
} 

Se si assegna a d il valore 33.15 il metodo restituisce true. Per ottenere risultati migliori è possibile assegnare valori più bassi a testRange (come 0.0002) a propria discrezione.

4

Prova questo modo,

public static boolean isInteger(double number){ 
    return Math.ceil(number) == Math.floor(number); 
} 

ad esempio:

Math.ceil(12.9) = 13; Math.floor(12.9) = 12; 

quindi 12,9 è non intero, tuttavia

Math.ceil(12.0) = 12; Math.floor(12.0) =12; 

quindi 12.0 è intero

0

Ecco una versione per Integer e Double:

private static boolean isInteger(Double variable) { 
    if ( variable.equals(Math.floor(variable)) && 
      !Double.isInfinite(variable)   && 
      !Double.isNaN(variable)    && 
      variable <= Integer.MAX_VALUE   && 
      variable >= Integer.MIN_VALUE) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Per convertire Double-Integer:

Integer intVariable = variable.intValue(); 
-1

Ecco una soluzione:

float var = Your_Value; 
if ((var - Math.floor(var)) == 0.0f) 
{ 
    // var is an integer, so do stuff 
} 
0

Simile a SkonJeet di rispondi a bove, ma le prestazioni sono migliori (almeno in java):

Double zero = 0d;  
zero.longValue() == zero.doubleValue() 
0

Personalmente, preferisco la semplice soluzione di operazione modulo nella risposta accettata. Sfortunatamente, SonarQube non apprezza i test di uguaglianza con punti fluttuanti senza impostare una precisione rotonda. Quindi abbiamo cercato di trovare una soluzione più conforme. Eccolo:

if (new BigDecimal(decimalValue).remainder(new BigDecimal(1)).equals(BigDecimal.ZERO)) { 
    // no decimal places 
} else { 
    // decimal places 
} 

Remainder(BigDecimal) restituisce un BigDecimal il cui valore è (this % divisor). Se questo è uguale a zero, sappiamo che non esiste un punto variabile.

1

consideri:

Double.isFinite (value) && Double.compare (value, StrictMath.rint (value)) == 0 

Questo attacca al core Java ed evita un confronto di uguaglianza tra i valori in virgola mobile (==) che è consdered male. Il isFinite() è necessario poiché rint() passa ai valori infiniti.

Problemi correlati