Wie implementiere ich Infinity in Java?


138

Hat Java für jeden numerischen Datentyp etwas, das Unendlichkeit darstellt? Wie ist es so implementiert, dass ich damit mathematische Operationen ausführen kann?

Z.B

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

Ich habe versucht, sehr große Zahlen zu verwenden, aber ich möchte eine richtige, einfache Lösung.


10
Es gibt unendlich viele Unendlichkeiten, welche möchten Sie modellieren?
Dave Richardson

11
Warum sollte ∞-∞==0das wahr sein? Und auch: Warum brauchst du so etwas?
Brimborium

Antworten:


190

double unterstützt 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

druckt

Infinity
NaN
-Infinity

Hinweis: Infinity - Infinityist keine Nummer .


23
Ich vermeide es, floatwann immer möglich zu verwenden, da seine Präzision ziemlich schlecht ist. ;)
Peter Lawrey

3
Durch die Implementierung von Algorithmen wie Dijkstra frage ich mich, ob POSITIVE_INFINITY <POSITIVE_INFINITY.
Joey Carson

41

Ich nehme an, Sie verwenden aus einem bestimmten Grund ganzzahlige Mathematik. In diesem Fall können Sie mithilfe des Felds MAX_VALUE der IntegerKlasse ein Ergebnis erhalten, das funktional nahezu dem von POSITIVE_INFINITY entspricht :

Integer myInf = Integer.MAX_VALUE;

(Und für NEGATIVE_INFINITY können Sie MIN_VALUE verwenden.) Natürlich gibt es einige funktionale Unterschiede, z. B. beim Vergleich myInfmit einem Wert, der zufällig MAX_VALUE ist: Diese Zahl ist eindeutig nicht kleiner als myInf.

Es gibt auch eine Bibliothek mit den Feldern POSITIVE_INFINITY und NEGATIVE_INFINITY, aber es handelt sich eigentlich nur um neue Namen für MAX_VALUE und MIN_VALUE.


11
Wie viel kostet Integer.MAX_VALUE + 5?
Erwin Smout

9
Integer.MAX_VALUE + 5 wird in die negativen Ganzzahlen umgebrochen. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom

Was ist der Unterschied zwischen der Verwendung Integer.MAX_VALUEals Unendlichkeit und nicht der Double.POSITIVE_INFINITYAussage, dass sie "funktional nahezu gleich" sind? Was ist also der Unterschied?
ahitt6345

1
@ ahitt6345 Integer.MAX_VALUEist immer noch endlich, es ist nur ein Hack, um die Unendlichkeit nachzuahmen. Darüber hinaus Integer.MAX_VALUEist nur 32-Bit, während Double.POSITIVE_INFINITY64-Bit ist.
mgthomas99

1
Integer.MAX_VALUE ist eine gültige Zahl, die in Ihrer Eingabe verwendet werden kann. op fragte nach unendlich, was KEINE Zahl ist, sondern ein mathematisches Symbol.
Refaelio

11

Zur Verwendung Infinitykönnen Sie verwenden Für Doublewelche unterstützt 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);

AUSGABE : -

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

Die Doubleund FloatTypen haben die POSITIVE_INFINITYKonstante.


@ user1753100: Standardmäßig nein, aber einige Bibliotheken, wie diese: jscience.org implementieren es anscheinend.
Tudor

1
Es erscheint willkürlich, unendliche Werte auf Doubles und Floats zu beschränken. Ihre Maximalwerte sind näher an der Unendlichkeit als der Maximalwert von Ganzzahlen, aber nicht viel näher.
Patrick Brinich-Langlois

3
@ PatrickBrinich-Langlois Gleitkommatypen (wie Double und Float) können normalerweise unendlich direkt ausdrücken (dh es gibt ein Bitmuster, das speziell "Unendlichkeit" bedeutet und sich vom Maximalwert des Typs unterscheidet). Double und Float haben MAX_VALUE gemeinsam mit Integer.
David Morris

7
"Ihre Maximalwerte sind näher an der Unendlichkeit als der Maximalwert von Ganzzahlen, aber nicht viel näher." Jede endliche Zahl ist unendlich von unendlich entfernt;)
carlsb3rg

4

Ich bin nicht sicher, ob Java für jeden numerischen Typ unendlich ist, aber für einige numerische Datentypen ist die Antwort positiv:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

oder

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Außerdem kann der folgende Artikel nützlich sein, der einige mathematische Operationen mit +/- unendlich darstellt: Java-Gleitkommazahlen-Komplikationen .


4

Nur Double- und Float-Unterstützungskonstanten POSITIVE_INFINITY.


2

Für die numerischen Wrapper-Typen.

