Programmeermethoden 2012
Vierde programmeeropgave: GROTE getallen

De vierde programmeeropgave van het vak Programmeermethoden in het najaar van 2012 heet GROTE getallen; zie ook het twaalfde werkcollege, en lees geregeld deze pagina op WWW.

Spreekuur in zalen 302 ... 309: dinsdag 20, woensdag 21, donderdag 22, dinsdag 27, woensdag 28, donderdag 29 november, dinsdag 4, woensdag 5, donderdag 6 en vrijdag 7 december 2012, van circa 15.30 tot 17.00 uur.

De opgave

Het is de bedoeling om een C++-programma te maken dat de gebruiker in staat stelt met grote getallen te rekenen via een eenvoudig menu. De grote getallen worden gerepresenteerd door dubbelverbonden pointer-lijstjes (rijtjes): met pointers dus! Ieder vakje uit de rij (een "cijfervakje") bevat een int waarin k cijfers van het getal zitten opgeslagen; hierbij is k een constante, met waarde tussen 1 en 9. In feite werken we in het 10k-tallig stelsel. Zo wordt, als k=2, het getal 23056007008 opgeslagen in 6 cijfervakjes: 2 30 56 0 70 8.

In het menu kan de gebruiker een drietal grote getallen, zeg A, B en C, manipuleren (tip: gebruik een array met drie grote getallen). De gebruiker kan voor elk van de drie een "klein" getal invoeren, ze afdrukken, twee ervan optellen of [optioneel] vermenigvuldigen naar de derde of een Fibonacci-getal erin laten uitrekenen. Bijvoorbeeld: stop het 212-e Fibonacci-getal in B, het 567-e Fibonacci-getal in C en hun som of product in A. Stop daarna 3 in B, en tel A en B op naar C.
De menu-structuur is verder vergelijkbaar met die van de derde programmeeropgave. Zo kan de functie leesgetal opnieuw gebruikt worden!

De bedoeling is een klasse (class) grootgetal te maken, met member-variabelen:

  1. een pointer begin naar het begin van de rij met cijfervakjes;
  2. een pointer einde naar het eind van de rij met cijfervakjes;
  3. een int met het aantal gebruikte cijfervakjes.
De cijfervakjes (een struct met twee pointers en een int) zijn dubbelverbonden: ieder cijfervakje heeft een pointer vorige naar het vorige cijfervakje en volgende naar het volgende cijfervakje.
De klasse heeft in ieder geval de volgende functies:
  1. print druk groot getal af op het beeldscherm (loop het getal af via de begin-pointer, langs de volgende-pointers; ter controle is het ook handig tijdelijk even langs de vorige-pointers te lopen)
  2. leesin: lees "klein" getal (kleiner dan 10k) in vanaf toetsenbord (je mag ook grotere getallen inlezen)
  3. telop(gg1,gg2): het grote getal moet de som worden van de grote getallen gg1 en gg2 (loop de getallen af via hun einde-pointers, langs de vorige-pointers)
  4. fibonacci(n): het grote getal wordt het n-de Fibonacci-getal (met n<10000); het eerste en tweede Fibonacci-getal zijn 1, en de som van het i-de en het i+1-de is het i+2-de
  5. [Als je dit onderdeel niet hebt kost dat 1 punt.] vermenigvuldig(gg1,gg2): het grote getal moet het product worden van de grote getallen gg1 en gg2

  6. voegvoor: voeg een cijfervakje met een gegeven getal erin vooraan het reeds gebouwde grote getal toe (pas op als dit het eerste cijfervakje is!)
  7. voegachter: voeg een cijfervakje met een gegeven getal erin achteraan het reeds gebouwde grote getal toe (pas op als dit het eerste cijfervakje is!) [dit is meer ter oefening dat dat de functie nodig is]
  8. maak: het grote getal stelt het "kleine" getal x voor: één cijfervakje; gebruik voegvoor
  9. maaknullen(m): maak een "groot getal" bestaande uit m cijfervakjes met 0 erin [deze functie kan handig zijn, maar misschien heb je er ook niks aan ...]
  10. vernietig: gooi alle door het grote getal gebruikte cijfervakjes weg
