ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Java 中实现无穷大?

对于每种数值数据类型,Java 是否有任何东西可以表示无穷大?它是如何实现的,以便我可以用它进行数学运算?

例如

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

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

有无数个无穷大,你想建模哪一个?
为什么 ∞-∞==0 应该为真?还有:你为什么需要这样的东西?

P
Peter Lawrey

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 不是数字


我尽可能避免使用 float,因为它的精度很差。 ;)
实现像 Dijkstra 这样的算法让我质疑 POSITIVE_INFINITY < POSITIVE_INFINITY。
J
JohnK

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

Integer myInf = Integer.MAX_VALUE;

(对于 NEGATIVE_INFINITY,您可以使用 MIN_VALUE。)当然会有一些功能差异,例如,将 myInf 与恰好是 MAX_VALUE 的值进行比较时:显然这个数字不小于 myInf。此外,正如下面的评论中所指出的,增加正无穷大将使您回到负数(而减少负无穷大将使您回到正数)。

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


Integer.MAX_VALUE + 5 是多少?
Integer.MAX_VALUE + 5 环绕成负整数。整数.MAX_VALUE + 5 = 整数.MIN_VALUE + 4 = -2147483644。
使用 Integer.MAX_VALUE 作为无穷大而不是 Double.POSITIVE_INFINITY 您说它们“在功能上几乎相同”有什么区别,那么有什么区别?
@ahitt6345 Integer.MAX_VALUE 仍然是有限的,它只是模仿无限的一种技巧。此外,Integer.MAX_VALUE 只有 32 位,而 Double.POSITIVE_INFINITY 是 64 位。
Integer.MAX_VALUE 是可以在您的输入中使用的有效数字。 op 要求无穷大,它不是一个数字,而是一个数学符号。
R
Rohit Jain

要使用 Infinity,您可以使用支持 InfinityDouble:-

    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

T
Tudor

DoubleFloat 类型具有 POSITIVE_INFINITY 常量。


@user1753100:默认情况下没有,但是一些库,比如这个:jscience.org 显然实现了它。
将无限值限制为 Doubles 和 Floats 似乎是任意的。它们的最大值比 Integers 的最大值更接近无穷大,但不会更接近。
@PatrickBrinich-Langlois 浮点类型(例如 double 和 float)通常能够直接表示无穷大(即,有一个位模式专门表示“无穷大”,不同于该类型的最大值)。 Double 和 Float 具有 MAX_VALUE,与 Integer 相同。
“它们的最大值比整数的最大值更接近无穷大,但不会更接近。”。任何有限数都是远离无穷大的无穷大;)
S
Sneha Mule

整数无穷大:

  Integer maxNumber = Integer.MAX_VALUE

双无限

  Double maxNumber = Double.MAX_VALUE;
  Double positiveInf = Double.POSITIVE_INFINITY;
  Double negativeInf = Double.NEGATIVE_INFINITY

浮动无穷大

   Float positiveInf = Float.POSITIVE_INFINITY;
   Float negativeInf = Float.NEGATIVE_INFINITY
   Float maxNumber = Float.MAX_VALUE;

我认为 Integer.MAX_VALUE 是一个可实现的值,因此它可以通过可表示的位数来匹配。这并不总是很重要,因为不可能有更大的数字,因为 +1 会溢出到 Integer.MIN_VALUE。无论如何,它与Infinity不太一样?
但是,您可以在许多情况下使用 MAX_VALUE,例如合并排序,如果它可以用作“哨兵值”。例如,如果您想返回一对中的最小值,并且碰巧将哨兵与列表中出现的值 2147483647 进行了比较。你返回哪个并不重要。
唯一的问题是,如果您的输入中有正确的 MAX_VALUE 组合,您可能会迭代超出数组的索引。此时您不妨放下哨兵并检查列表的长度。
A
Akos K

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

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

或者

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

此外,您可能会发现以下文章很有用,它代表了一些涉及 +/- 无穷大的数学运算:Java Floating-Point Number Intricacies


N
NKM

只有 Double 和 Float 类型支持 POSITIVE_INFINITY 常量。


J
Jonas Kölker

一个通用的解决方案是引入一种新类型。它可能涉及更多,但它具有适用于任何未定义其自身无穷大的类型的优势。

如果 T 是定义了 lteq 的类型,您可以使用 lteq 定义 InfiniteOr<T>,如下所示:

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 是;也许这是相关的。

注意:想出一个关于无限值应该发生什么的良好定义并不总是那么容易。它用于比较,加法和乘法,但可能不是减法。此外,您可能需要注意无限基数和序数之间的区别。


使用额外的枚举字段来表示额外的状态可能是值得的,因此您也可以使用 负无穷大,这通常是可取的,并使 -(yourvalue) 正常工作。这也将允许您支持 NaN(不是数字)概念。除此之外,在整数类型之上添加特殊值可能是一个好主意,特别是当应用程序需要浮点数违反的语义时。
c
computingfreak

对于数字包装器类型。

例如Double.POSITIVE_INFINITY

希望这可以帮助你。


不适用于所有数字包装器类型。仅适用于 Double 和 Float。
佚名

由于课程编号不是最终的,这里有一个想法,我在其他帖子中还没有找到。即对类号进行子类化。

这将以某种方式提供一个对象,该对象可以被视为 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() 等应该被覆盖以引发异常。因此,如果没有进一步的预防措施,就无法使用无穷大值。


K
Kislik

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

正零和负零比较相等;因此表达式 0.0==-0.0 的结果为真,而 0.0>-0.0 的结果为假。但其他操作可以区分正负零;例如,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);
    }

}