简体   繁体   English

如何在 Java 中实现无穷大?

[英]How to implement infinity in Java?

Does Java have anything to represent infinity for every numerical data type? Java 是否有任何东西可以代表每种数字数据类型的无穷大? How is it implemented such that I can do mathematical operations with it?它是如何实现的,以便我可以用它进行数学运算?

Eg例如

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

I have tried using very large numbers, but I want a proper, easy solution.我尝试过使用非常大的数字,但我想要一个合适、简单的解决方案。

double supports Infinity double支持 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

prints印刷

Infinity
NaN
-Infinity

note: Infinity - Infinity is Not A Number .注意: Infinity - Infinity is Not A Number

I'm supposing you're using integer math for a reason.我假设您出于某种原因使用整数数学。 If so, you can get a result that's functionally nearly the same as POSITIVE_INFINITY by using the MAX_VALUE field of the Integer class:如果是这样,您可以通过使用Integer类的 MAX_VALUE 字段获得在功能上与 POSITIVE_INFINITY 几乎相同的结果:

Integer myInf = Integer.MAX_VALUE;

(And for NEGATIVE_INFINITY you could use MIN_VALUE.) There will of course be some functional differences, eg, when comparing myInf to a value that happens to be MAX_VALUE: clearly this number isn't less than myInf . (对于 NEGATIVE_INFINITY,您可以使用 MIN_VALUE。)当然会有一些功能差异,例如,当将myInf与恰好为 MAX_VALUE 的值进行比较时:显然这个数字不小于myInf Also, as noted in the comments below, incrementing positive infinity will wrap you back around to negative numbers (and decrementing negative infinity will wrap you back to positive).另外,正如下面评论中所指出的,增加正无穷大将使您回到负数(而减少负无穷大将使您回到正数)。

There's also a library that actually has fields POSITIVE_INFINITY and NEGATIVE_INFINITY, but they are really just new names for MAX_VALUE and MIN_VALUE.还有一个库实际上有字段 POSITIVE_INFINITY 和 NEGATIVE_INFINITY,但它们实际上只是 MAX_VALUE 和 MIN_VALUE 的新名称。

To use Infinity , you can use Double which supports Infinity : -要使用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);

OUTPUT : -输出:-

Infinity
-Infinity
-Infinity

Infinity 
NaN

The Double and Float types have the POSITIVE_INFINITY constant. DoubleFloat类型具有POSITIVE_INFINITY常量。

Integer Infinity:整数无穷大:

  Integer maxNumber = Integer.MAX_VALUE

Double Infinity双重无限

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

Float infinity浮动无限

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

I'm not sure that Java has infinity for every numerical type but for some numerical data types the answer is positive:我不确定 Java 是否对每种数字类型都有无穷大,但对于某些数字数据类型,答案是肯定的:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

or要么

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Also you may find useful the following article which represents some mathematical operations involving +/- infinity: Java Floating-Point Number Intricacies .此外,您可能会发现以下文章很有用,它表示涉及 +/- 无穷大的一些数学运算: Java Floating-Point Number Intracacies

Only Double and Float type support POSITIVE_INFINITY constant.只有 Double 和 Float 类型支持POSITIVE_INFINITY常量。

For the numeric wrapper types.对于数字包装器类型。

eg Double.POSITIVE_INFINITY例如Double.POSITIVE_INFINITY

Hope this might help you.希望这对你有帮助。

A generic solution is to introduce a new type.一个通用的解决方案是引入一个新类型。 It may be more involved, but it has the advantage of working for any type that doesn't define its own infinity.它可能涉及更多,但它具有适用于任何未定义其自身无穷大的类型的优势。

If T is a type for which lteq is defined, you can define InfiniteOr<T> with lteq something like this:如果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())

I'll leave it to you to translate this to exact Java syntax.我将留给您将其翻译成准确的 Java 语法。 I hope the ideas are clear;我希望思路清晰; but let me spell them out anyways.但还是让我把它们拼出来吧。

The idea is to create a new type which has all the same values as some already existing type, plus one special value which—as far as you can tell through public methods—acts exactly the way you want infinity to act, eg it's greater than anything else.这个想法是创建一个新类型,它具有与某些已经存在的类型相同的所有值,加上一个特殊值——就您通过公共方法可以看出的而言——完全按照您希望无穷大的方式行事,例如,它大于还要别的吗。 I'm using null to represent infinity here, since that seems the most straightforward in Java.我在这里使用null来表示无穷大,因为这在 Java 中似乎是最直接的。

If you want to add arithmetic operations, decide what they should do, then implement that.如果你想添加算术运算,决定它们应该做什么,然后实现它。 It's probably simplest if you handle the infinite cases first, then reuse the existing operations on finite values of the original type.如果您首先处理无限情况,然后再对原始类型的有限值重用现有操作,这可能是最简单的。

There might or might not be a general pattern to whether or not it's beneficial to adopt a convention of handling left-hand-side infinities before right-hand-side infinities or vice versa;对于在处理右侧无穷大之前采用处理左侧无穷大的惯例是否有益,反之亦然,可能存在也可能没有通用模式; I can't tell without trying it out, but for less-than-or-equal ( lteq ) I think it's simpler to look at right-hand-side infinity first.我不能不尝试就知道,但对于小于或等于( lteq ),我认为首先查看右侧无穷大更简单。 I note that lteq is not commutative, but add and mul are;我注意到lteq不是可交换的,但是addmul是; maybe that is relevant.也许这是相关的。

Note: coming up with a good definition of what should happen on infinite values is not always easy.注意:想出一个关于无限值应该发生什么的好的定义并不总是那么容易。 It is for comparison, addition and multiplication, but maybe not subtraction.它用于比较、加法和乘法,但可能不是减法。 Also, there is a distinction between infinite cardinal and ordinal numbers which you may want to pay attention to.此外,您可能需要注意无限基数和序数之间的区别。

Since the class Number is not final, here is an idea, that I don't find yet in the other posts.由于 class Number 不是最终的,这里有一个想法,我在其他帖子中还没有找到。 Namely to subclass the class Number.即对类 Number 进行子类化。

This would somehow deliver an object that can be treated as infinity for Integer, Long, Double, Float, BigInteger and BigDecimal.这将以某种方式提供一个对象,该对象对于 Integer、Long、Double、Float、BigInteger 和 BigDecimal 可以被视为无穷大。

Since there are only two values, we could use the singleton pattern:由于只有两个值,我们可以使用单例模式:

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

Somehow I think the remaining methods intValue(), longValue() etc.. should then be overriden to throw an exceptions.不知何故,我认为其余的方法 intValue()、longValue() 等应该被覆盖以抛出异常。 So that the infinity value cannot be used without further precautions.因此,如果没有进一步的预防措施,则无法使用无穷大值。

I'm a beginner in Java... I found another implementation for the infinity in the Java documentation, for the boolean and double types.我是 Java 的初学者......我在 Java 文档中找到了另一个无穷大的实现,用于booleandouble类型。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3 https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Positive zero and negative zero compare equal;正零和负零比较相等; thus the result of the expression 0.0==-0.0 is true and the result of 0.0>-0.0 is false.因此表达式 0.0==-0.0 的结果为真,而 0.0>-0.0 的结果为假。 But other operations can distinguish positive and negative zero;但其他操作可以区分正负零; for example, 1.0/0.0 has the value positive infinity, while the value of 1.0/-0.0 is negative infinity.例如,1.0/0.0 的值为正无穷大,而 1.0/-0.0 的值为负无穷大。

It looks ugly, but it works.它看起来很丑陋,但它确实有效。

public class Main {

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM