Est-ce que Java a quelque chose à représenter l'infini pour chaque type de données numérique? Comment est-il implémenté de telle sorte 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 correcte, facile.
double
supporte 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
empreintes
Infinity
NaN
-Infinity
remarque: Infinity - Infinity
est pas un nombre.
Je suppose que vous utilisez un calcul mathématique entier pour une raison. Si tel est le cas, vous pouvez obtenir un résultat pratiquement identique à POSITIVE_INFINITY en utilisant le champ MAX_VALUE de la classe Integer
:
Integer myInf = Integer.MAX_VALUE;
(Et pour NEGATIVE_INFINITY, vous pouvez utiliser MIN_VALUE.) Il y aura bien sûr quelques différences fonctionnelles, par exemple, lorsque l'on compare myInf
à une valeur MAX_VALUE: ce nombre n'est évidemment pas inférieur à myInf
.
Il y a aussi ne 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.
Pour utiliser Infinity
, vous pouvez utiliser Double
qui prend en charge 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);
OUTPUT: -
Infinity
-Infinity
-Infinity
Infinity
NaN
Les types Double
et Float
ont la constante POSITIVE_INFINITY
.
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 quelques opérations mathématiques impliquant +/- infini: Intricacies de nombres en virgule flottante Java .
Seuls les types Double et Float prennent en charge POSITIVE_INFINITY
constante.
Pour les types de wrapper numériques.
par exemple, Double.POSITVE_INFINITY
J'espère que cela pourrait vous aider.
Une solution générique consiste à introduire un nouveau type. Il est peut-être plus impliqué, mais il a l’avantage de fonctionner pour tout type qui ne définit pas son propre infini.
Si T
est un type pour lequel lteq
est défini, vous pouvez définir InfiniteOr<T>
avec lteq
à peu près 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 avec la syntaxe exacte Java. J'espère que les idées sont claires. mais laissez-moi les épeler quand même.
L'idée est de créer un nouveau type qui a toutes les mêmes valeurs qu'un type déjà existant, plus une valeur spéciale qui, autant que vous puissiez le savoir à l'aide de méthodes publiques, agit exactement de la manière dont vous souhaitez que l'infini agisse, par exemple. c'est plus que toute autre chose. J'utilise null
pour représenter l'infini ici, car cela semble le plus simple en Java.
Si vous souhaitez ajouter des opérations arithmétiques, décidez ce qu'elles doivent faire, puis implémentez-les. 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 peut y avoir ou non une tendance générale à décider s'il est avantageux ou non d'adopter une convention de traitement des infinis du côté gauche avant les infinis du côté droit ou inversement; Je ne saurais le dire sans l'essayer, mais pour des valeurs inférieures ou égales (lteq
), je pense qu'il est plus simple de commencer par regarder l'infini du côté droit. Je remarque que lteq
est pas commutatif, mais add
et mul
sont; c'est peut-être pertinent.
Remarque: il n'est pas toujours facile de définir avec exactitude ce qui devrait se passer pour des valeurs infinies. C'est pour la comparaison, l'addition et la multiplication, mais peut-être pas la soustraction. En outre, il existe une distinction entre nombres cardinaux et ordinaux infinis auxquels vous voudrez peut-être faire attention.
Comme le numéro de classe n'est pas définitif, voici une idée que je ne trouve pas encore dans les autres articles. À savoir sous-classer le numéro de classe.
Cela fournirait en quelque sorte un objet qui peut être traité comme un 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;
}
}
En quelque sorte, je pense que les méthodes restantes intValue (), longValue (), etc., devraient alors être remplacées pour générer une exception. Ainsi, la valeur de l'infini ne peut pas être utilisée sans précautions supplémentaires.