zB Double.POSITVE_INFINITY

Hoffe das könnte dir helfen.


1
Nicht für alle numerischen Wrapper-Typen. Nur für Double und Float.
Erick G. Hagstrom

2

Eine generische Lösung besteht darin, einen neuen Typ einzuführen. Es mag komplizierter sein, aber es hat den Vorteil, für jeden Typ zu arbeiten, der seine eigene Unendlichkeit nicht definiert.

Wenn Tein Typ , für die lteqdefiniert ist, können Sie festlegen , InfiniteOr<T>mit lteqetwas wie folgt aus :

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())

Ich überlasse es Ihnen, dies in die exakte Java-Syntax zu übersetzen. Ich hoffe, die Ideen sind klar; aber lassen Sie mich sie trotzdem buchstabieren.

Die Idee ist, einen neuen Typ zu erstellen, der dieselben Werte wie ein bereits vorhandener Typ hat, sowie einen speziellen Wert, der - soweit Sie dies mit öffentlichen Methoden erkennen können - genau so wirkt, wie Sie möchten, dass die Unendlichkeit wirkt, z. B. größer als noch etwas. Ich verwende hier nulldie Darstellung der Unendlichkeit, da dies in Java am einfachsten erscheint.

Wenn Sie arithmetische Operationen hinzufügen möchten, entscheiden Sie, was sie tun sollen, und implementieren Sie diese. Es ist wahrscheinlich am einfachsten, wenn Sie zuerst die unendlichen Fälle behandeln und dann die vorhandenen Operationen für endliche Werte des ursprünglichen Typs wiederverwenden.

Es kann ein allgemeines Muster geben oder nicht, ob es vorteilhaft ist, eine Konvention zum Umgang mit Unendlichkeiten auf der linken Seite vor Unendlichkeiten auf der rechten Seite oder umgekehrt anzuwenden. Ich kann es nicht sagen, ohne es auszuprobieren, aber für weniger als oder gleich ( lteq) denke ich, dass es einfacher ist, zuerst die Unendlichkeit auf der rechten Seite zu betrachten. Ich stelle fest, dass lteqdas nicht kommutativ ist, sondern addund mulsind; Vielleicht ist das relevant.

Hinweis: Es ist nicht immer einfach, eine gute Definition für unendliche Werte zu finden. Es dient zum Vergleich, zur Addition und Multiplikation, aber möglicherweise nicht zur Subtraktion. Außerdem wird zwischen unendlichen Kardinal- und Ordnungszahlen unterschieden, auf die Sie möglicherweise achten möchten.


Es kann sinnvoll sein, ein zusätzliches Aufzählungsfeld zu verwenden, um die zusätzlichen Zustände darzustellen, sodass Sie auch eine negative Unendlichkeit haben können , was häufig wünschenswert ist und die -(yourvalue)ordnungsgemäße Arbeit ermöglicht. Und das würde es Ihnen auch ermöglichen, das NaN- Konzept (keine Zahl) zu unterstützen. Abgesehen davon kann das Hinzufügen spezieller Werte zu integralen Typen eine gute Idee sein, insbesondere wenn die Anwendung eine Semantik benötigt, die durch Gleitkommazahlen verletzt wird.
Blubberdiblub

0

Da die Klassennummer nicht endgültig ist, ist hier eine Idee, die ich in den anderen Beiträgen noch nicht finde. Nämlich um die Klassennummer zu unterklassifizieren.

Dies würde irgendwie ein Objekt liefern, das für Integer, Long, Double, Float, BigInteger und BigDecimal als unendlich behandelt werden kann.

Da es nur zwei Werte gibt, können wir das Singleton-Muster verwenden:

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;
    }
}

Irgendwie denke ich, dass die verbleibenden Methoden intValue (), longValue () usw. dann überschrieben werden sollten, um Ausnahmen auszulösen. Damit kann der Unendlichkeitswert nicht ohne weitere Vorsichtsmaßnahmen verwendet werden.


0

Ich bin ein Anfänger in Java ... Ich habe eine andere Implementierung für die Unendlichkeit in der Java-Dokumentation gefunden, für die booleanund doubleTypen. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Positive Null und negative Null sind gleich; somit ist das Ergebnis des Ausdrucks 0.0 == - 0.0 wahr und das Ergebnis von 0.0> -0.0 ist falsch. Andere Operationen können jedoch positive und negative Nullen unterscheiden. Beispielsweise hat 1,0 / 0,0 den Wert positiv unendlich, während der Wert 1,0 / -0,0 negativ unendlich ist.

Es sieht hässlich aus, aber es funktioniert.

public class Main {

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

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.