如何在Java中实现无穷大?


138

Java是否可以代表每种数值数据类型的无穷大?如何实现它以便我可以对其进行数学运算?

例如

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

我尝试使用非常大的数字,但是我想要一个适当,简单的解决方案。


10
有无穷多个无穷大,您想建模哪一个?
戴夫·理查森

11
为什么要∞-∞==0如此?而且:为什么您需要这样的东西?
brimborium 2012年

Answers:


190

double 支持无限

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

版画

Infinity
NaN
-Infinity

记:Infinity - Infinity不是一个数字


23
我避免float尽可能使用它,因为它的精度很差。;)
Peter Lawrey 2012年

3
像Dijkstra这样的实现算法使我质疑POSITIVE_INFINITY <POSITIVE_INFINITY。
乔伊·卡森

41

我想您使用整数数学是有原因的。如果是这样,通过使用Integer该类的MAX_VALUE字段,您可以获得与POSITIVE_INFINITY在功能上几乎相同的结果:

Integer myInf = Integer.MAX_VALUE;

(对于NEGATIVE_INFINITY,您可以使用MIN_VALUE。)当然,会有一些功能上的差异,例如,与myInf恰好为MAX_VALUE的值进行比较时:显然,这个数字不少于myInf

还有一个库实际上具有字段POSITIVE_INFINITY和NEGATIVE_INFINITY,但是它们实际上只是MAX_VALUE和MIN_VALUE的新名称。


11
Integer.MAX_VALUE + 5是多少?
Erwin Smout 2015年

9
Integer.MAX_VALUE + 5环绕成负整数。Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644。
Erick G. Hagstrom 2015年

使用Integer.MAX_VALUE无穷大(而不是Double.POSITIVE_INFINITY您说它们“在功能上几乎相同”)之间有什么区别,那有什么区别?
ahitt6345

1
@ ahitt6345 Integer.MAX_VALUE仍然是有限的,它只是模仿无限的hack。此外,Integer.MAX_VALUE只有32位,而Double.POSITIVE_INFINITY只有64位。
mgthomas99

1
Integer.MAX_VALUE是可以在输入中使用的有效数字。op要求输入无穷大,这不是一个数字,而是一个数学符号。
refaelio

11

要使用Infinity,您可以使用以下Double支持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);

输出:-

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

DoubleFloat类型具有POSITIVE_INFINITY恒定的。


@ user1753100:默认情况下不,但是有些库,例如这样的库:jscience.org显然实现了它。
2012年

1
将无限值限制为Doubles和Floats似乎是任意的。它们的最大值比整数的最大值更接近无穷大,但相差不远。
Patrick Brinich-Langlois,

3
@ PatrickBrinich-Langlois浮点类型(例如double和float)通常能够直接表示无穷大(即,有一种位模式专门表示“无穷大”,与该类型的最大值不同)。Double和Float具有与Integer相同的MAX_VALUE。
大卫·莫里斯

7
“它们的最大值比Integers的最大值更接近无穷大,但相差不远。” 任何有限的数都是无穷远的;)
carlsb3rg

4

我不确定Java是否对每种数值类型都具有无限性,但对于某些数值数据类型,答案是否定的:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

要么

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

另外,下面的文章对涉及+/-无限的一些数学运算也很有用:Java浮点数复杂度


4

仅Double和Float类型支持POSITIVE_INFINITY常量。



2

通用解决方案是引入一种新类型。它可能涉及更多,但它的优点是可以处理任何未定义其自身无穷大的类型。

如果T是一个类型,它lteq被定义,你可以定义InfiniteOr<T>lteq这样的事情:

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

我将把它翻译成确切的Java语法。我希望这些想法很明确。但是我还是要把它们拼出来

这个想法是创建一个新的类型,该类型具有与某些现有类型相同的值,再加上一个特殊的值(据您可以通过公共方法告知),该特殊值的作用完全符合您希望无限操作的方式,例如,它大于还要别的吗。我在null这里用来表示无穷大,因为这在Java中似乎是最简单的。

如果要添加算术运算,请确定它们应该执行的操作,然后实施该运算。如果先处理无限情况,然后在原始类型的有限值上重用现有操作,那可能是最简单的。

关于在左手无穷之前先处理左手无穷的约定是否有益,反之亦然,这可能有一个普遍的模式。我不能不尝试一下就知道,但是对于小于或等于(lteq)的情况,我认为首先查看右侧无穷大会更简单。我注意到,lteq不是可交换的,但addmul者; 也许这是相关的。

注意:对无限值上发生的情况给出一个好的定义并不总是那么容易。它用于比较,加法和乘法,但可能不用于减法。另外,您可能要注意的无限基数和序数之间也有区别。


可能值得使用一个额外的enum字段来表示其他状态,因此您也可以具有负Infinity,这通常是理想的并且可以-(yourvalue)正常工作。这也将使您支持NaN(不是数字)概念。除此之外,在整数类型之上添加特殊值可能是一个好主意,尤其是在应用程序需要浮点数违反语义的情况下。
blubberdiblub

0

由于Number类不是最终的,所以这里有个主意,在其他帖子中我还没有找到。即为类Number的子类。

这将以某种方式传递可被视为Integer,Long,Double,Float,BigInteger和BigDecimal的无穷大的对象。

由于只有两个值,我们可以使用单例模式:

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;
    }
}

我以某种方式认为剩下的方法intValue(),longValue()等应被覆盖以引发异常。因此,如果没有进一步的预防措施,就无法使用无穷大值。


0

我是Java的初学者...我在Java文档中为booleandouble类型找到了另一个用于无限的实现。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

正零与负零比较相等;因此表达式0.0 ==-0.0的结果为true,而0.0> -0.0的结果为false。但是其他运算可以区分正零和负零;例如,1.0 / 0.0的值为正无穷大,而1.0 / -0.0的值为负无穷大。

看起来很丑,但是行得通。

public class Main {

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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.