[java]Fibonacci reeks verder uit rekenen

Pagina: 1
Acties:
  • 1.966 views sinds 30-01-2008

Acties:
  • 0 Henk 'm!

  • wvdburgt
  • Registratie: Juli 2003
  • Laatst online: 29-04 10:59

wvdburgt

MacOS all the way baby!

Topicstarter
Beste mede programmeurs.

Allereerst zal ik eerst uitleggen wat nou de fibonacci reeks is voor de gene die dit niet weten. Dat is een reeks waarvan de vorige 2 getallen bij elkaar opgeteld het volgende getal is. Het staat goed uitgelegd op deze pagina: http://www.home.zonnet.nl/LeonardEuler/fibo1.htm

Ik ben eens weze proberen of ik dit met de huidige kennis en ervaring kan programmeren. ( 2 jaar java op mbo niv 4)
Na wat geklooi en wat hulp van een kennis kwam ik op deze code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.awt.*;
import java.applet.*;

public class Fibonacci_reeks extends Applet {
long [] fibo;

    public void init() {
    fibo = new long [ 1000 ];
    fibo[ 0 ] = 0; 
    fibo[ 1 ] = 1; 
 
    for (i = 2; i < 1000; i++) 
        { 
        fibo[ i ] = fibo[ i - 2  ] + fibo[ i - 1  ]; 
        }  
 }

    public void paint(Graphics g) {
    int yPos = 20;

    for( i = 0; i < 1000; i++)
        { 
        g.drawString(""+fibo [i], 50, yPos );
        yPos +=20;
        }

    }


Dit werkt in principe prima alleen ik kom op een gegeven moment het bereik van de long tegen. Ik kom na ongeveer 70 keer die berekening te hebben uitgevoerd in de min terecht. Dit is me allemaal duidelijk hoe ik hier kom. (Na het maximale getal gaat het in in de min met het hoogste getal verder en loopt zo weer naar de 0 toe).

Wat ik me af vroeg is hoe ik nog meer getallen kan uitrekenen zonder dat ik het probleem met die long tegen kom. Ik heb van alles bedacht maar ik kom er niet uit met mijn ervaring. Ik heb al wat gezocht maar ik weet niet waar ik op moet zoeken. (zoektermen grotere waardes java en grotere getallen java).

Heeft iemand een tip zodat ik weer verder kan?
nou ga ik mooi slapen het is al laat genoeg:)

AMD Ryzen 5 7600X | Asus Prime X670-P | Corsair Vengeance 2x 16GB DDR5 PC5200 | XFX Speedser MERC 310 AMD 7900 XTX| http://wvdburgt.nl


Acties:
  • 0 Henk 'm!

  • 4VAlien
  • Registratie: November 2000
  • Laatst online: 24-06 09:47

4VAlien

Intarweb!

je kan je datatypes nog wat oprekken met unsigned long of long long en anders moet je een grote getallen library gebruiken (kan zo maar in Java SDK zitten) verder kan je natuurlijk ook gewoon de getallen opslaan in strings en dan optellen net als je op papier twee getallen onder elkaar optelt, van rechts naar links.

Acties:
  • 0 Henk 'm!

  • T.T.
  • Registratie: April 2000
  • Laatst online: 15-07 15:34

T.T.

Sowieso

Misschien moet je even naar BigInteger kijken (en BigDecimal als je wilt gaan delen ofzo)

http://java.sun.com/j2se/...java/math/BigInteger.html

voorbeeldje gebruik

[ Voor 49% gewijzigd door T.T. op 01-07-2005 03:03 ]


Acties:
  • 0 Henk 'm!

  • RicX
  • Registratie: September 2003
  • Laatst online: 04-09 13:11

RicX

Het leven is geen ponypark

Je moet het recursief programmeren (oftewel: de functie roept zichzelf steeds weer aan). Dat je verder kan uitrekenen omdat alleen het laatste getal wordt opgeslagen, de long kun je typecasten naar een string en zo lang mogelijk maken als je wilt... (en ook nog eens gemakkelijk printen :P )

Honesty is the best policy, but insanity is a better defense


Acties:
  • 0 Henk 'm!

  • 4VAlien
  • Registratie: November 2000
  • Laatst online: 24-06 09:47

4VAlien

Intarweb!

ehm de niet recursieve optie is in principe beter voor dit probleem

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

4VAlien schreef op vrijdag 01 juli 2005 @ 03:51:
ehm de niet recursieve optie is in principe beter voor dit probleem
Inderdaad. Dynamisch programmeren is de snelste oplossing, al gebruikt de topicstarter dat niet echt:
Java:
1
fibo[ i ] = fibo[ i - 2  ] + fibo[ i - 1  ];
Door dit te doen bereken je elk getal in de rij (behalve fibo[0] en fibo[1]) twee keer. Wanneer je tussendoor alles opslaat in een lijstvorm of tussenvariabele hoef je niet telkens getallen te berekenen die je al berekend hebt. :)

Overigens is een bigint inderdaad een goede oplossing hier. Bigints zijn intern opgeslagen als string of array, en zijn daardoor niet begrensd door de grootte van een datatype.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-09 14:19

Robtimus

me Robtimus no like you

Er zijn (minimaal) 3 manieren om fib(n) te berekenen: de recursieve, de lineaire en de exponentiele. Deze laatste twee staan in 'Programming: The Derivation of Algorithms' van Anne Kaldewaij.

