2013-08-15 15 views
25

ho qualche codice come questo:Come testare se un doppio è zero?

class Foo { 
    public double x; 
} 

void test() { 
    Foo foo = new Foo(); 

    // Is this a valid way to test for zero? 'x' hasn't been set to anything yet. 
    if (foo.x == 0) { 

    } 

    foo.x = 0.0; 

    // Will the same test be valid? 
    if (foo.x == 0) { 

    } 
} 

Io fondamentalmente vogliono evitare un'eccezione di divisione per zero nel futuro.

Grazie

+8

Perché non ci provi? – hexafraction

+1

Il valore predefinito di un tipo di dati numerici è 0, quindi sì. –

+1

C'è zero positivo e negativo e 'x == 0' test per entrambi e non fornirà mai un'eccezione o un errore. Si ottiene solo un errore di divisione per zero dividendo due * numeri interi * e il denominatore è 0. Poiché si utilizza il punto mobile, non si otterrà mai un'eccezione. –

risposta

33

I primitivi numerici nell'ambito della classe vengono inizializzati a zero quando non vengono inizializzati esplicitamente.

I primitivi numerici in ambito locale (variabili nei metodi) devono essere inizializzati in modo esplicito.

Se si è preoccupati solo della divisione con zero eccezioni, verificare che il proprio doppio non sia esattamente zero funzioni alla grande.

if(value != 0) 
    //divide by value is safe when value is not exactly zero. 

Altrimenti quando controllare se un valore di virgola mobile come double o float è 0, una soglia di errore è utilizzato per rilevare se il valore è prossimo a 0, ma non abbastanza 0.

+3

+1 per chiarire che solo la classe le primitive numeriche di scope vengono inizializzate a zero. – anubhava

+2

Quanto va definita una soglia di errore? È molto soggettivo e probabilmente non farebbe ciò che l'utente sta tentando di fare. Che cosa succede se la soglia è troppo grande e in realtà tratti un non zero come zero? – Anshul

+0

@Anshul Whoops, grazie per le critiche! Ho modificato la mia risposta dopo aver riletto la domanda. Perso era preoccupato per la divisione di 0. –

5

Sì; tutti i tipi numerici primitivi sono impostati su 0.

Tuttavia, i calcoli che coinvolgono tipi a virgola mobile (double e float) possono essere imprecise, quindi di solito è meglio verificare se è vicino-0:

if (Math.abs(foo.x) < 2 * Double.MIN_VALUE) 

È necessario pick a margin of error, che non è semplice.

+0

Non vero solo PRIMITIVE default Il doppio (mentre questo è doppio) sarebbe nullo – Jackie

+0

@Jackie Double non è un tipo numerico. – arshajii

+0

Cosa intendi per tipo numerico? Stai cercando di dire primitivo? – Jackie

1

Sì, è un test valido anche se esiste una conversione implicita da int a double. Per chiarezza/semplicità si dovrebbe usare (foo.x == 0.0) per testare. Ciò ostacolerà gli errori NAN/divisione per zero, ma il doppio valore può in alcuni casi essere molto molto molto vicino a 0, ma non esattamente zero, e quindi il test fallirà (sto parlando in generale ora, non il tuo codice). La divisione di quello darà numeri enormi.

Se questo ha qualcosa a che fare con il denaro, non utilizzare float o double, invece usa BigDecimal.

-3

Il modo più sicuro sarebbe OR bit a bit ing vostro doppio con 0. Guardate questa XORing two doubles in Java

In sostanza si dovrebbe fare if ((Double.doubleToRawLongBits(foo.x) | 0)) (se è veramente 0)

+3

Perché? C'è una ragione! = 0,0 non funzionerebbe? –

+9

Sarei preoccupato per uno sviluppatore Java che verifica zero con un OR bit a bit. – Kayaman

+1

Hmm sembra che stia sbagliando. Quanto sopra mancherebbe zero negativo. '== 0.0' dovrebbe funzionare bene – Anshul

3

In Java, 0 è lo stesso 0.0 e raddoppia il valore predefinito a 0 (sebbene molti consigliano di impostarli sempre esplicitamente per una migliore leggibilità). Ho controllato e foo.x == 0 e foo.x == 0.0 sono entrambi vero se foo.x è zero

+1

Normalmente trovo che impostare una variabile al suo valore predefinito invece di migliorare la leggibilità faccia esattamente l'opposto e diminuisca effettivamente la leggibilità e ingombra il codice. È estraneo e non è necessario. – Michael

-1

un po 'tardi, ma se può aiutare. In realtà, per prima cosa converto in int e confronta con 0.

Double val = 0.0; 
if(Integer.valueOf((String) val) == 0){ ...;} 
Problemi correlati