De eerste vijf functies staan gegeven in volgorde van moeilijkheid. Maak ook snel een aantal van de vijf laatste (hulp)functies; andere hulpfuncties, zoals kopieer, kunnen ook nuttig zijn. Denk aan een constructor.

Als k > 4, kan bij het vermenigvuldigen een productje van twee int's boven INT_MAX uit komen. Gebruik hier (voor dat productje) tijdelijk een long long, dat zal wel helpen.

Het is de bedoeling om een drietal files te produceren: de eerste bevat main en het menu, de tweede (zeg gg.h) bevat de klasse-definitie voor grote getallen, en de derde (zeg gg.cc) bevat de functies uit die klasse. Maak ook een makefile.
Dev-C++-gebruikers: Maak een nieuw leeg ("empty") project aan. Voeg daaraan de drie files toe, en compileer het project. Dev-C++ maakt nu zelf een makefile, makefile.win geheten.

Opmerkingen
Gebruik geschikte (member)functies. Bij deze opgave mogen wederom bij elke functie (zelfs main) tussen begin-{ en eind-} hooguit circa 20 niet al te volle regels staan! Elke functie dient van commentaar voorzien te zijn. Let op goed parametergebruik: alle parameters, met uitzondering van membervariabelen, in de heading doorgeven, en de variabele-declaraties zowel bij main als bij de andere functies aan het begin. De enige te gebruiken headerfile is in principe iostream. Zeer ruwe indicatie voor de lengte van het C++-programma: 400 regels. Denk aan het infoblokje.

Uiterste inleverdatum: vrijdag 7 december 2012, 17.00 uur.
BinnenhofHaagse studenten: maandagochtend 10 december 2012, 11.00 uur.
 

Manier van inleveren:

  1. Digitaal de C++-code inleveren: stuur een email naar pm@liacs.nl.
    Stuur geen executable's, lever alleen de drie C++-files en de makefile digitaal in! Noem deze bij voorkeur zoiets als simongarfunkelgg4.cc, dit voor de opdracht van het duo Simon-Garfunkel. De laatst voor de deadline ingeleverde versie wordt nagekeken.
  2. En ook een papieren versie van het verslag (inclusief de C++-code) deponeren in de speciaal daarvoor bestemde doos "Programmeermethoden" in de postkamer van Informatica, kamer 156 van het Snellius-gebouw.
    BinnenhofHaagse studenten: bij de docent.
     

    Overal duidelijk datum en namen van de (maximaal twee) makers vermelden, in het bijzonder als commentaar in de eerste regels van de C++-code.
    Het verslag (uiteraard weer in LaTeX, zie de eerdere opgaven) moet het volgende bevatten: een zeer korte beschrijving van het programma, een beschrijving van punten waarop het programma faalt (indien van toepassing), en een tabel met gewerkte uren, uitgesplitst per week en per persoon. En een referentie betreffende Fibonacci-getallen. Als je kunt vermenigvuldigen: controleer voor een paar zelfgekozen waarden een van de identiteiten met producten van Fibonacci-getallen, bijvoorbeeld die van Cassini. Als je het vermenigvuldigen niet hebt, zeg dan iets over de tijd die het kost om grote Fibonacci-getallen te berekenen (gebruik bijvoorbeeld secs = time (NULL); ... berekening ...; secs = time (NULL) - secs; en denk aan #include <ctime>).

Te gebruiken compiler: als hij maar C++ vertaalt; het programma moet in principe zowel op een Linux-machine (met g++) als onder Visual C++ of Dev-C++ draaien. Test dus in principe op beide systemen! Het programma wordt doorgaans nagekeken met behulp van de compiler die (uiteraard) in het commentaar bovenin het programma vermeld staat. Normering: layout 1; commentaar 2; modulariteit (OOP, functies) 3; werking 4. Eventuele aanvullingen en verbeteringen: lees deze WWW-bladzijde: www.liacs.nl/home/kosters/pm/op4pm.php.