Come implementare l'infinito in Java?


139

Java ha qualcosa per rappresentare l'infinito per ogni tipo di dato numerico? Come viene implementato in modo tale da poter eseguire operazioni matematiche con esso?

Per esempio

int myInf = infinity; //However it is done
myInf + 5; //returns infinity
myInf*(-1); //returns negative infinity

Ho provato a usare numeri molto grandi, ma voglio una soluzione semplice e adeguata .


10
ci sono un numero infinito di infiniti, quale vorresti modellare?
Dave Richardson,

11
Perché dovrebbe ∞-∞==0essere vero? E anche: perché hai bisogno di una cosa del genere?
Brimborium,

Risposte:


190

double supporta Infinity

double inf = Double.POSITIVE_INFINITY;
System.out.println(inf + 5);
System.out.println(inf - inf); // same as Double.NaN
System.out.println(inf * -1); // same as Double.NEGATIVE_INFINITY

stampe

Infinity
NaN
-Infinity

nota: nonInfinity - Infinity è un numero .


23
Evito di usarlo floatquando possibile poiché la sua precisione è piuttosto scarsa. ;)
Peter Lawrey,

3
L'implementazione di algoritmi come Dijkstra mi fa dubitare che POSITIVE_INFINITY <POSITIVE_INFINITY.
Joey Carson,

41

Suppongo che tu stia usando la matematica dei numeri interi per un motivo. In tal caso, puoi ottenere un risultato funzionalmente quasi uguale a POSITIVE_INFINITY utilizzando il campo MAX_VALUE della Integerclasse:

Integer myInf = Integer.MAX_VALUE;

(E per NEGATIVE_INFINITY potresti usare MIN_VALUE.) Ci saranno ovviamente alcune differenze funzionali, ad esempio, quando si confronta myInfcon un valore che è MAX_VALUE: chiaramente questo numero non è inferiore a myInf.

C'è anche una libreria che in realtà ha i campi POSITIVE_INFINITY e NEGATIVE_INFINITY, ma in realtà sono solo nuovi nomi per MAX_VALUE e MIN_VALUE.


11
Quanto costa Integer.MAX_VALUE + 5?
Erwin Smout,

9
Integer.MAX_VALUE + 5 si avvolge negli interi negativi. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom, l'

Qual è la differenza tra usare Integer.MAX_VALUEcome infinito piuttosto che Double.POSITIVE_INFINITYhai detto che sono "funzionalmente quasi uguali", quindi qual è la differenza?
ahitt6345,

1
@ ahitt6345 Integer.MAX_VALUEè ancora finito, è solo un trucco per imitare l'infinito. Inoltre, Integer.MAX_VALUEè solo a 32 bit mentre Double.POSITIVE_INFINITYè a 64 bit.
mgthomas99

1
Integer.MAX_VALUE è un numero valido che può essere utilizzato nel tuo input. op ha chiesto l'infinito, che NON è un numero, ma un simbolo matematico.
refaelio,

11

Per utilizzare Infinity, è possibile utilizzare Doublequali supporti Infinity: -

    System.out.println(Double.POSITIVE_INFINITY);
    System.out.println(Double.POSITIVE_INFINITY * -1);
    System.out.println(Double.NEGATIVE_INFINITY);

    System.out.println(Double.POSITIVE_INFINITY - Double.NEGATIVE_INFINITY);
    System.out.println(Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY);

USCITA : -

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

I tipi Doublee Floathanno la POSITIVE_INFINITYcostante.


@ user1753100: per impostazione predefinita no, ma alcune librerie, come questa: jscience.org lo implementano apparentemente.
Tudor,

1
Sembra arbitrario limitare i valori infiniti a Doubles e Float. I loro valori massimi sono più vicini all'infinito rispetto al valore massimo di Integer, ma non molto più vicini.
Patrick Brinich-Langlois,

3
I tipi a virgola mobile di @ PatrickBrinich-Langlois (come double e float) sono in genere in grado di esprimere direttamente l'infinito (ovvero, esiste un modello di bit che significa specificamente "infinito", distinto dal valore massimo del tipo). Double e Float hanno MAX_VALUE, in comune con Integer.
David Morris,

7
"I loro valori massimi sono più vicini all'infinito rispetto al valore massimo di Integer, ma non molto più vicini.". Qualsiasi numero finito è infinito lontano dall'infinito;)
carlsb3rg

4

Non sono sicuro che Java abbia infinito per ogni tipo numerico ma per alcuni tipi di dati numerici la risposta è positiva:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

o

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Inoltre, potresti trovare utile il seguente articolo che rappresenta alcune operazioni matematiche che coinvolgono +/- infinito: Java complessità in virgola mobile .


