Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java, matemaattiset funktiot ja määrittelyjoukot

Sivun loppuun

Jappe [21.07.2005 14:04:50]

#

Onko kenelläkään kokemusta matemaattisten funktioiden käsittelystä Javassa? Erityisesti määrittelyjoukkojen käsittely ja poikkeustapaukset kiinnostaisivat. Javassa NaN ja äärettömyysarvot menevät try-catchien läpi ja esim. log x arvolla x = 0 on hyväksytty syöte, vaikka logaritmifunktion määrittelyjoukossa x > 0 (tässäkin tapauksessa try-catchit ympärillä). Miksi virheellisillä syötteillä saadaan tuloksia vaikka ei pitäisi, ja miten tällaisiin tilanteisiin tulisi varautua?

Metabolix [21.07.2005 15:54:26]

#

Noihin voi varautua helposti if-lauseilla. Jos (x <= 0), heität virheen, muuten lasket logaritmin.

Jappe [21.07.2005 16:45:36]

#

Metabolix kirjoitti:

Noihin voi varautua helposti if-lauseilla. Jos (x <= 0), heität virheen, muuten lasket logaritmin.

Tarkoituksena ohjelmassani olisi, että käyttäjä voisi itse määrätä laskettavan funktion. Tällöin jokaiseen mahdolliseen poikkeukseen on mahdotonta itse keksiä riittävää määrää ehtoja, jotta ohjelma toimisi kaikilla syötteillä. Onko todellakin niin, että Javassa ovat matemaattisten funktioiden määritelmät päin mäkeä? Logaritmifunktio on vain yksi esimerkki.

peran [21.07.2005 20:12:13]

#

Mitä minä olen käyttänyt, niin Javassa matemaattiset funktiot toimivat paremmin kuin monessa muussa kielessä.
0/0 -> NaN (Not a Number)
1/0 -> Infinity (ääretön)
-1/0 -> -Infinity (-ääretön)

500-1/0 -> -Infinity
1/0-500 -> Infinity
1/0-1/0 -> NaN

Toisin sanoen Java kertoo mitä lukua lähestytään, kun monet muut kielet heittää herjoja. Jos haluaa pysyä reaaliluvuissa, voi vertailla lukuja.

double nro;
// laskutoimituksia
// käsittelyt
if((nro==Double.POSITIVE_INFINITY)||
   (nro==Double.NEGATIVE_INFINITY)||
   (nro==Double.NaN)) {
      // tähän heitetään herjaa
   }

Jappe [22.07.2005 10:42:43]

#

Entä esimerkiksi tapaus Math.pow(Math.E, Math.log(5-x)/3) arvolla x = 5? Funktion ei pitäisi toimia tällä arvolla, mutta antaa kuitenkin arvoksi 0. Tämä on väärin. Tällaiseen tapaukseen ei voi oikein noilla iffeilläkään vaikuttaa. Ja jokaista mahdollista valmista matemaattista funktiota on mahdotonta alkaa tutkimaan.

msdos464 [22.07.2005 13:48:44]

#

Teet esim. näin:

public double pow(double a, double b)
  {
  ...tarkistuksia jne...
  return Math.pow(a, b);
  }

kaikille funktioille mitä tarvitset ohjelmassa.

peran [22.07.2005 23:30:16]

#

Jappe kirjoitti:

Entä esimerkiksi tapaus Math.pow(Math.E, Math.log(5-x)/3) arvolla x = 5? Funktion ei pitäisi toimia tällä arvolla, mutta antaa kuitenkin arvoksi 0.

Logiikka, miten java sen laski:
(5-x)/3->0
log(0)->-ääretön
e potenssiin -ääretön -> 0

Valitettavasti matikkapää ei nyt toimi, eikä ole funktionpiirto-ohjelmia (eikä graafista laskinta), että voisin tarkistaa lähestyykö e^ln((5-x)/3) nollaa, kun x lähestyy 5:sta, mutta voinet tarkistaa.

Jos javan laskentatapa ei miellytä, joudut käyttämään msdos464:n tapaista tarkistusta.
Kannattaa kuitenkin heittää (throw) poikkeus, kun syöte ei miellytä.

Jappe [23.07.2005 14:10:41]

#

Juu, kyllä se noin menee. Mutta tuntuu aika turhauttavalta, kun homma ei toimi luotettavasti. Nyt on ihan pakko käyttää tässä tapauksessa javaa, muuten en käyttäisikään. Ja jatkoa ajatellen taidan määritellä omat funktiot, kuten tuossa msdos464 ehdotti. Sekin vaan turhauttaa, että pitää tehdä tuo kun alkuperäisiin ei voi luottaa. Kun esim log 0:aa ei ole olemassakaan, ja se on tosiasia vaikka voissa paistaisi. Jos siis käyttäjä päättää syöttää oman funktion, jossa on useita matemaattisia funktioita ja jokainen lähestyy jotain arvoa, saadaan vastaukseksi täysin virheellisiä arvoja.

peran [25.07.2005 00:01:15]

#

Tässä mun vinkki, miten saattaa kannattaa toteuttaa omat funktiot.
Toki kannattaa luoda NotaReal (pääluokaksi),NaNException, InfinityException ja NegativeInfinityException, vaikka lyhyyden takia esittelen niiden pääluokalla l. Exception-luokalla.

    public static double pow(double a, double b) throws Exception {
        if((a==Double.POSITIVE_INFINITY)||
            (a==Double.NEGATIVE_INFINITY)||
            (a==Double.NaN)) {
            throw(new Exception());
        }
        if((b==Double.POSITIVE_INFINITY)||
            (b==Double.NEGATIVE_INFINITY)||
            (b==Double.NaN)) {
            throw(new Exception());
        }
        a=Math.pow(a,b);
        if((a==Double.POSITIVE_INFINITY)||
            (a==Double.NEGATIVE_INFINITY)||
            (a==Double.NaN)) {
            throw(new Exception());
        }
        return a;
    }

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta