Yhtälöllä desimaalilukuratkaisu

Edellä kuvattu ratkaisutapa ei toimi, jos yhtälön ratkaisuna on desimaaliluku. Silmukka luvusta -10 lukuun 10 yhden askeleen välein ei anna mitään ratkaisua, jos ratkaisu sattuu kokonaislukujen väliin. Kokeile ratkaista esimerkiksi yhtälö x + 4 = 5x + 2. Ratkaisua ei löydy ja ohjelma ei tulosta mitään.

Jos haluamme ratkaista yhtälön, jossa on desimaalilukuratkaisu, niin joudumme hieman muokkaamaan edellistä esimerkkiä. Aluksi meidän pitää päättää, kuinka monta desimaalia haluamme ratkaisuumme. Jos meille riittää yhden desimaalin ratkaisu, niin silloin voimme kasvattaa for silmukan koko luvusta -100 lukuun 100. Lisäksi emme yritä löytää täysin samaa ratkaisua vaan laskemme yhtälön oikean ja vasemman puolen erotuksen ja määritämme kokeilemalla rajan, milloin olemme tarpeeksi lähellä yhtälön ratkaisua. Tehdään seuraava ohjelma ja ratkaistaan yhtälö.

SANALLINEN ALGORITMI
  1. Määrittele globaali kokonaislukumuuttuja a ja aseta sille alkuarvo 0.
  2. Aseta ikkunan kooksi 500 px vaakaan ja 200 px pystyyn.
  3. Aseta täyttöväriksi eli tekstin väriksi musta.
  4. Aseta tekstin kooksi 20.
  5. Aseta ikkunan taustaväriksi valkoinen.
  6. Aseta asetus, että void draw()-lohko suoritetaan vain kerran.
  7. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -100. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 100. Kasvata muuttujaa yhdellä).
  8. Määrittele desimaalilukumuuttuja y1 ja sijoita siihen laskutoimituksen (x/10.0)+4 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  9. Määrittele desimaalilukumuuttuja y2 ja sijoita siihen laskutoimituksen 5*(x/10.0)+2 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  10. Jos y1:n y2:n erotuksen itseisarvo on pienempi tai yhtä suuri kuin 0.4 (joka on raja-arvo, jota voit muuttaa), niin silloin kasvata laskuria yhdellä ja tulosta löydetyt ratkaisut allekkain laskurin avulla.
  11. Jos muuttujan a arvo on 0 (eli laskuri ei ole kasvanut), niin silloin tulosta kommentti: "En löytänyt ratkaisua. Kasvata raja-arvoa" paikkaan (20,40).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
int a = 0;
void setup () {
size(500,200); // ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
noLoop(); // Toistetaan vain kerran
}

void draw() {
for (int x = -100; x <= 100; x++) {
float y1 = (x/10.0)+4; // Yhtälön vasen puoli
float y2 = 5*(x/10.0)+2; // Yhtälön oikea puoli
if ((abs(y1 - y2) <= 0.4)) {
a++;
text("Yhtälön x+4=5x+2 ratkaisu on x = "+(x/10.0),20,20+a*20);
}
}
if (a == 0) {
text("En löytänyt ratkaisua. Kasvata raja-arvoa!",20,40);
}
}


Ohjelmassa on lihavoitu ne kohdat, joita sinun tarvitsee muuttaa, jos tutkit muiden yhtälöiden ratkaisua.

Koska for-silmukka on 10-kertainen edelliseen nähden, niin vastaavasti kaikki x:t laskukaavoissa pitää jakaa 10:llä. Nyt voimme käydä kaikki luvut läpi yhden desimaalin tarkkuudella. Tämän takia, joudumme muuttamaan kokonaislukumuuttujat (int) desimaalilukumuuttujiksi (float). Olen etsinyt kokeilemalla rajan, milloin ohjelma löytää yhden ratkaisun. Katso lauseketta: if ((abs(y1 - y2) <= 0.4)), se tarkoittaa samaa kuin että jos itseisarvo yhtälön vasemman puolen arvo vähennettynä oikean puolen arvosta on pienempi tai yhtä suuri kuin 0.4, silloin niin tulosta yhtälön ratkaisu. Uutena Processing-ohjelman komentona esiteltiin funktio: abs(luku); joka tarkoittaa syötetyn luvun itseisarvoa.

Nyt ohjelma tulostaa seuraavaa.



Saman voi havaita, jos laskee funktioiden arvoja taulukkoon.



