Como implementar o infinito em Java?


138

Java tem algo para representar o infinito para cada tipo de dado numérico? Como é implementado para que eu possa fazer operações matemáticas com ele?

Por exemplo

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

Tentei usar números muito grandes, mas quero uma solução adequada e fácil .


10
há um número infinito de infinitos, qual deles você gostaria de modelar?
18712 Dave

11
Por que deveria ∞-∞==0ser verdade? E também: Por que você precisa disso?
Brimborium 18/10/12

Respostas:


190

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

impressões

Infinity
NaN
-Infinity

nota: nãoInfinity - Infinity é um número .


23
Evito usar floatsempre que possível, pois sua precisão é muito baixa. ;)
Peter Lawrey

3
Implementar algoritmos como o Dijkstra me faz questionar se POSITIVE_INFINITY <POSITIVE_INFINITY ou não.
Joey Carson

41

Suponho que você esteja usando matemática inteira por um motivo. Nesse caso, você pode obter um resultado que é funcionalmente quase o mesmo que POSITIVE_INFINITY usando o campo MAX_VALUE da Integerclasse:

Integer myInf = Integer.MAX_VALUE;

(E, para NEGATIVE_INFINITY, você pode usar MIN_VALUE.) É claro que haverá algumas diferenças funcionais, por exemplo, ao comparar myInfcom um valor que é MAX_VALUE: claramente esse número não é menor myInf.

Também há uma biblioteca que realmente possui os campos POSITIVE_INFINITY e NEGATIVE_INFINITY, mas na verdade são apenas novos nomes para MAX_VALUE e MIN_VALUE.


11
Quanto é Integer.MAX_VALUE + 5?
Erwin Smout

9
Integer.MAX_VALUE + 5 envolve os números inteiros negativos. Número inteiro.MAX_VALUE + 5 = Número inteiro.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom

Qual é a diferença entre usar Integer.MAX_VALUEcomo infinito e não Double.POSITIVE_INFINITYo que você disse que eles são 'funcionalmente quase iguais', então qual é a diferença?
ahitt6345

1
@ ahitt6345 Integer.MAX_VALUEainda é finito, é apenas um truque para imitar o infinito. Além disso, Integer.MAX_VALUEé de apenas 32 bits, enquanto Double.POSITIVE_INFINITYé de 64 bits.
mgthomas99

1
Integer.MAX_VALUE é um número válido que pode ser usado em sua entrada. op pediu infinito, que NÃO é um número, mas um símbolo matemático.
Refaelio 3/04

11

Para usar Infinity, você pode usar o Doubleque suporta 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);

SAÍDA : -

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

Os tipos Doublee Floattêm a POSITIVE_INFINITYconstante.


@ user1753100: Por padrão, não, mas algumas bibliotecas, como esta: jscience.org , aparentemente, a implementam.
Tudor

1
Parece arbitrário restringir valores infinitos a duplos e flutuadores. Seus valores máximos estão mais próximos do infinito do que o valor máximo de Inteiros, mas não muito mais próximos.
Patrick Brinich-Langlois

3
Os tipos de ponto flutuante @ PatrickBrinich-Langlois (como double e float) normalmente são capazes de expressar diretamente o infinito (ou seja, há um padrão de bits que significa especificamente 'infinito', distinto do valor máximo do tipo). Double e Float têm MAX_VALUE, em comum com Inteiro.
David Morris

7
"Seus valores máximos estão mais próximos do infinito do que o valor máximo de Inteiros, mas não muito mais próximos." Qualquer número finito está infinito longe do infinito;)
carlsb3rg

4

Não tenho certeza de que o Java tenha infinito para cada tipo numérico, mas para alguns tipos de dados numéricos a resposta é positiva:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

ou

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Além disso, você pode achar útil o seguinte artigo, que representa algumas operações matemáticas envolvendo +/- infinito: Complexidade do número de ponto flutuante do Java .


4

Somente os tipos Double e Float suportam POSITIVE_INFINITYconstante.


2

Para os tipos de wrapper numérico.

por exemplo, Double.POSITVE_INFINITY

Espero que isso possa ajudá-lo.


1
Não para todos os tipos de wrapper numérico. Apenas para Double e Float.
Erick G. Hagstrom

2

Uma solução genérica é introduzir um novo tipo. Pode estar mais envolvido, mas tem a vantagem de trabalhar para qualquer tipo que não defina seu próprio infinito.

Se Té um tipo para o qual lteqestá definido, você pode definir InfiniteOr<T>com lteqalgo como isto:

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

Deixo para você traduzir isso para a sintaxe exata do Java. Espero que as idéias sejam claras; mas deixe-me explicá-los de qualquer maneira.

A idéia é criar um novo tipo que tenha todos os mesmos valores de algum tipo já existente, mais um valor especial que, tanto quanto você pode dizer através de métodos públicos, age exatamente da maneira que você deseja que o infinito aja, por exemplo, é maior que algo mais. estou a usarnull para representar o infinito aqui, pois isso parece o mais direto em Java.

Se você deseja adicionar operações aritméticas, decida o que elas devem fazer e implemente-as. Provavelmente é mais simples se você manipular os casos infinitos primeiro e depois reutilizar as operações existentes com valores finitos do tipo original.

Pode ou não haver um padrão geral para se é benéfico ou não adotar uma convenção de lidar com infinitos do lado esquerdo antes dos infinitos do lado direito ou vice-versa; Não sei dizer sem experimentar, mas para menos que ou igual ( lteq), acho mais simples olhar primeiro para o infinito do lado direito. Noto que nãolteq é comutativo, mas eaddmul é; talvez isso seja relevante.

Nota: apresentar uma boa definição do que deve acontecer com valores infinitos nem sempre é fácil. É para comparação, adição e multiplicação, mas talvez não subtração. Além disso, há uma distinção entre números cardinais e ordinais infinitos aos quais você pode prestar atenção.


Pode valer a pena usar um campo de enum extra para representar os estados adicionais, para que você também possa ter Infinito negativo , o que geralmente é desejável e faz com que -(yourvalue)funcione corretamente. E isso também permitiria que você apoiasse o conceito NaN (não um número). Além disso, a adição de valores especiais sobre tipos integrais pode ser uma boa ideia, principalmente quando o aplicativo precisa de semânticas que são violadas por números de ponto flutuante.
blubberdiblub

0

Como a classe Number não é final, eis uma idéia que ainda não encontro nos outros posts. Ou seja, para subclassificar a classe Number.

De alguma forma, isso entregaria um objeto que pode ser tratado como infinito para Inteiro, Longo, Duplo, Flutuante, BigInteger e BigDecimal.

Como existem apenas dois valores, poderíamos usar o padrão 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 alguma forma, acho que os métodos restantes intValue (), longValue () etc. devem ser substituídos para lançar uma exceção. Para que o valor infinito não possa ser usado sem outras precauções.


0

Sou iniciante em Java ... Encontrei outra implementação para o infinito na documentação Java, para os tipos booleane double. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Zero positivo e zero negativo comparam iguais; portanto, o resultado da expressão 0.0 == - 0.0 é verdadeiro e o resultado de 0.0> -0.0 é falso. Mas outras operações podem distinguir zero positivo e negativo; por exemplo, 1,0 / 0,0 tem o valor infinito positivo, enquanto o valor de 1,0 / -0,0 é infinito negativo.

Parece feio, mas funciona.

public class Main {

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

}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.