Jak zaimplementować nieskończoność w Javie?

138

Czy Java ma coś, co reprezentuje nieskończoność dla każdego liczbowego typu danych? Jak to jest zaimplementowane, że mogę na nim wykonywać operacje matematyczne?

Na przykład

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

Próbowałem używać bardzo dużych liczb, ale chcę odpowiedniego, łatwego rozwiązania.

user1753100
źródło
10
istnieje nieskończona liczba nieskończoności, którą chciałbyś wymodelować?
Dave Richardson
11
Dlaczego powinno ∞-∞==0być prawdą? A także: dlaczego potrzebujesz czegoś takiego?
brimborium

Odpowiedzi:

190

double obsługuje 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

wydruki

Infinity
NaN
-Infinity

Uwaga: Infinity - Infinityto nie liczba .

Peter Lawrey
źródło
23
Unikam używania, floatgdy tylko jest to możliwe, ponieważ jego precyzja jest dość niska. ;)
Peter Lawrey
3
Implementacja algorytmów takich jak Dijkstra sprawia, że ​​zastanawiam się, czy POSITIVE_INFINITY <POSITIVE_INFINITY.
Joey Carson
41

Przypuszczam, że nie bez powodu używasz matematyki całkowitej. Jeśli tak, możesz uzyskać wynik, który funkcjonalnie jest prawie taki sam jak POSITIVE_INFINITY, używając pola MAX_VALUE Integerklasy:

Integer myInf = Integer.MAX_VALUE;

(A dla NEGATIVE_INFINITY możesz użyć MIN_VALUE.) Oczywiście będą pewne różnice funkcjonalne, np. W porównaniu myInfz wartością, która przypadkiem wynosi MAX_VALUE: oczywiście ta liczba nie jest mniejsza niż myInf.

Istnieje również biblioteka, która faktycznie ma pola POSITIVE_INFINITY i NEGATIVE_INFINITY, ale tak naprawdę są to tylko nowe nazwy dla MAX_VALUE i MIN_VALUE.

John K.
źródło
11
Ile to Integer.MAX_VALUE + 5?
Erwin Smout,
9
Integer.MAX_VALUE + 5 zawija się do ujemnych liczb całkowitych. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom
Jaka jest różnica między używaniem Integer.MAX_VALUEjako nieskończoności, a nie Double.POSITIVE_INFINITYpowiedziałeś, że są one „prawie takie same funkcjonalnie”, więc jaka jest różnica?
ahitt6345
1
@ ahitt6345 Integer.MAX_VALUEjest nadal skończona, to tylko trik do naśladowania nieskończoności. Ponadto Integer.MAX_VALUEjest tylko 32-bitowy, podczas gdy Double.POSITIVE_INFINITYjest 64-bitowy.
mgthomas99
1
Integer.MAX_VALUE to prawidłowa liczba, której można użyć do wprowadzenia. op poprosił o nieskończoność, która NIE jest liczbą, ale symbolem matematycznym.
refaelio
11

Aby użyć Infinity, możesz użyć, Doublektóre obsługuje 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);

WYJŚCIE : -

Infinity
-Infinity
-Infinity

Infinity 
NaN
Rohit Jain
źródło
5

DoubleI Floattypy mają POSITIVE_INFINITYstałą.

Tudor
źródło
@ user1753100: Domyślnie nie, ale niektóre biblioteki, takie jak ta: jscience.org , najwyraźniej ją implementują.
Tudor
1
Ograniczanie wartości nieskończonych do podwójnych i zmiennoprzecinkowych wydaje się arbitralne. Ich maksymalne wartości są bliższe nieskończoności niż maksymalna wartość liczb całkowitych, ale niewiele bliżej.
Patrick Brinich-Langlois
3
@ PatrickBrinich-Langlois typy zmiennoprzecinkowe (takie jak double i float) są zazwyczaj zdolne do bezpośredniego wyrażania nieskończoności (tj. Istnieje wzorzec bitowy, który konkretnie oznacza „nieskończoność”, różny od maksymalnej wartości typu). Double i Float mają MAX_VALUE, wspólne z Integer.
David Morris
7
„Ich maksymalne wartości są bliżej nieskończoności niż maksymalna wartość liczb całkowitych, ale niewiele bliżej”. Każda liczba skończona jest nieskończonością oddaloną od nieskończoności;)
carlsb3rg
4

Nie jestem pewien, czy Java ma nieskończoność dla każdego typu liczbowego, ale w przypadku niektórych liczbowych typów danych odpowiedź jest twierdząca:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

