如何在 Java 中实现无穷大?
Posted
技术标签:
【中文标题】如何在 Java 中实现无穷大?【英文标题】:How to implement infinity in 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
应该是真的?还有:你为什么需要这样的东西?
【参考方案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_VALUE
和Double.POSITIVE_INFINITY
有什么区别,你说它们“功能几乎相同”,那么有什么区别?
@ahitt6345 Integer.MAX_VALUE
仍然是有限的,它只是模仿无限的一种技巧。此外,Integer.MAX_VALUE
只有 32 位,而Double.POSITIVE_INFINITY
是 64 位。
Integer.MAX_VALUE 是可以在您的输入中使用的有效数字。 op 要求无穷大,它不是一个数字,而是一个数学符号。【参考方案3】:
要使用Infinity
,可以使用支持Infinity
的Double
:-
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】:Double
和 Float
类型具有 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
是不是可交换的,但add
和mul
是;也许这是相关的。
注意:想出一个关于无限值应该发生什么的良好定义并不总是那么容易。它用于比较,加法和乘法,但可能不是减法。此外,您可能需要注意无限基数和序数之间的区别。
【讨论】:
使用额外的枚举字段来表示额外的状态可能是值得的,因此您也可以使用 负无穷大,这通常是可取的,并且使@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 文档中为 boolean
和 double
类型找到了另一个无穷大的实现。
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);
【讨论】:
以上是关于如何在 Java 中实现无穷大?的主要内容,如果未能解决你的问题,请参考以下文章