2012-01-19 10 views
5

Próbuję rozwiązać Euler's Project #2 i nadal otrzymuję odpowiedź jako "Nieskończoność" lub "NaN" (Nie numer) Próbowałem zmienić typ numeru na int (pierwotnie Double), ale to nie naprawiło niczego po prostu dał mi odpowiedź „-1833689714”Projekt Euler # 2 Infinity?

public class Pro { 
    static int g = 1; 
    static int n, f = 0; 
    public static void main(String args[]) { 
     for (int i = 0; i <= 4000000; i++) { 
      f = f + g; 
      g = f - g; 
      if (f % 2 == 0) { 
       n += f; 
      } 
     } 
     System.out.println("Answer: " + n); 
    } 
} 

pytania brzmi:

Każdy nowy termin w ciągu Fibonacciego jest generowany przez dodanie dwóch poprzednich terminów. Rozpoczynając od dnia 1 i 2, pierwsze 10 terminy będą:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

przy wzięciu pod uwagę warunki w sekwencja Fibonacciego, której wartości nie przekraczają czterech milionów, znajdź sumę wartości parzystych.

+0

można również sprawdzić klasę BigInteger: http://docs.oracle.com/javase/6/docs/ api/java/math/BigInteger.html – santiagozky

Odpowiedz

8

Państwo rozważają pierwsze 4.000.000 wyrazów ciągu Fibonacciego zamiast pierwszych x warunkach, które nie przekraczają 4.000.000.

+0

Dzięki, wciąż się budziłem;) Rozumiem teraz – M4trixSh4d0w

2

Prawdopodobnie napotykasz przepełnienie. fibo(4000000) jest znacznie powyżej MAX_INT.

Uwaga:, że nie poprosił, aby znaleźć sumę liczb parzystych w pierwszych numerach od 4.000.000, ale aby znaleźć sumę nawet elementy, które ich wartośćnie jest ponad 4,000,000.

Należy sprawdzić, czy f< 4000000 a jeśli nie, złamać, a nie czekać do i osiągnąć 4.000.000

1

Sprawdzasz pierwsze 4 miliony Fibonacci, musisz tylko sprawdzić warunki, aż termin fibonnaci będzie większy niż 4 miliony, a następnie przestań. Powodem, dla którego uzyskujesz liczby ujemne, jest to, że w końcu uzyskujesz terminy Fibonacci, które są większe niż Integer.MAX_INT, w którym to momencie przepełniasz i zaczynasz uzyskiwać liczby ujemne, które dodajesz do swojej sumy. Jeśli nie masz pewności, czy ostateczna odpowiedź przekroczy wartość Integer.MAX_INT, powinieneś używać długiego jako swojego akumulatora zamiast int.

0

Zastosowanie GMP do obsługi dużych liczb w C i trochę myślenia, zanim nie zaszkodzi (jak często, jak tam jest nieparzysta versus nawet, co jest sumą pierwszych elementów n sekwencji Fibonacciego) ...

+1

To nie jest 'C', java ma natywną klasę' BigInteger'. Również dla tego pytania 'long' jest więcej niż wystarczające. – amit

+0

Moja wina dotycząca części C ... – Matthieu

+0

Użycie 'long' może być więcej niż wystarczające, ale' 'BigInteger' jest preferowany dla precyzyjnych obliczeń: http://docs.oracle.com/javase/tutorial/java/data /numberclasses.html –

3

Twój problem jest przepełnieniem liczby całkowitej: w Javie zmienna int jest ograniczona do Integer.MAX_VALUE (2147483647). Jeśli przekroczysz tę wartość w obliczeniach, przepełnisz wartość do Integer.MIN_VALUE, najmniejszej wartości ujemnej. Zobacz:

public class IntegerOverflow { 
    public static void main(String[] args) { 
     int i = Integer.MAX_VALUE; 
     System.out.println("i = Integer.MAX_VALUE: " + i); 
     System.out.println("i + 1: " + (i + 1)); 
     System.out.println("i + 2: " + (i + 2)); 
    } 
} 

Aby uniknąć problemów z przelewem, wykonują swoje obliczenia z arbitralny precyzji liczb całkowitych, pod warunkiem przez klasę java.math.BigInteger:

import java.math.BigInteger; 

public class BigIntegerExample { 
    public static void main(String[] args) { 
     BigInteger b = BigInteger.valueOf(Long.MAX_VALUE); 
     System.out.println("b = Long.MAX_VALUE: " + b); 
     System.out.println("b**2: " + b.multiply(b)); 
     System.out.println("b**3: " + b.pow(3)); 
     System.out.println("b**10: " + b.pow(10)); 
    } 
} 

Note: Jak można nie zapytać aby uzyskać pomoc dotyczącą samego problemu, właśnie odpowiadam na pytanie.Mam nadzieję, że to pomaga

+1

Ten problem powinien wymagać tylko 'int'. – Jeffrey

+0

Masz rację, ale: utrata wydajności używania 'BigInteger' jest znikoma w tym problemie, a użycie' BigInteger' nie musi martwić się przepełnieniami. –

+0

+1 za udzielenie odpowiedzi na pytanie wraz z notatką i zachowanie w duchu pomocy PE. –

0

Możesz użyć long zamiast int.

Co trzecie wyrażenie jest parzyste, więc wystarczy ocenić co trzecią wartość. Jest to trochę szybsze, ponieważ pętle są mniej razy i nie musisz testować parzystości/nieparzystości.

Musisz tylko n, a nie i, czyli mniej niż 4 miliony.

0

To jak mam odpowiedź:

def fib(): 
     x,y = 0,1 
     while True: 
      yield x 
      x,y = y, x+y 

def even(seq): 
    for number in seq: 
     if not number % 2: 
      yield number 

def under_a_million(seq): 
    for number in seq: 
     if number > 4000000: 
      break 
     yield number 

print sum(even(under_a_million(fib()))) 

-M1K3

Powiązane problemy