4

Solo la POSITIVE_INFINITYcostante di supporto di tipo Double e Float .


2

Per i tipi di wrapper numerici.

ad es. Double.POSITVE_INFINITY

Spero che questo possa aiutarti.


1
Non per tutti i tipi di wrapper numerici. Solo per Double e Float.
Erick G. Hagstrom, l'

2

Una soluzione generica consiste nell'introdurre un nuovo tipo. Può essere più coinvolto, ma ha il vantaggio di lavorare per qualsiasi tipo che non definisce il proprio infinito.

Se Tè un tipo per il quale lteqè definito, è possibile definire InfiniteOr<T>con lteqqualcosa del genere:

class InfiniteOr with type parameter T:
    field the_T of type null-or-an-actual-T
    isInfinite()
        return this.the_T == null
    getFinite():
        assert(!isInfinite());
        return this.the_T
    lteq(that)
        if that.isInfinite()
            return true
        if this.isInfinite()
            return false
        return this.getFinite().lteq(that.getFinite())

Lascio a te tradurre questo per l'esatta sintassi Java. Spero che le idee siano chiare; ma lasciami precisare comunque.

L'idea è di creare un nuovo tipo che abbia tutti gli stessi valori di un tipo già esistente, oltre a un valore speciale che, per quanto si può dire attraverso metodi pubblici, agisce esattamente come si desidera che l'infinito agisca, ad esempio è maggiore di qualunque altra cosa. Sto usando nullper rappresentare l'infinito qui, dal momento che sembra il più semplice in Java.

Se si desidera aggiungere operazioni aritmetiche, decidere cosa devono fare, quindi implementarlo. Probabilmente è più semplice se prima gestisci gli infiniti casi, quindi riutilizza le operazioni esistenti su valori finiti del tipo originale.

Potrebbe esserci o meno un modello generale per stabilire se sia utile o meno adottare una convenzione di gestione degli infiniti sul lato sinistro prima degli infiniti sul lato destro o viceversa; Non posso dirlo senza provarlo, ma per meno-o-uguale ( lteq) penso che sia più semplice guardare prima l'infinito sul lato destro. Noto che nonlteq è commutativo, ma e lo è; forse è rilevante.addmul

Nota: trovare una buona definizione di ciò che dovrebbe accadere su valori infiniti non è sempre facile. È per confronto, addizione e moltiplicazione, ma forse non per sottrazione. Inoltre, esiste una distinzione tra infiniti numeri cardinali e ordinali ai quali potresti voler prestare attenzione.


Potrebbe essere utile utilizzare un campo enum extra per rappresentare gli stati aggiuntivi, in modo da poter avere anche Infinity negativo , che è spesso desiderabile e fa -(yourvalue)funzionare correttamente. E ciò consentirebbe anche di supportare il concetto NaN (non un numero). A parte questo, aggiungere valori speciali in cima ai tipi integrali può essere una buona idea, in particolare quando l'applicazione necessita di semantiche violate da numeri in virgola mobile.
Blubberdiblub,

0

Poiché il numero di classe non è definitivo, ecco un'idea che non trovo ancora negli altri post. Vale a dire la sottoclasse della classe Numero.

Ciò fornirebbe in qualche modo un oggetto che può essere trattato come infinito per Integer, Long, Double, Float, BigInteger e BigDecimal.

Poiché esistono solo due valori, è possibile utilizzare il modello singleton:

public final class Infinity extends Number {
    public final static Infinity POSITIVE = new Infinity(false);
    public final static Infinity NEGATIVE = new Infinity(true);
    private boolean negative;
    private Infinity(boolean n) {
        negative = n;
    }
}

In qualche modo penso che i restanti metodi intValue (), longValue () ecc. Dovrebbero quindi essere sostituiti per generare eccezioni. In modo che il valore di infinito non possa essere utilizzato senza ulteriori precauzioni.


0

Sono un principiante in Java ... Ho trovato un'altra implementazione per l'infinito nella documentazione Java, per i tipi booleane double. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Lo zero positivo e lo zero negativo sono uguali; quindi il risultato dell'espressione 0,0 == - 0,0 è vero e il risultato di 0,0> -0,0 è falso. Ma altre operazioni possono distinguere zero positivo e zero; ad esempio, 1.0 / 0.0 ha il valore infinito positivo, mentre il valore di 1.0 / -0.0 è l'infinito negativo.

Sembra brutto, ma funziona.

public class Main {

    public static void main(String[] args) {
        System.out.println(1.0/0.0);
        System.out.println(-1.0/0.0);
    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.