wiki:JakolaskuJavassa
Last modified 7 years ago Last modified on 2010-09-05 14:35:09

Pages linking to JakolaskuJavassa:
paate08-2
paate2
paate09-2
JavanAnsoja
paate10-2
s2010

Yllättäviä jakolaskutuloksia Javassa?

Kokonaisluku jaettuna kokonaisluku voi olla ongelmallinen

Kokeile kääntää ja ajaa seuraava ohjelma (tiedostonimeksi Jakolasku.java):

public class Jakolasku {
  public static void main(String[] args) {
    System.out.println(3/2);
  }
}

Mitä oletat saavasi jakolaskun tuloksena ruudulle? 1.5? Melkein. Tulokseksi saadaan hiukan yllättävästi 1. Tämä on siksi, että laskettaessa kahden kokonaisluvun jakolasku, mikäli jako ei mene tasan, palauttaa Java jakolaskun kokonaisosan! Sama pätee seuraavaan:

public class Jakolasku {
  public static void main(String[] args) {
    int a = 3;
    int b = 2;
    System.out.println(a/b);  //tulostaa: 1, kuten edelläkin kävi
  }
}

Mikäli haluat em. esimerkissä vastauksen reaalilukuna 1.5, täytyy jakolasku muuttaa muotoon: 3/2.0 tai 3.0/2 tai 3.0/2.0 (muitakin mahdollisuuksia on, mutta ei puututa nyt niihin).

Yhteenveto

  • ei toimi "odotetusti" jos jako ei mene tasan:
    • kokonaisluku jaettuna kokonaisluku
  • toimii odotetusti vaikka jako ei menisi tasan:
    • reaaliluku jaettuna kokonaisluku
    • kokonaisluku jaettuna reaaliluku
    • reaaliluku jaettuna reaaliluku

Pidempi esimerkki samasta

Tallenna tiedostoon Jakolaskuesimerkki.java:

/**
 * Havainnollistaa Javan ehkä hiukan yllättävää jakolaskukäyttäytymistä:
 *  - mikäli jaetaan kokonaisluku kokonaisluvulla, saadaan tulokseksi vain jakolaskun *kokonaisosa*
 *  - yhteenvetona:
 *     - reaaliluku / kokonaisluku: toimii odotetusti, esim. 3.0/2 = 1.5
 *     - kokonaisluku / reaaliluku: toimii odotetusti, esim. 3/2.0 = 1.5
 *     - kokonaisluku / kokonaisluku: toimii 'yllättävästi' jos jako ei mene tasan, esim. 3/2 = 1 eikä 1.5!!
 */
public class Jakolaskuesimerkki {

  public static void main(String[] args) {
    System.out.println();
    System.out.println("---------------------------------------------------------------------");
    System.out.println("Tunnetusti 3/2 = 1.5...tarkastele kuitenkin seuraavia laskutuloksia.");
    System.out.println("---------------------------------------------------------------------");
    System.out.println("\n\n\n");


    System.out.println("==================================");
    System.out.println("KOKONAISLUKU / KOKONAISLUKU:");
    System.out.println();
    System.out.println("3/2 = " + 3/2);                                // tulostaa: 3/2   = 1
    int iJakaja = 2;
    System.out.println("iJakaja = " +iJakaja+ "    (tyyppi: int)");    // tulostaa: iJakaja = 2   (tyyppi: int)
    System.out.println("3/iJakaja = 3/" +iJakaja+ " = " + 3/iJakaja);  // tulostaa: 3/iJakaja = 3/2 = 1
    System.out.println("\n\n");
    System.out.println("======= ^ HUOMAA TAMA! ^ =========");
    System.out.println("\n\n\n");


    System.out.println("-----------------------------------");
    System.out.println("KOKONAISLUKU / REAALILUKU:");
    System.out.println();
    System.out.println("3/2.0 = " + 3/2.0);                            // tulostaa: 3/2.0 = 1.5
    double dJakaja = 2;
    System.out.println("dJakaja = " +dJakaja+ "    (tyyppi: double)"); // tulostaa: dJakaja = 2.0   (tyyppi: double)
    System.out.println("3/dJakaja = 3/" +dJakaja+ " = " + 3/dJakaja);  // tulostaa: 3/dJakaja = 3/2.0 = 1.5
    System.out.println();


    System.out.println("-----------------------------------");
    System.out.println("REAALILUKU / KOKONAISLUKU:");
    System.out.println();
    System.out.println("3.0/2 = " + 3.0/2);                                  // tulostaa: 3/2.0 = 1.5
    double dJaettava = 3.0;
    System.out.println("dJaettava = " +dJaettava+ "    (tyyppi: double)");   // tulostaa: dJaettava = 3.0   (tyyppi: double)
    System.out.println("dJaettava/2 = " +dJaettava+ "/2 = " + dJaettava/2);  // tulostaa: dJaettava/3 = 3.0/2 = 1.5
  }
}