【问题标题】:How to implement infinity in Java?如何在 Java 中实现无穷大?
【发布时间】:2012-10-08 18:08:50
【问题描述】:

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

例如

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

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

【问题讨论】:

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

标签: java integer double long-integer infinity


【解决方案1】:

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
【解决方案2】:

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

Integer myInf = Integer.MAX_VALUE;

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

还有 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_VALUEDouble.POSITIVE_INFINITY 有什么区别,你说它们“功能几乎相同”,那么有什么区别?
  • @ahitt6345 Integer.MAX_VALUE 仍然是有限的,它只是模仿无限的一种技巧。此外,Integer.MAX_VALUE 只有 32 位,而Double.POSITIVE_INFINITY 是 64 位。
  • Integer.MAX_VALUE 是可以在您的输入中使用的有效数字。 op 要求无穷大,它不是一个数字,而是一个数学符号。
【解决方案3】:

要使用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

【讨论】:

    【解决方案4】:

    DoubleFloat 类型具有 POSITIVE_INFINITY 常量。

    【讨论】:

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

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

    Float.POSITIVE_INFINITY
    Float.NEGATIVE_INFINITY
    

    Double.POSITIVE_INFINITY
    Double.NEGATIVE_INFINITY
    

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        对于数字包装类型。

        例如 Double.POSITVE_INFINITY

        希望这对你有帮助。

        【讨论】:

        • 不适用于所有数字包装器类型。仅适用于 Double 和 Float。
        【解决方案8】:

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

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

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

        【讨论】:

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

        整数无穷大:

          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 组合,您可能会迭代超出数组的索引。此时你不妨放下哨兵,只检查列表的长度。
        【解决方案10】:

        由于类 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() 等等......然后应该被覆盖以引发异常。以便 如果没有进一步的预防措施,则无法使用无穷大值。

        【讨论】:

          【解决方案11】:

          我是 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);
              }
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-12
            • 2019-03-19
            • 2020-06-23
            相关资源
            最近更新 更多