Thông báo lỗi "Số nguyên quá lớn" cho 600851475143


89
public class Three {
    public static void main(String[] args) {
        Three obj = new Three();
        obj.function(600851475143);
    }

    private Long function(long  i) {
        Stack<Long> stack = new Stack<Long>();

        for (long j = 2; j <= i; j++) {
            if (i % j == 0) {
                stack.push(j);
            }
        }
        return stack.pop();
    }
}

Khi đoạn mã trên được chạy, nó tạo ra lỗi trên dòng obj.function(600851475143);. Tại sao?


1
cũng không có sự khác biệt giữa "l" và "L"?
user446654

@ user446654: Không, có. Cái sau dễ đọc hơn. Đọc "Java Puzzler" cho điều này.
Adeel Ansari

@ user446654: @Thilo phát triển suy nghĩ về giới hạn bộ nhớ có thể vượt quá Tôi muốn thêm 2 đồng tiền của mình: bạn đã chọn thuật toán thực sự, thực sự tồi để tìm kiếm tất cả các ước của một số nếu bạn muốn hoạt động với những số lớn như trong ví dụ của mình. Một cái gì đó dựa trên lập trình động có lẽ sẽ hoạt động tốt hơn. Google trên đó để có thêm kết quả.
Roman

1
Đã thêm thẻ PE, Project Euler # 3
st0le 21/09/10

@ st0le: IMHO câu hỏi thực sự không phải về giải pháp vấn đề ban đầu và những gì chúng tôi thấy cũng không phải là giải pháp.
Roman

Câu trả lời:


201

600851475143không thể được biểu diễn dưới dạng số nguyên 32 bit (kiểu int). Nó có thể được biểu diễn dưới dạng số nguyên 64-bit (kiểu long). các ký tự dài trong Java kết thúc bằng "L":600851475143L


71

Nối hậu tố L: 23423429L.

Theo mặc định, java giải thích tất cả các chữ số dưới dạng giá trị số nguyên 32 bit. Nếu bạn muốn chỉ định rõ ràng rằng đây là một cái gì đó lớn hơn thì số nguyên 32 bit, bạn nên sử dụng hậu tố Lcho các giá trị dài.


Đối với những người tìm kiếm một lời giải thích kỹ hơn về lý do tại sao bạn nhận được thông báo lỗi này ngay cả sau khi bạn thay đổi kiểu biến long, đọc: stackoverflow.com/a/8924925/293280
Joshua Pinter

29

Bạn cần sử dụng một từ dài:

obj.function(600851475143l);  // note the "l" at the end

Nhưng tôi mong rằng hàm đó sẽ hết bộ nhớ (hoặc thời gian) ...


17
nó được coi là một thực hành tốt hơn để làm cho lhợp cụ thể trên, để nó có thể dễ dàng phân biệt1
Bozho

2
@Bozho: Đồng ý. Nhưng tôi có một nền tảng Perl. Tôi viết mã "chỉ ghi" :-)
Thilo

Sử dụng "L" thay vì "l"
Kevin V

13

Trình biên dịch java cố gắng giải thích 600851475143 là một giá trị không đổi của kiểu int theo mặc định. Điều này gây ra lỗi vì 600851475143 không thể được đại diện bằng một int.

Để nói với trình biên dịch rằng bạn muốn tập hợp số, bạn phải thêm một trong hai lhoặc Lsau nó. Số của bạn sau đó sẽ giống như thế này 600851475143L.

Vì một số Phông chữ khó phân biệt "1" và "l" viết thường với nhau, bạn nên luôn sử dụng chữ hoa "L".


6

Tuy nhiên, bạn cần 40 bit để biểu thị số nguyên theo nghĩa đen 600851475143. Trong Java, giá trị số nguyên tối đa là 2 ^ 31-1 (tức là số nguyên là 32 bit, hãy xem http://download.oracle.com/javase/1.4.2/docs /api/java/lang/Integer.html ).

Điều này không có gì để làm với function. Hãy thử sử dụng một số nguyên dài để thay thế (như được đề xuất trong các câu trả lời khác).


4

Tại thời điểm biên dịch, số "600851475143" được biểu thị bằng số nguyên 32 bit, thay vào đó hãy thử ký tự dài ở cuối số của bạn để khắc phục sự cố này.


3

Ngoài tất cả các câu trả lời khác, những gì bạn có thể làm là:

long l = Long.parseLong("600851475143");

ví dụ :

obj.function(Long.parseLong("600851475143"));

1

Hoặc, bạn có thể khai báo số đầu vào bao lâu, và sau đó để nó thực hiện mã tango: D ...

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);
    System.out.println("Enter a number");
    long n = in.nextLong();

    for (long i = 2; i <= n; i++) {
        while (n % i == 0) {
            System.out.print(", " + i);
            n /= i;
        }
    }
}
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.