Raja-arvolla 0.4 tuli vielä yksi ratkaisu. Jos raja-arvo eli lukujen erotus on 0.5, niin tähän väliin mahtuu kolme ratkaisua. Mutta, jos raja-arvo eli lukujen erotus on 0.9, niin silloin tulostuu jo viisi ratkaisua. Taulukon mukaan 0.4:llä olisi pitänyt tulostua kolme ratkaisua, mutta johtuen pyöristyksistä kolme ratkaisua tulostuu heti seuraavasta eli esimerkiksi kun raja-arvo eli lukujen erotus on esimerkiksi 0.41, niin tulostuu jo kolme ratkaisua.

Eli jos kirjoitat if-lauseen muotoon: if ((abs(y1-y2) <= 0.5)), niin ohjelma tulostaa kolme ratkaisua allekkain eli 0.4, 0.5 ja 0.6. Siksi ohjelmaan on lisätty laskuri a, joka tulostaa ratkaisut allekkain, jos raja-arvo on liian suuri. Tällöin löytyy useampi ratkaisu tältä väliltä ja tulostus näyttää silloin tältä.



Tämä kertoo, että lukujen erotus on liian suuri ja raja-arvoa on pienennettävä.

Otetaan vielä toinen esimerkki. Haluamme ratkaista yhtälön 6x + 2 = 3x + 4. Katsotaan mikä on tälle yhtälölle sopiva raja-arvo. Lihavoidaan ohjelmaan tehdyt muutokset.

SANALLINEN ALGORITMI
  1. Määrittele globaali kokonaislukumuuttuja a ja aseta sille alkuarvo 0.
  2. Aseta ikkunan kooksi 500 px vaakaan ja 200 px pystyyn.
  3. Aseta täyttöväriksi eli tekstin väriksi musta.
  4. Aseta tekstin kooksi 20.
  5. Aseta ikkunan taustaväriksi valkoinen.
  6. Aseta asetus, että void draw()-lohko suoritetaan vain kerran.
  7. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -100. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 100. Kasvata muuttujaa yhdellä).
  8. Määrittele desimaalilukumuuttuja y1 ja sijoita siihen laskutoimituksen 6*(x/10.0)+2 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  9. Määrittele desimaalilukumuuttuja y2 ja sijoita siihen laskutoimituksen 3*(x/10.0)+4 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  10. Jos y1:n y2:n erotuksen itseisarvo on pienempi tai yhtä suuri kuin 0.1 (joka on raja-arvo, jota voit muuttaa), niin silloin kasvata laskuria yhdellä ja tulosta löydetyt ratkaisut allekkain laskurin avulla.
  11. Jos muuttujan a arvo on 0 (eli laskuri ei ole kasvanut), niin silloin tulosta kommentti: "En löytänyt ratkaisua. Kasvata raja-arvoa" paikkaan (20,40).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
int a = 0;
void setup () {
size(500,200); // ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
noLoop(); // Toistetaan vain kerran
}

void draw() {
for (int x = -100; x <= 100; x++) {
float y1 = 6*(x/10.0)+2; // Yhtälön vasen puoli
float y2 = 3*(x/10.0)+4; // Yhtälön oikea puoli
if ((abs(y1 - y2) <= 0.1)) {
a++;
text("Yhtälön 6x+2=3x+4 ratkaisu on x = "+(x/10.0),20,20+a*20);
}
}
if (a == 0) {
text("En löytänyt ratkaisua. Kasvata raja-arvoa!",20,40);
}
}


If-lauseen raja-arvolla 0.2 tulostuu kaksi ratkaisua peräkkäin eli 0.6 ja 0.7, mutta raja-arvolla 0.1 tulostuu vain yksi ratkaisu.



Huomaa, että jos raja-arvo on alle yhden desimaalin eli esimerkiksi 0.09, niin silloin ei tulostu mitään. Tämä tarkoittaa, että lukujen erotus on jo yli annetun raja-arvon. Silloin raja-arvo on liian pieni. Tätä varten ohjelman loppuun on lisätty kommentti: " En löytänyt ratkaisua. Kasvata raja-arvoa!" Jos tämä ei auta, niin yhtälön ratkaisu ei ole tutkittavalla välillä [-10.0,10.0]. Siinä tapauksessa voit kirjoittaa for-silmukan esimerkiksi muotoon: for (int x=-1000; x <= 1000; x++), jolloin tutkittava väli on [-100.0,100.0] eli kymmenkertainen.

Katsotaan vielä taulukkoon laskettuja arvoja.



Tästä nähdään, että kun raja-arvo eli lukujen erotus on 0.1, niin tulostuu yksi ratkaisu. Vastaavasti raja-arvolla 0.2 tulostuu kaksi ratkaisua. Raja-arvolla 0.4 pitäisi tulostua jo kolme ratkaisua, mutta tulostuukin kaksi. Johtuen pyöristyksistä käytännössä raja-arvo on tässä 4.0000001 jne.

Tällä ohjelmalla voi myös ratkaista kokonaislukuratkaisuja. Silloin raja-arvo on nolla.