600851475143 için "Tam sayı çok büyük" hata mesajı


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

Yukarıdaki kod çalıştırıldığında, satırda bir hata oluşturur obj.function(600851475143);. Neden?


1
ayrıca "l" ve "L" arasında bir fark yok mu?
user446654

@ user446654: Hayır, var. İkincisi daha okunabilir. Bunun için "Java Puzzler" ı okuyun.
Adeel Ansari

@ user446654: olası bellek sınırının aşılmasıyla ilgili @Thilo düşüncelerinin gelişmesi 2 jetonumu eklemek istiyorum: Örneğinizdeki gibi çok büyük sayılarla çalışmak istiyorsanız, bir sayının tüm bölücülerini aramak için gerçekten çok kötü bir algoritma seçtiniz. Dinamik programlamaya dayalı bir şey muhtemelen daha iyi çalışacaktır. Daha fazla sonuç için Google bu konuda.
Roma

1
PE etiketi eklendi, Project Euler # 3
st0le

@ st0le: IMHO soru kesinlikle orijinal problem çözümü ile ilgili değil ve gördüklerimiz de bir çözüm değil.
Roma

Yanıtlar:


201

60085147514332 bitlik bir tamsayı (tür int) olarak temsil edilemez . 64 bitlik bir tam sayı (tür long) olarak temsil edilebilir . Java'daki uzun değişmez değerler "L" ile biter:600851475143L


72

Ekleme eki L: 23423429L.

Varsayılan olarak, java tüm sayısal değişmezleri 32 bitlik tam sayı değerleri olarak yorumlar. Bunun 32 bitlik tamsayıdan daha büyük bir şey olduğunu açıkça belirtmek istiyorsanız, Luzun değerler için son ek kullanmalısınız .


Değişken türünü olarak değiştirdikten sonra bile bu hata mesajını neden aldığınıza dair daha kapsamlı bir açıklama arayanlar için şunu longokuyun: stackoverflow.com/a/8924925/293280
Joshua Pinter

29

Uzun bir kelime kullanmalısınız:

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

Ama bu işlevin hafızanın (veya zamanın) tükenmesini beklerdim ...


17
lBüyük harf yapmak daha iyi bir uygulama olarak kabul edilir , böylece kolayca ayırt edilebilir1
Bozho

2
@Bozho: Kabul edildi. Ama bir Perl geçmişim var. "Sadece yazılır"
kodluyorum

"L" yerine "L" kullanın
Kevin V

13

Java derleyicisi 600851475143'ü varsayılan olarak int türünün sabit bir değeri olarak yorumlamaya çalışır. 600851475143 bir int ile temsil edilemediği için bu bir hataya neden olur.

Derleyiciye sayının uzun süre yorumlanmasını istediğinizi söylemek için ondan birini lveya Lsonrasını eklemeniz gerekir. Numaranız daha sonra böyle görünmelidir 600851475143L.

Bazı Yazı Tipleri "1" ve küçük harf "l" yi birbirinden ayırmayı zorlaştırdığından, her zaman büyük "L" harfini kullanmalısınız.



4

Derleme zamanında "600851475143" sayısı 32 bitlik tamsayı ile temsil edilir, bu problemden kurtulmak için sayınızın sonunda uzun hazır bilgi deneyin.


3

Diğer tüm yanıtların dışında yapabilecekleriniz:

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

Örneğin :

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

1

Veya, girdi numarasını uzun süre bildirebilir ve ardından tango: D ... kodunu yapmasına izin verebilirsiniz.

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;
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.