Laboration nr 2, Rationella tal

Denna laboration bör du klara av efter att ha läst kapitel 1-3 i kursboken. Avsikten med laborationen är att du skall bli säker på grundläggande objektorienterade begrepp såsom klasser, objekt, instansmetoder, instansvariabler och konstruktorer.

Uppgiften är att konstruera en klass RatNum som beskriver rationella tal.  Ett rationellt tal uttrycks som bekant som kvoten mellan två heltal. Vi skriver rationella tal på formen 1/3, -1/5.

För att förenkla arbetet har laborationen delats in i tre steg. När du fått ett steg färdigt bör det, om så är möjligt, visas upp för en handledare.
När
steg 3 är klart skall laborationen dokumenteras. Vad dokumentationen skall innehålla beskrivs sist i detta PM. Dokumentationen skall lämnas in via Fire..

Steg 1

När man beskriver rationella tal är det bäst att förkorta bort alla gemensamma faktorer i täljaren och nämnaren. För att kunna göra denna förkortning behövs en klassmetod som beräknar den största gemensamma divisorn till två heltal m och n. Skriv en sådan metod! Kalla metoden sgd och placera den i en klass med namnet RatNum. Metoden ska acceptera både positiva och negativa argument som inte är lika med noll, men den ska alltid ge ett resultat som är större än noll. Utforma din metod så att den genererar en exception av typen IllegalArgumentException om någon av  parametrarna är lika med noll. Detta kan göras med satsen
   throw new IllegalArgumentException ();

Tips. Euklides algoritm för att beräkna den största gemensamma divisorn till två positiva heltal m och n kan beskrivas på följande sätt:

- Dividera m med n och beteckna resten vid divisionen med r.
- Om r=0 så är beräkningen klar och resultatet finns i n.
- Sätt annars m till n och n till r och gå tillbaka till steg 1.

Denna algoritm fungerar om talen  m och n båda är >=1. Se därför i metoden sgd till att parametrarna alltid görs positiva innan algoritmen tillämpas.

Test.

Testa metoden sgd genom att kopiera det färdiga huvudprogrammet RatNumTest1  till samma bibliotek som klassen RatNum . Kompilera och kör programmet!

Steg 2

Det är nu dags att börja fylla i klassen RatNum så att den kan användas för att beskriva rationella tal. För varje objekt av klassen RatNum skall täljaren och nämnaren lagras som två heltal. Dessa skall alltid sakna gemensamma faktorer, dvs. ett rationellt tal skall alltid vara avkortat så långt det går. Nämnaren måste alltid vara större än noll. Negativa rationella tal representeras med en negativ täljare.

I detta steg skall du förse klassen RatNum med följande  konstruktorer och metoder:

Tips.

 I den tredje konstruktorn måste du först  kontrollera att nämnaren inte är lika med 0.  Om så inte är fallet så ska du dividera de båda parametrarna a och b med den största gemensamma divisorn. Du finner lätt den största gemensamma divisorn genom att använda klassmetoden sgd  från  steg 1.  En liten komplikation är att någon eller båda av parametrarna a och b kan vara mindre än noll. Om båda är negativa betecknar a/b ett positivt tal och man kan därför ersätta a och b med sina motsvarande positiva värden. Om den ena parametern är positiv och den andra negativ betecknar ett a/b negativt tal. Man skall då låta täljaren vara negativ och nämnaren positiv.

Test.

Testa klassen RatNum genom att kopiera det färdiga huvudprogrammet RatNumTest2  till samma bibliotek som klassen RatNum . Kompilera och kör programmet! Läs sedan programkoden för huvudprogrammet RatNumTest2 och förvissa dig om att du förstår vad detta program gör.

Steg 3

Klassen skall nu utökas med några metoder, vilka förenklar inläsning och utskrift av rationella tal och gör det möjligt att utföra matematiska operationer på rationella tal. Följande metoder skall läggas till:

Tips.

I metoderna add, sub, mul och div använder du förstås dina matematiska kunskaper. Uttrycket a/b+c/d kan t.ex. skrivas om som (ad+bc)/bd. Använd en lämplig konstruktor när du skapar det tal som skall innehålla resultatet av den matematiska operationen. Då kommer automatiskt alla gemensamma faktorer att divideras bort.

I metoden parse har du stor nytta av några av de metoder för klassen String som visas i faktarutan i avsnitt 2.12 i kursboken. Ett litet tips: Om parametern s till parse inte innehåller någon nämnare kan du själv lägga till texten "/1" sist i s. På det sättet behöver du inte konstruera någon speciell kod för detta fall. Använd metoden Integer.parseInt för att avkoda täljaren respektive nämnaren. Denna genererar som du vet själv en exception av typen NumberFormatException om texten inte innehåller ett heltal.

Test.

När klassen RatNum är klar skall den testas tillsammans med det färdiga huvudprogrammet RatNumTest3. Studera detta program i detalj och sätt dig in i hur det fungerar! När man kör det färdiga huvudprogrammet tillsammans med din klass RatNum kan det se ut på följande sätt:

Skriv uttryck på formen a/b ? c/d, där ? är något av tecknen + - * / = <

> 1/3 + 1/5

1/3 + 1/5       --> 8/15

> 2/3 * 2/5

2/3 * 2/5       --> 4/15

> 1/3 - 2/5

1/3 - 2/5       --> -1/15

> 2/3 / 2/5

2/3 / 2/5       --> 1 2/3

> -2/3 - 2/5

-2/3 - 2/5      --> -1 1/15

> 2/11 < 1/5

2/11 < 1/5      --> true

> 3/15 = 1/5

3/15 = 1/5      --> true

> 5 / 2/3

5 / 2/3 --> 7 1/2

> 5/9 * 2

5/9 * 2 --> 1 1/9

>
 

För att underlätta testningen av klassen RatNum finns det en färdig fil indata.txt som du kan använda om du vill. Du kör den genom att i ett textfönster ge kommandot

 

java RatNumTest3 < indata.txt

Utskriften som programmet då ger kan jämföras med "facit" som finns i filen utdata.txt. När programmet är färdigt skall du köra filen indata.txt som indata till programmet.

Dokumentation.

Dokumentationen skall innehålla programtexten för din klass RatNum samt den utskrift programmet RatNumTest3 producerar när det körs med filen indata.txt som indata. I dokumentationen skall du också med egna ord ge en beskrivning av vad det färdiga huvudprogrammet RatNumTest3 gör och hur det fungerar.