lub

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Przydatny może się również okazać następujący artykuł, w którym przedstawiono niektóre operacje matematyczne związane z +/- nieskończonością: Zawiłości liczb zmiennoprzecinkowych Java .

Akos K
źródło
4

Tylko typy Double i Float obsługują POSITIVE_INFINITYstałą.

NKM
źródło
2

Dla liczbowych typów opakowań.

np. Double.POSITVE_INFINITY

Mam nadzieję, że to może ci pomóc.

Ankit HTech
źródło
1
Nie dla wszystkich typów opakowań liczbowych. Tylko dla Double i Float.
Erick G. Hagstrom
2

Ogólnym rozwiązaniem jest wprowadzenie nowego typu. Może być bardziej zaangażowany, ale ma tę zaletę, że działa dla każdego typu, który nie definiuje własnej nieskończoności.

Jeśli Tjest to typ, dla którego lteqjest zdefiniowana, można określić InfiniteOr<T>z lteqczymś takim:

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

Tobie pozostawiam przetłumaczenie tego na dokładną składnię Java. Mam nadzieję, że pomysły są jasne; ale mimo wszystko pozwól mi je przeliterować.

Chodzi o to, aby stworzyć nowy typ, który ma wszystkie te same wartości, co jakiś już istniejący typ, plus jedną specjalną wartość, która - o ile możesz to stwierdzić za pomocą metod publicznych - działa dokładnie tak, jak chcesz, aby działała nieskończoność, np. Jest większa niż coś jeszcze. Używam nulltutaj do reprezentowania nieskończoności, ponieważ wydaje się to najprostsze w Javie.

Jeśli chcesz dodać operacje arytmetyczne, zdecyduj, co mają zrobić, a następnie zaimplementuj to. Prawdopodobnie najprościej jest, jeśli najpierw zajmiesz się nieskończonymi przypadkami, a następnie ponownie użyjesz istniejących operacji na skończonych wartościach oryginalnego typu.

Może istnieć ogólny wzorzec wskazujący, czy korzystne jest przyjęcie konwencji traktowania lewostronnych nieskończoności przed prawostronnymi lub odwrotnie; Nie mogę tego stwierdzić bez wypróbowania tego, ale w przypadku mniej niż lub równych ( lteq) myślę, że łatwiej jest najpierw spojrzeć na nieskończoność po prawej stronie. Zauważam, że nielteq jest to przemienne, ale addi mulsą; może to ma znaczenie.

Uwaga: wymyślenie dobrej definicji tego, co powinno się dziać z nieskończonymi wartościami, nie zawsze jest łatwe. Służy do porównywania, dodawania i mnożenia, ale może nie do odejmowania. Istnieje również rozróżnienie między nieskończonymi liczbami głównymi i porządkowymi, na które warto zwrócić uwagę.

Jonas Kölker
źródło
Warto użyć dodatkowego pola wyliczeniowego, aby przedstawić dodatkowe stany, aby można było również mieć ujemną Nieskończoność , co jest często pożądane i sprawia, że -(yourvalue)działa poprawnie. Pozwoliłoby to również na wspieranie koncepcji NaN (nie liczby). Poza tym dodanie specjalnych wartości do typów całkowitych może być dobrym pomysłem, szczególnie gdy aplikacja wymaga semantyki, która jest naruszana przez liczby zmiennoprzecinkowe.
blubberdiblub
0

Ponieważ numer klasy nie jest ostateczny, oto pomysł, którego jeszcze nie znajduję w innych postach. Mianowicie, aby podklasować numer klasy.

W jakiś sposób dostarczyłoby to obiekt, który można traktować jako nieskończoność dla liczb Integer, Long, Double, Float, BigInteger i BigDecimal.

Ponieważ istnieją tylko dwie wartości, możemy użyć wzorca 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;
    }
}

W jakiś sposób uważam, że pozostałe metody intValue (), longValue () itd. Powinny zostać zastąpione, aby zgłosić wyjątki. Aby wartość nieskończoności nie mogła być używana bez dalszych środków ostrożności.

Mostowski Upadek
źródło
0

Jestem początkującym w Javie ... Znalazłem inną implementację nieskończoności w dokumentacji Java dla typów booleani double. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Dodatnie zero i ujemne zero porównują równe; zatem wynik wyrażenia 0,0 == - 0,0 jest prawdą, a wynik 0,0> -0,0 jest fałszem. Ale inne operacje mogą rozróżnić dodatnie i ujemne zero; na przykład 1,0 / 0,0 ma wartość dodatnią nieskończoność, podczas gdy wartość 1,0 / -0,0 jest ujemną nieskończonością.

Wygląda brzydko, ale działa.

public class Main {

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

}
Kislik
źródło