Làm thế nào để thực hiện vô hạn trong Java?


138

Java có gì để biểu diễn vô hạn cho mọi kiểu dữ liệu số không? Làm thế nào nó được thực hiện để tôi có thể thực hiện các phép toán với nó?

Ví dụ

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

Tôi đã thử sử dụng số lượng rất lớn, nhưng tôi muốn một giải pháp phù hợp, dễ dàng .


10
Có vô số vô số, bạn muốn làm mô hình nào?
Dave Richardson

11
Tại sao phải ∞-∞==0đúng? Và cũng: Tại sao bạn cần một điều như vậy?
brimborium

Câu trả lời:


190

double hỗ trợ vô cực

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

in

Infinity
NaN
-Infinity

lưu ý: không phảiInfinity - Infinitysố .


23
Tôi tránh sử dụng floatbất cứ khi nào có thể vì độ chính xác của nó khá kém. ;)
Peter Lawrey

3
Việc triển khai các thuật toán như Dijkstra khiến tôi đặt câu hỏi liệu có hay không POSITIVE_INFINITY <POSITIVE_INFINITY.
Joey Carson

41

Tôi cho rằng bạn đang sử dụng toán học số nguyên vì một lý do. Nếu vậy, bạn có thể nhận được một kết quả có chức năng gần giống như POSITIVE_INFINITY bằng cách sử dụng trường MAX_VALUE của Integerlớp:

Integer myInf = Integer.MAX_VALUE;

(Và đối với NEGECT_INFINITY, bạn có thể sử dụng MIN_VALUE.) Tất nhiên sẽ có một số khác biệt về chức năng, ví dụ: khi so sánh myInfvới một giá trị xảy ra là MAX_VALUE: rõ ràng con số này không ít hơn myInf.

Ngoài ra còn có một thư viện thực sự có các trường POSITIVE_INFINITY và NEGECT_INFINITY, nhưng chúng thực sự chỉ là tên mới cho MAX_VALUE và MIN_VALUE.


11
Bao nhiêu là Integer.MAX_VALUE + 5?
Erwin Smout

9
Integer.MAX_VALUE + 5 kết thúc thành các số nguyên âm. Số nguyên.MAX_VALUE + 5 = Số nguyên.MIN_VALUE + 4 = -2147483644.
Erick G. Hagstrom

Có gì khác biệt giữa việc sử dụng Integer.MAX_VALUEdưới dạng vô cực thay vì Double.POSITIVE_INFINITYbạn nói rằng chúng "có chức năng gần giống nhau", vậy sự khác biệt là gì?
ahitt6345

1
@ ahitt6345 Integer.MAX_VALUEvẫn là hữu hạn, nó chỉ là một bản hack để bắt chước vô hạn. Hơn nữa, Integer.MAX_VALUEchỉ có 32 bit trong khi đó Double.POSITIVE_INFINITYlà 64 bit.
mgthomas99

1
Integer.MAX_VALUE là một số hợp lệ có thể được sử dụng trong đầu vào của bạn. op yêu cầu vô hạn, KHÔNG phải là một số, mà là một ký hiệu toán học.
refaelio

11

Để sử dụng Infinity, bạn có thể sử dụng các Doublehỗ trợ 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);

ĐẦU RA : -

Infinity
-Infinity
-Infinity

Infinity 
NaN

5

Các DoubleFloatcác loại có POSITIVE_INFINITYhằng số.


@ user1753100: Theo mặc định là không, nhưng một số thư viện, như thế này: jscience.org thực hiện nó rõ ràng.
Tudor

1
Có vẻ như tùy tiện để hạn chế các giá trị vô hạn đối với Nhân đôi và Nổi. Giá trị tối đa của chúng gần với vô cực hơn giá trị tối đa của Số nguyên, nhưng không gần hơn nhiều.
Patrick Brinich-Langlois

3
@ PatrickBrinich - Các loại dấu phẩy động Langlois (như double và float) thường có khả năng biểu thị trực tiếp vô cực (nghĩa là có một mẫu bit có nghĩa cụ thể là "vô cực", khác với giá trị tối đa của loại). Double và Float có MAX_VALUE, chung với Integer.
David Morris

7
"Giá trị tối đa của chúng gần với vô cực hơn giá trị tối đa của Số nguyên, nhưng không gần hơn nhiều.". Bất kỳ số hữu hạn nào là vô cùng xa vô tận;)
carlsb3rg

4

Tôi không chắc chắn rằng Java có vô hạn cho mọi loại số nhưng đối với một số loại dữ liệu số thì câu trả lời là tích cực:

Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY

hoặc là

Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Ngoài ra, bạn có thể thấy bài viết hữu ích sau đây đại diện cho một số hoạt động toán học liên quan đến +/- vô cực: Các điểm phức tạp của số dấu phẩy động Java .


4

Chỉ hỗ trợ loại Double và Float POSITIVE_INFINITYkhông đổi.


2

Đối với các loại trình bao bọc số.

ví dụ: Double.POSITVE_INFINITY

Hy vọng điều này có thể giúp bạn.


1
Không phải cho tất cả các loại trình bao bọc số. Chỉ cần cho Double và Float.
Erick G. Hagstrom

2

Một giải pháp chung là giới thiệu một loại mới. Nó có thể được tham gia nhiều hơn, nhưng nó có lợi thế là làm việc cho bất kỳ loại nào không xác định vô hạn của chính nó.

Nếu Tlà một loại lteqđược xác định, bạn có thể định nghĩa InfiniteOr<T>với lteqmột cái gì đó như thế này:

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())

Tôi sẽ để nó cho bạn dịch cái này sang cú pháp Java chính xác. Tôi hy vọng các ý tưởng là rõ ràng; nhưng hãy để tôi đánh vần chúng ra

Ý tưởng là tạo ra một loại mới có tất cả các giá trị giống như một số loại đã có sẵn, cộng với một giá trị đặc biệt mà theo như bạn có thể nói thông qua các phương thức công cộng, hành động chính xác theo cách bạn muốn hành động vô cùng, ví dụ như nó lớn hơn còn gì nữa không. Tôi đang sử dụng nullđể thể hiện sự vô hạn ở đây, vì điều đó có vẻ đơn giản nhất trong Java.

Nếu bạn muốn thêm các phép toán số học, hãy quyết định những gì họ nên làm, sau đó thực hiện điều đó. Có thể đơn giản nhất nếu bạn xử lý các trường hợp vô hạn trước, sau đó sử dụng lại các hoạt động hiện có trên các giá trị hữu hạn của loại ban đầu.

Có thể có hoặc không có một mô hình chung về việc có hay không có lợi khi áp dụng một quy ước xử lý các hành vi vô cực bên trái trước các hành vi phạm tội bên phải hoặc ngược lại; Tôi không thể nói mà không dùng thử, nhưng với mức độ thấp hơn hoặc bằng ( lteq) tôi nghĩ rằng việc nhìn vào vô cực bên tay phải trước sẽ đơn giản hơn. Tôi lưu ý rằng đó không phảilteq là giao hoán, nhưng và là; có lẽ điều đó có liên quanaddmul

Lưu ý: đưa ra một định nghĩa tốt về những gì sẽ xảy ra trên các giá trị vô hạn không phải lúc nào cũng dễ dàng. Nó là để so sánh, cộng và nhân, nhưng có thể không trừ. Ngoài ra, có một sự khác biệt giữa số thứ tự vô hạn và số thứ tự mà bạn có thể muốn chú ý đến.


Có thể đáng để sử dụng một trường enum bổ sung để thể hiện các trạng thái bổ sung, do đó bạn cũng có thể có Vô cực âm , điều này thường được mong muốn và làm cho -(yourvalue)hoạt động đúng. Và điều đó cũng sẽ cho phép bạn hỗ trợ khái niệm NaN (không phải số). Ngoài ra, việc thêm các giá trị đặc biệt lên trên các loại tích phân có thể là một ý tưởng hay, đặc biệt khi ứng dụng cần ngữ nghĩa bị vi phạm bởi các số dấu phẩy động.
blubberdiblub

0

Vì Số lớp không phải là cuối cùng, đây là một ý tưởng mà tôi chưa tìm thấy trong các bài viết khác. Cụ thể là để phân lớp Số lớp.

Điều này bằng cách nào đó sẽ cung cấp một đối tượng có thể được coi là vô hạn cho Integer, Long, Double, Float, BigInteger và BigDecimal.

Vì chỉ có hai giá trị, chúng tôi có thể sử dụng mẫu singleton:

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

Bằng cách nào đó tôi nghĩ rằng các phương thức còn lại intValue (), longValue () vv .. sau đó nên được ghi đè để đưa ra một ngoại lệ. Vì vậy, giá trị vô hạn không thể được sử dụng mà không cần đề phòng thêm.


0

Tôi là người mới bắt đầu sử dụng Java ... Tôi đã tìm thấy một triển khai khác cho tính vô hạn trong tài liệu Java, cho các loại booleandoubleloại. https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

Số 0 dương và số 0 âm so sánh bằng nhau; do đó, kết quả của biểu thức 0,0 == - 0,0 là đúng và kết quả của 0,0> -0,0 là sai. Nhưng các hoạt động khác có thể phân biệt số 0 dương và âm; ví dụ: 1.0 / 0.0 có giá trị vô cực dương, trong khi giá trị của 1.0 / -0.0 là vô cực âm.

Nó trông xấu, nhưng nó hoạt động.

public class Main {

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

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.