Kirjoittaja: Sami
Kirjoitettu: 26.01.2004 – 26.01.2004
Tagit: matematiikka, koodi näytille, vinkki
Rationaalilukuluokka sisältää seuraavia metodeita, joita on käytetty Esimerkki.java:ssa:
Seuraavat saavat parametrikseen toisen rationaaliluvun:
* multiply() - kertoo rationaaliluvun toisella rationaaliluvulla
* divide() - jakaa rationaaliluvun toisella rationaaliluvulla
* add() - lisää rationaalilukuun toisen rationaaliluvun
* subtract() - vähentää rationaaliluvusta toisen rationaaliluvun
Ei parametreja:
* simplify() - sieventää rationaaliluvun
* gcd() - palauttaa osoittajan ja nimittäjän suurimman yhteisen tekijän int-tyypin muuttujana
* toDouble() - palauttaa rationaaliluvun likiarvon double-tyypin muuttujana
* toString() - palauttaa rationaaliluvun merkkijonona (muotoa x/y)
* x() - palauttaa rationaaliluvun osoittajan
* y() - palauttaa rationaaliluvun nimittäjän
Seuraavat saavat parametrikseen int:in:
* pow() - korottaa rationaaliluvun haluttuun potenssiin
* setX() - asettaa uuden osoittajan
* setY() - asettaa uuden nimittäjän
P.S. Toivottavasti edes joku hyötyy tästä
Rational.java
/** * @author Sami Mäki */ public class Rational { private int x, y; public Rational() { } public Rational(int x, int y) { this.x = x; this.y = y; } public void multiply(Rational number2) { this.x *= number2.x(); this.y *= number2.y(); } public void divide(Rational number2) { this.x *= number2.y(); this.y *= number2.x(); } public void add(Rational number2) { int laventaja1 = this.y; int laventaja2 = number2.y; this.x = laventaja1 * number2.x + laventaja2 * this.x; this.y = laventaja1 * laventaja2; } public void subtract(Rational number2) { int laventaja1 = this.y; int laventaja2 = number2.y; this.x = laventaja2 * this.x - laventaja1 * number2.x; this.y = laventaja1 * laventaja2; } public void simplify() { int gcd = gcd(); this.x /= gcd; this.y /= gcd; } public int gcd() { int a, b, c; a = this.x; b = this.y; if (a < 0) a = -a; if (b < 0) b = -b; if (a < b) { c = a; a = b; b = c; } int gcd = 0; while(b != 0) { c = a - b*(a/b); if (c == 0) gcd = b; a = b; b = c; } return gcd; } public void pow(int a) { this.x = (int)(Math.pow(this.x, a)); this.y = (int)(Math.pow(this.y, a)); } public double toDouble() { return (double)this.x / this.y; } public String toString() { return this.x + "/" + this.y; } public int x() { return this.x; } public int y() { return this.y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } }
Esimerkki.java
/** * @author Sami Mäki */ public class Esimerkki { public static void main(String[] args) { //Luodaan rationaaliluku (12/7) Rational luku = new Rational(12, 7); //kerrotaan luku luvulla 5/14 luku.multiply(new Rational(5,14)); System.out.println("Luku on kertomisen jälkeen " + luku.x() + "/" + luku.y()); //Sievennetään luku luku.simplify(); System.out.println("Sievennyksen jälkeen luku on " + luku.toString()); //lisätään lukuun 15/7 luku.add(new Rational(15,7)); System.out.println("Lisäyksen jälkeen luku on " + luku.toString()); //Sievennetään luku uudelleen luku.simplify(); System.out.println("Äskeinen sievennettynä " + luku.x() + "/" + luku.y()); // vähennetään 15/7 luku.subtract(new Rational(15, 7)); System.out.println("Vähennyksen jälkeen luku on " + luku.toString()); //Haetaan syt (=suurin yhteinen tekijä) ja sievennetään System.out.print("Suurin yhteinen tekijä on " + luku.gcd() + ", eli äskeinen sievennettynä on "); luku.simplify(); System.out.println(luku.toString()); //Jaetaan luku luvulla 5/6 luku.divide(new Rational(5,6)); System.out.println("Jakolaskun jälkeen luku on " + luku.x() + "/" + luku.y()); //Korotetaan kolmanteen potenssiin ja sievennetään luku.pow(3); System.out.println("Potenssiin korotuksen jälkeen luku on " + luku.toString()); luku.simplify(); System.out.println("Ja lopputulos sievennettynä " + luku.toString()); //Lasketaan likiarvo double likiarvo = luku.toDouble(); System.out.println("Äskeisen hirvityksen likiarvo on " + likiarvo); } }
Ai niin, jos huomaatte virheitä jossain, niin niistä saa antaa kommenttia. (muutakin palautetta voi tietysti antaa, kuten ilmoituksia metodeista, joita voisi lisätä)
Ihan mukava idea. Tuossa sievennysfunktiossa on selvästikin käytetty Eukleideen algoritmia. Minusta se toimii oikein, vaikka luvut olisivat kummatkin negatiivisia tai jälkimmäinen luvuista olisi suurempi. Eli funktio lyhenisi muotoon:
public int gcd() { int a, b, c; a = this.x; b = this.y; int gcd = 0; while(b != 0) { c = a - b*(a/b); if (c == 0) gcd = b; a = b; b = c; } return gcd; }
Meneekös se tosiaan aina kaikilla arvoilla? Pitäneekin tarkistaa asia...
Kyllähän Eukleideen algoritmi toimii myös negatiivisilla luvuilla ja myös muillakin renkailla kuin Z. Luokassa kannattaisi varautua myös nollalla jakoon esim. poikkeuksilla tai määrittelemällä laskusäännöt kuten tehdään mittateoriassa. Tällöin pitäisi kuitenkin ohjelmoida luokkaan erillinen ääretön.
Eikös Javassa ole %-operaattoria (joka siis laskee jakojäännöksen)? Tulisi jotenkin selkeämmän näköinen tuosta, jos kirjottaisi c = a % b. Ei sen luulisi hitaampaakaan olevan, kun kuitenkin aivan sama asia suoritetaan kielen valmiilla operaattorilla?
Crimit:
Heh, tyhmänä en tullut ajatelleeksi tuotakaan, sillä juurihan tuo siinä tehdään (--> pitänee korjata pari pikku asiaa ja yrittää saada muutokset tännekin... sitten kunhan pääsee omalle koneelleen...)