Lineair voor fib(N):
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
// N = n
long x = 0; // x = fib(N-n)
long y = 1; // y = fib(N-n+1)
while (n > 0)
{
    // volgend blok is niets anders dan x, y = y, x + y
    long t = x;
    x = y;
    y = t + y;
    n--;
}
// n = 0, so x = fib(N)
return x;
De exponentiele heeft te maken met matrixes, maar hier is de code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// N = n
long a = 0; // the first matrix value
long b = 1; // the second matrix value
long x = 0; // x = fib(N-n)
long y = 1; // y = fib(N-n+1)
while (n != 0)
{
    if ((n % 2) == 0)
    {
        long p = a; // p = a
        long q = b; // q = b
        a = p * p + q * q;
        b = p * q + q * p + q * q;
        n /= 2;
    }
    else
    {
        // (n % 2) == 1
        long p = x; // p = x
        long q = y; // q = y
        x = a * p + b * q;
        y = b * p + a * q + b * q;
        n--;
    }
}
// n = 0, so x = fib(N)
return x;

Nu nog even BigInteger gaan gebruiken tegen de overflow et voila.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
-NMe- schreef op vrijdag 01 juli 2005 @ 04:04:
Door dit te doen bereken je elk getal in de rij (behalve fibo[0] en fibo[1]) twee keer. Wanneer je tussendoor alles opslaat in een lijstvorm of tussenvariabele hoef je niet telkens getallen te berekenen die je al berekend hebt. :)
Dit is juist een schoolvoorbeeld van dynamisch programmeren , fibo[i -1] en fibo[i-2] zijn gewoon lookups in een array welke al bekend is en dus niet uitgerekend hoeven te worden.
Trouwens, dit zou ook kunnen dmv 3 variabelen ipv een long[1000], dat scheelt geheugen, maar kost je extra kopieeracties.
zoals IcemanX het beschrijft dus :P

[ Voor 4% gewijzigd door Glimi op 01-07-2005 09:33 ]


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Kopieeracties zijn niet nodig als je een loop-unroll doet en het 3 keer uitschrijft:
code:
1
2
3
c = b + a
a = b + c
b = a + c

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
MSalters schreef op vrijdag 01 juli 2005 @ 10:06:
Kopieeracties zijn niet nodig als je een loop-unroll doet en het 3 keer uitschrijft:
code:
1
2
3
c = b + a
a = b + c
b = a + c
True, maar echt doorzichtiger wordt het er niet echt op, aangezien je 3 stappen per iteratie gaat doen. Echter wel lekker efficiënt :9~

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Binet's fibonacci number formula:
         (1 + √5)n - (1 - √5)n
f(n) = -----------------------------
                (2n√5)

;)

[ Voor 39% gewijzigd door .oisyn op 01-07-2005 10:54 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • T.T.
  • Registratie: April 2000
  • Laatst online: 15-07 15:34

T.T.

Sowieso

.oisyn schreef op vrijdag 01 juli 2005 @ 10:51:
Binet's fibonacci number formula:
(1 + √5)n - (1 - √5)n
f(n) = -----------------------------
(2n√5)

;)
Als je alleen het n-de Fibonnaci nummer wilt uitrekenen is dat inderdaad handig, als je echter de hele rij wilt uitrekenen, dan is dat minder handig omdat je per fibonnaci-nummer meer berekeningen doet. Alhoewel je natuurlijk het iets zou kunnen vereenvoudigen door:
      (1.6180339...)[sup]n[/] - (&#8211;0.6180339...)[sup]n[/]
f(n) = -----------------------------
                 2.236067977...

Je krijgt dan wel met afrondingsfouten te maken, maar omdat je weet dat je altijd een Integer moet krijgen, kun je dat wel afronden zonder problemen.

Van het feit dat je toch te maken hebt met Integers, kun je nog meer gebruik maken, door een benadering te geven:
                 (1.6180339...)[sup]n[/] 
f(n) =round( ------------------------)
                     &#8730;5

(wel met n>0 natuurlijk) en die 1.6180339... is eigenlijk (1+√5)/2

[ Voor 52% gewijzigd door T.T. op 01-07-2005 12:01 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

T.T. schreef op vrijdag 01 juli 2005 @ 11:47:
Je krijgt dan wel met afrondingsfouten te maken, maar omdat je weet dat je altijd een Integer moet krijgen, kun je dat wel afronden zonder problemen.
Het probleem is echter dat je met doubles nog minder ver komt dan met longs (53 bits precisie van een double vs 64 bits precisie van een long). Ik gaf de formule dus ook niet als manier om het probleem van de topicstarter op te lossen, maar om de al aangedragen methodes om het uit te rekenen aan te vullen.

[ Voor 7% gewijzigd door .oisyn op 01-07-2005 12:11 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Glimi schreef op vrijdag 01 juli 2005 @ 09:32:
Dit is juist een schoolvoorbeeld van dynamisch programmeren.
Woeps, ik was er met mijn hoofd niet helemaal bij, je hebt gelijk. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

T.T. schreef op vrijdag 01 juli 2005 @ 11:47:
(wel met n>0 natuurlijk) en die 1.6180339... is eigenlijk (1+√5)/2
Ook wel als φ(phi) of gulden snede ;)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

ik heb dit gedaan

/**
* bereken het aantal konijnen
*/
public void berekenAantalKonijnen(int maand)
{
int index = 1;
int index2 = 1;
int index3 = 1;
while(index3<maand) {
index = index2 + index;
index2 = index - index2;
index3++;
}
if (index3>=maand) {
System.out.println(index2);
}
}

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Geweldig, maar om daar een topic uit 2005 voor te schoppen... ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1

Dit topic is gesloten.