ChatGPT解决这个技术问题 Extra ChatGPT

How to implement infinity in Java?

Does Java have anything to represent infinity for every numerical data type? How is it implemented such that I can do mathematical operations with it?

E.g.

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.

there are an infinite number of infinities, which one would you like to model?
Why should ∞-∞==0 be true? And also: Why do you need such a thing?

P
Peter Lawrey

double supports 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.


I avoid using float whenever possible as its precision is pretty poor. ;)
Implementing algorithms like Dijkstra make me question whether or not POSITIVE_INFINITY < POSITIVE_INFINITY.
J
JohnK

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 myInf = Integer.MAX_VALUE;

(And for NEGATIVE_INFINITY you could use MIN_VALUE.) There will of course be some functional differences, e.g., when comparing myInf to a value that happens to be MAX_VALUE: clearly this number isn't less than 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.


How much is Integer.MAX_VALUE + 5 ?
Integer.MAX_VALUE + 5 wraps around into the negative integers. Integer.MAX_VALUE + 5 = Integer.MIN_VALUE + 4 = -2147483644.
Whats the difference between using Integer.MAX_VALUE as infinity rather than Double.POSITIVE_INFINITY you said that they are 'functionally nearly the same', so what is the difference?
@ahitt6345 Integer.MAX_VALUE is still finite, its just a hack for mimicking infinity. Furthermore, Integer.MAX_VALUE is only 32-bits whereas Double.POSITIVE_INFINITY is 64-bits.
Integer.MAX_VALUE is a valid number which can be used in your input. op asked for infinity, which is NOT a number, but a mathematical symbol.
R
Rohit Jain

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

OUTPUT: -

Infinity
-Infinity
-Infinity

Infinity 
NaN

T
Tudor

The Double and Float types have the POSITIVE_INFINITY constant.


@user1753100: By default no, but some libraries, like this one: jscience.org implement it apparently.
It seems arbitrary to restrict infinite values to Doubles and Floats. Their maximum values are closer to infinity than the maximum value of Integers, but not much closer.
@PatrickBrinich-Langlois floating-point types (such as double and float) are typically capable of directly expressing infinity (i.e., there is a bit pattern that specifically means 'infinity', distinct from the maximum value of the type). Double and Float have MAX_VALUE, in common with Integer.
"Their maximum values are closer to infinity than the maximum value of Integers, but not much closer.". Any finite number is infinity away from infinity ;)
S
Sneha Mule

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 think Integer.MAX_VALUE an achievable value, so it can be matched by a representable number of digits. This does not always matter as a larger figure is not possible as +1 would overflow to Integer.MIN_VALUE. Never the less, it's not quite the same as Infinity?
However, you can use MAX_VALUE in many situations like a merge sort were it can be used as a "sentinel value". If for example, you wanted to return the smallest of a pair and you happened to compare the sentinel with the value 2147483647 occurring in your list. It doesn't matter which you return.
The only problem being if you have the right combination of MAX_VALUEs in your input you might iterate beyond the index of your array. At which point you might as well drop the sentinel and just check the length of the list.
A
Akos K

I'm not sure that Java has infinity for every numerical type but for some numerical data types the answer is positive:

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.


N
NKM

Only Double and Float type support POSITIVE_INFINITY constant.


J
Jonas Kölker

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:

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. 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, e.g. it's greater than anything else. I'm using null to represent infinity here, since that seems the most straightforward in 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. I note that lteq is not commutative, but add and mul are; 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.


It may be worthwhile to use an extra enum field in order to represent the additional states, so you can have negative Infinity as well, which is often desirable and makes -(yourvalue) work properly. And that would also allow you to support the NaN (not a number) concept. Apart from that, adding special values on top of integral types can be a good idea, particularly when the application needs semantics that are violated by floating point numbers.
c
computingfreak

For the numeric wrapper types.

e.g Double.POSITIVE_INFINITY

Hope this might help you.


Not for all of the numeric wrapper types. Just for Double and Float.
佚名

Since the class Number is not final, here is an idea, that I don't find yet in the other posts. Namely to subclass the class Number.

This would somehow deliver an object that can be treated as infinity for Integer, Long, Double, Float, BigInteger and 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. So that the infinity value cannot be used without further precautions.


K
Kislik

I'm a beginner in Java... I found another implementation for the infinity in the Java documentation, for the boolean and double types. 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. 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.

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

}