¿Cómo implementar el infinito en Java?

139

¿Java tiene algo que represente el infinito para cada tipo de datos numéricos? ¿Cómo se implementa de modo que pueda realizar operaciones matemáticas con él?

P.ej

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

He intentado usar números muy grandes, pero quiero una solución adecuada y fácil .

usuario1753100
fuente
10
hay un número infinito de infinitos, ¿cuál te gustaría modelar?
Dave Richardson
11
¿Por qué debería ∞-∞==0ser verdad? Y también: ¿Por qué necesitas tal cosa?
Brimborium

Respuestas:

190

double soporta 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

huellas dactilares

Infinity
NaN
-Infinity

nota: noInfinity - Infinity es un número .

Peter Lawrey
fuente
23
Evito usarlo floatsiempre que sea posible ya que su precisión es bastante pobre. ;)
Peter Lawrey
3
La implementación de algoritmos como Dijkstra me hace cuestionar si POSITIVE_INFINITY <POSITIVE_INFINITY o no.
Joey Carson el
41

Supongo que estás usando matemáticas enteras por una razón. Si es así, puede obtener un resultado funcionalmente similar al POSITIVE_INFINITY utilizando el campo MAX_VALUE de la Integerclase:

Integer myInf = Integer.MAX_VALUE;

(Y para NEGATIVE_INFINITY, podría usar MIN_VALUE.) Por supuesto, habrá algunas diferencias funcionales, por ejemplo, cuando se compara myInfcon un valor que resulta ser MAX_VALUE: claramente este número no es menor que myInf.

También hay una biblioteca que en realidad tiene campos POSITIVE_INFINITY y NEGATIVE_INFINITY, pero en realidad son nombres nuevos para MAX_VALUE y MIN_VALUE.

JohnK
fuente
11
¿Cuánto es Integer.MAX_VALUE + 5?
Erwin Smout
9
Integer.MAX_VALUE + 5 se envuelve en los enteros negativos. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom
¿Cuál es la diferencia entre usar Integer.MAX_VALUEcomo infinito en lugar de Double.POSITIVE_INFINITYdecir que son 'funcionalmente casi iguales', entonces cuál es la diferencia?
ahitt6345
1
@ ahitt6345 Integer.MAX_VALUEtodavía es finito, es solo un truco para imitar el infinito. Además, Integer.MAX_VALUEsolo tiene 32 bits, mientras que Double.POSITIVE_INFINITYes de 64 bits.
mgthomas99
1
Integer.MAX_VALUE es un número válido que se puede usar en su entrada. op pidió infinito, que NO es un número, sino un símbolo matemático.
refaelio
11

Para usar Infinity, puede usar Doublequé soportes 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);

SALIDA : -

Infinity
-Infinity
-Infinity

Infinity 
NaN
Rohit Jain
fuente
5

Los tipos Doubley Floattienen la POSITIVE_INFINITYconstante.

Tudor
fuente
@ user1753100: Por defecto no, pero algunas bibliotecas, como esta: jscience.org aparentemente lo implementan.
Tudor
1
Parece arbitrario restringir valores infinitos a Dobles y Flotadores. Sus valores máximos están más cerca del infinito que el valor máximo de los enteros, pero no mucho más cerca.
Patrick Brinich-Langlois
3
@ PatrickBrinich-Langlois los tipos de punto flotante (como doble y flotante) suelen ser capaces de expresar directamente el infinito (es decir, hay un patrón de bits que significa específicamente 'infinito', distinto del valor máximo del tipo). Double y Float tienen MAX_VALUE, en común con Integer.
David Morris el
77
"Sus valores máximos están más cerca del infinito que el valor máximo de los enteros, pero no mucho más cerca". Cualquier número finito está infinito lejos del infinito;)
carlsb3rg
4

No estoy seguro de que Java tenga infinito para cada tipo numérico, pero para algunos tipos de datos numéricos la respuesta es positiva:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

o

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

También puede resultarle útil el siguiente artículo, que representa algunas operaciones matemáticas que involucran +/- infinito: complejidades de números de punto flotante de Java .

Akos K
fuente
4

Solo el tipo Double y Float admite POSITIVE_INFINITYconstante.

NKM
fuente
2

Para los tipos de envoltorio numérico.

por ejemplo, Double.POSITVE_INFINITY

Espero que esto te pueda ayudar.

Ankit HTech
fuente
1
No para todos los tipos de envoltorios numéricos. Solo para doble y flotante.
Erick G. Hagstrom
2

Una solución genérica es introducir un nuevo tipo. Puede estar más involucrado, pero tiene la ventaja de trabajar para cualquier tipo que no defina su propio infinito.

Si Tes un tipo para el que lteqestá definido, puede definirlo InfiniteOr<T>con lteqalgo como esto:

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

Dejaré que traduzca esto a la sintaxis exacta de Java. Espero que las ideas sean claras; pero déjame deletrearlos de todos modos.

La idea es crear un nuevo tipo que tenga todos los mismos valores que algunos tipos ya existentes, más un valor especial que, por lo que puede ver a través de métodos públicos, actúa exactamente de la manera en que desea que actúe el infinito, por ejemplo, es mayor que Algo más. Estoy usando nullpara representar el infinito aquí, ya que eso parece lo más sencillo en Java.

Si desea agregar operaciones aritméticas, decida qué deben hacer, luego implemente eso. Probablemente sea más simple si maneja los casos infinitos primero y luego reutiliza las operaciones existentes en valores finitos del tipo original.

Puede haber o no un patrón general para determinar si es beneficioso o no adoptar una convención para manejar los infinitos del lado izquierdo antes que los infinitos del lado derecho o viceversa; No puedo decirlo sin probarlo, pero para menos que o igual ( lteq) creo que es más simple mirar primero el infinito del lado derecho. Tomo nota de que lteqes no conmutativo, pero addy mulson; Quizás eso sea relevante.

Nota: proponer una buena definición de lo que debería suceder en valores infinitos no siempre es fácil. Es para comparación, suma y multiplicación, pero tal vez no para resta. Además, hay una distinción entre los números cardinales y ordinales infinitos a los que puede prestar atención.

Jonas Kölker
fuente
Puede valer la pena usar un campo de enumeración adicional para representar los estados adicionales, por lo que también puede tener Infinito negativo , que a menudo es deseable y hace que -(yourvalue)funcione correctamente. Y eso también le permitiría apoyar el concepto NaN (no un número). Aparte de eso, agregar valores especiales sobre los tipos integrales puede ser una buena idea, particularmente cuando la aplicación necesita semánticas que son violadas por números de punto flotante.
blubberdiblub
0

Como el número de clase no es definitivo, aquí hay una idea que aún no encuentro en las otras publicaciones. A saber, subclasificar el número de clase.

Esto de alguna manera entregaría un objeto que puede ser tratado como infinito para Integer, Long, Double, Float, BigInteger y BigDecimal.

Como solo hay dos valores, podríamos usar el patrón 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;
    }
}

De alguna manera, creo que los métodos restantes intValue (), longValue () etc. deberían ser anulados para arrojar excepciones. Para que el valor de infinito no se pueda usar sin más precauciones.

Colapso de Mostowski
fuente
0

Soy un principiante en Java ... Encontré otra implementación para el infinito en la documentación de Java, para los tipos booleany double. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

El cero positivo y el cero negativo se comparan igual; así, el resultado de la expresión 0.0 == - 0.0 es verdadero y el resultado de 0.0> -0.0 es falso. Pero otras operaciones pueden distinguir cero positivo y cero; por ejemplo, 1.0 / 0.0 tiene el valor infinito positivo, mientras que el valor de 1.0 / -0.0 es infinito negativo.

Se ve feo, pero funciona.

public class Main {

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

}
Kislik
fuente