Comment implémenter l'infini en Java?


139

Java a-t-il quelque chose pour représenter l'infini pour chaque type de données numériques? Comment est-il mis en œuvre pour que je puisse faire des opérations mathématiques avec?

Par exemple

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

J'ai essayé d'utiliser de très grands nombres, mais je veux une solution appropriée et simple .


10
il y a un nombre infini d'infinis, lequel aimeriez-vous modéliser?
Dave Richardson

11
Pourquoi devrait-il ∞-∞==0être vrai? Et aussi: pourquoi avez-vous besoin d'une telle chose?
brimborium

Réponses:


190

double prend en charge 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

impressions

Infinity
NaN
-Infinity

Remarque: Infinity - Infinityn'est pas un nombre .


23
J'évite d'utiliser floatautant que possible car sa précision est assez médiocre. ;)
Peter Lawrey

3
La mise en œuvre d'algorithmes comme Dijkstra me fait me demander si POSITIVE_INFINITY <POSITIVE_INFINITY.
Joey Carson

41

Je suppose que vous utilisez le calcul des nombres entiers pour une raison. Si tel est le cas, vous pouvez obtenir un résultat fonctionnellement presque identique à POSITIVE_INFINITY en utilisant le champ MAX_VALUE de la Integerclasse:

Integer myInf = Integer.MAX_VALUE;

(Et pour NEGATIVE_INFINITY, vous pouvez utiliser MIN_VALUE.) Il y aura bien sûr des différences fonctionnelles, par exemple, lors de la comparaison myInfavec une valeur qui se trouve être MAX_VALUE: clairement ce nombre n'est pas inférieur à myInf.

Il existe également une bibliothèque qui contient en fait les champs POSITIVE_INFINITY et NEGATIVE_INFINITY, mais ce ne sont en réalité que de nouveaux noms pour MAX_VALUE et MIN_VALUE.


11
Combien vaut Integer.MAX_VALUE + 5?
Erwin Smout

9
Integer.MAX_VALUE + 5 s'enroule dans les entiers négatifs. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Erick G.Hagstrom

Quelle est la différence entre l'utilisation Integer.MAX_VALUEde l'infini plutôt que de Double.POSITIVE_INFINITYdire qu'ils sont «fonctionnellement presque identiques», alors quelle est la différence?
ahitt6345 le

1
@ ahitt6345 Integer.MAX_VALUEest toujours fini, c'est juste un hack pour imiter l'infini. De plus, Integer.MAX_VALUEc'est seulement 32 bits alors que Double.POSITIVE_INFINITYc'est 64 bits.
mgthomas99

1
Integer.MAX_VALUE est un nombre valide qui peut être utilisé dans votre entrée. op a demandé l'infini, qui n'est PAS un nombre, mais un symbole mathématique.
refaelio

11

Pour l'utiliser Infinity, vous pouvez utiliser Doublequels supports 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);

SORTIE : -

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

Les types Doubleet Floatont la POSITIVE_INFINITYconstante.


@ user1753100: Par défaut non, mais certaines bibliothèques, comme celle-ci: jscience.org l' implémentent apparemment.
Tudor

1
Il semble arbitraire de limiter les valeurs infinies aux doubles et aux flottants. Leurs valeurs maximales sont plus proches de l'infini que la valeur maximale des nombres entiers, mais pas beaucoup plus proches.
Patrick Brinich-Langlois

3
@ Les types à virgule flottante PatrickBrinich-Langlois (tels que double et float) sont généralement capables d'exprimer directement l'infini (c'est-à-dire qu'il existe un motif de bits qui signifie spécifiquement «infini», distinct de la valeur maximale du type). Double et Float ont MAX_VALUE, en commun avec Integer.
David Morris

7
"Leurs valeurs maximales sont plus proches de l'infini que la valeur maximale des nombres entiers, mais pas beaucoup plus proches.". Tout nombre fini est à l'infini loin de l'infini;)
carlsb3rg

4

Je ne suis pas sûr que Java ait l'infini pour chaque type numérique, mais pour certains types de données numériques, la réponse est positive:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

ou

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Vous pouvez également trouver utile l'article suivant qui représente certaines opérations mathématiques impliquant +/- infini: Intricacités de nombres à virgule flottante Java .


4

Seuls les types Double et Float prennent POSITIVE_INFINITYen charge la constante.


2

Pour les types d'encapsuleurs numériques.

par exemple Double.POSITVE_INFINITY

J'espère que cela pourrait vous aider.


1
Pas pour tous les types d'encapsuleurs numériques. Juste pour Double et Float.
Erick G.Hagstrom

2

Une solution générique consiste à introduire un nouveau type. Il est peut-être plus compliqué, mais il a l'avantage de fonctionner pour tout type qui ne définit pas sa propre infinité.

Si Test un type pour lequel lteqest défini, vous pouvez définir InfiniteOr<T>avec lteqquelque chose comme ceci:

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

Je vous laisse le soin de traduire cela dans la syntaxe Java exacte. J'espère que les idées sont claires; mais laissez-moi les épeler de toute façon.

L'idée est de créer un nouveau type qui a toutes les mêmes valeurs que certains types déjà existants, plus une valeur spéciale qui - pour autant que vous puissiez en juger par les méthodes publiques - agit exactement comme vous voulez que l'infini agisse, par exemple, il est supérieur à rien d'autre. J'utilise nullpour représenter l'infini ici, car cela semble le plus simple en Java.

Si vous souhaitez ajouter des opérations arithmétiques, décidez de ce qu'elles doivent faire, puis implémentez-la. C'est probablement plus simple si vous gérez d'abord les cas infinis, puis réutilisez les opérations existantes sur des valeurs finies du type d'origine.

Il pourrait ou non y avoir un modèle général pour savoir s'il est avantageux ou non d'adopter une convention de gestion des infinis de gauche avant les infinis de droite ou vice versa; Je ne peux pas dire sans l'essayer, mais pour moins que ou égal ( lteq), je pense qu'il est plus simple de regarder d'abord l'infini de droite. Je note que ce lteqn'est pas commutatif, mais addet mulsont; c'est peut-être pertinent.

Remarque: trouver une bonne définition de ce qui doit se passer sur des valeurs infinies n'est pas toujours facile. C'est pour la comparaison, l'addition et la multiplication, mais peut-être pas la soustraction. En outre, il existe une distinction entre les nombres cardinaux et ordinaux infinis auxquels vous voudrez peut-être faire attention.


Il peut être intéressant d'utiliser un champ d'énumération supplémentaire afin de représenter les états supplémentaires, de sorte que vous puissiez également avoir une infinité négative , ce qui est souvent souhaitable et -(yourvalue)fonctionne correctement. Et cela vous permettrait également de prendre en charge le concept NaN (pas un nombre). En dehors de cela, ajouter des valeurs spéciales au-dessus des types intégraux peut être une bonne idée, en particulier lorsque l'application a besoin d'une sémantique violée par des nombres à virgule flottante.
blubberdiblub

0

Puisque la classe Number n'est pas définitive, voici une idée, que je ne trouve pas encore dans les autres articles. À savoir pour sous-classer la classe Number.

Cela fournirait en quelque sorte un objet qui peut être traité comme l'infini pour Integer, Long, Double, Float, BigInteger et BigDecimal.

Comme il n'y a que deux valeurs, nous pourrions utiliser le modèle 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;
    }
}

D'une manière ou d'une autre, je pense que les méthodes restantes intValue (), longValue () etc. devraient alors être surchargées pour lancer des exceptions. De sorte que la valeur infinie ne peut être utilisée sans précautions supplémentaires.


0

Je suis un débutant en Java ... J'ai trouvé une autre implémentation pour l'infini dans la documentation Java, pour les types booleanet double. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Le zéro positif et le zéro négatif sont égaux; ainsi le résultat de l'expression 0.0 == - 0.0 est vrai et le résultat de 0.0> -0.0 est faux. Mais d'autres opérations peuvent distinguer zéro positif et négatif; par exemple, 1.0 / 0.0 a la valeur infini positif, tandis que la valeur 1.0 / -0.0 est l'infini négatif.

Ça a l'air moche, mais ça marche.

public class Main {

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

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.