Tämä javapätkä siis laskee lausekkeen arvon, lauseke voi sisältää matemaattisia funktioita, kertomia ( ! ), potensseja, desimaalilukuja (desimaaliPISTE, ei pilkku), sisäkkäisiä sulkuja sekä tietty peruslaskutoimituksia.
Virheenkäsittelyä ei ole, joten jos esim. lasketaan (-3)^0.5 niin ohjelma pukkaa ruman virheilmoituksen. Bugeja ei pitäisi paljoa olla, mutta joissain tapauksissa saattaa olla häikkää.
public class laskin { static String[] math = {"sin", "cos", "tan", "round", "abs", "sum"}; // tuettavat matemaattiset funktiot public static void main(String[] args) { System.out.println("\ntulos=" + laske("round(abs(3!*tan(sum(3!)))^.5*100)+5*2", 1)); } public static String laske(String lasku, int ind) // ind liittyy välivaiheiden tulostukseen { String tulos = "", tmp1 = ""; int a, b=0, c, m=0, m2=1, j=0, i, l, raja = lasku.indexOf(")"), raja2, des=0; double tmp = 0; boolean neg = false, n = false, desim = false, math_l = false; /* poista kommentti jos haluat nähdä miten lasku etenee for (a = 1; a < ind; a++) System.out.print(" "); System.out.println("laskuun="+lasku+", ind="+ind); */ if (raja > -1) // jos löytyy sulkuja { String tmp2 = lasku.substring(0, raja); // pätkä ennen ) sulkua raja2 = tmp2.lastIndexOf("("); // pätkä ennen ( sulkua // lasketaan sulkujen sisällä olevan lausekkeen arvo, sijoitetaan se edelliseen lausekkeeseen ja palautetaan tulos return laske(lasku.substring(0, raja2)+laske(tmp2.substring(raja2+1, tmp2.length()), ind+1)+lasku.substring(tmp2.length()+1, lasku.length()), ind+1); } for (i = 0; i < math.length; i++) // katsotaan onko joitain matemaattisia funktioita käytetty { for (a = 0; a < lasku.length()-math[i].length(); a++) { math_l = true; for (b = 0; b < math[i].length() && math_l; b++) // voisi olla substringillä järkevämpi if (lasku.charAt(a+b) != math[i].charAt(b)) math_l = false; if (math_l) math_l = (num(lasku.charAt(a+b)-48) || lasku.charAt(a+b) == '-'); if (math_l) { tmp = des = 0; c = a+math[i].length(); desim = false; while (c < lasku.length() && (num(lasku.charAt(c)-48) || (lasku.charAt(c) == '-') && c == a+math[i].length())) { if (lasku.charAt(c) != '.' && lasku.charAt(c) != '-') { tmp = tmp * 10 + lasku.charAt(c) - 48; if (desim) des++; } else if (lasku.charAt(c) == '.') desim = true; c++; } tmp = 1.0*tmp/Math.pow(10, des); if (lasku.charAt(a+b) == '-') tmp = -tmp; tmp1 = lasku.substring(0, a); double luk=0; // katsotaan mikä funktio on kyseessä if (i == 0) luk = Math.sin(tmp); else if (i == 1) luk = Math.cos(tmp); else if (i == 2) luk = Math.tan(tmp); else if (i == 3) luk = Math.round(tmp); else if (i == 4) luk = Math.abs(tmp); else if (i == 5) luk = sum(tmp); if (c<lasku.length()) tmp1 = lasku.substring(c, lasku.length()); else tmp1 = ""; return laske(lasku.substring(0, a)+luk+tmp1, ind+1); } } } for (a = 0; a < lasku.length(); a++) if (!num(lasku.charAt(a)-48) && a > 0) { n = true; if (lasku.charAt(a) != '!' && num(lasku.charAt(a-1)-48) || lasku.charAt(a-1) == '!') m++; } else if (num(lasku.charAt(a)-48) && n) { m2++; n = false; } double[] luvut = new double[m2]; char[] merkit = new char[m]; m=0; for (a = 0; a < lasku.length(); a++) if (num(lasku.charAt(a)-48) && lasku.charAt(a) != '.') { tmp = 10*tmp + lasku.charAt(a)-48; if (desim) des++; } else if (neg(lasku, a)) neg = true; else if (lasku.charAt(a) == '!') { tmp = 1.0*kert(tmp/Math.pow(10, des)); des = 0; } else if (lasku.charAt(a) == '.') desim = true; else { merkit[m] = lasku.charAt(a); luvut[m] = 1.0*tmp/Math.pow(10, des); if (neg) { luvut[m] = -luvut[m]; neg = false; } tmp = des = 0; desim = false; m++; } luvut[m] = 1.0*tmp/Math.pow(10, des); if (neg) { luvut[m] = -luvut[m]; neg = false; } // katsotaan mitä seuraavaksi lasketaan if (lasku.indexOf("!") > -1) { for (a = 0; a < m; a++) tmp1 += (""+luvut[a])+merkit[a]; return laske(tmp1+luvut[a], ind+1); } for (a = 0; a < merkit.length; a++) if (merkit[a] == '^') { for (b = 0; b < a; b++) tmp1 += (""+luvut[b]) + merkit[b]; tmp1 += Math.pow(luvut[a], luvut[a+1]); for (b++; b < merkit.length; b++) tmp1 += (""+merkit[b]) + luvut[b+1]; return laske(tmp1, ind+1); } for (a = 0; a < merkit.length; a++) if (merkit[a] == '*') { for (b = 0; b < a; b++) tmp1 += (""+luvut[b]) + merkit[b]; tmp1 += luvut[a] * luvut[a+1]; for (b++; b < merkit.length; b++) tmp1 += (""+merkit[b]) + luvut[b+1]; return laske(tmp1, ind+1); } else if (merkit[a] == '/') { for (b = 0; b < a; b++) tmp1 += (""+luvut[b]) + merkit[b]; tmp1 += luvut[a] / luvut[a+1]; for (b++; b < merkit.length; b++) tmp1 += (""+merkit[b]) + luvut[b+1]; return laske(tmp1, ind+1); } for (a = 0; a < merkit.length; a++) if (merkit[a] == '+') { for (b = 0; b < a; b++) tmp1 += (""+luvut[b]) + merkit[b]; tmp1 += luvut[a] + luvut[a+1]; for (b++; b < merkit.length; b++) tmp1 += (""+merkit[b]) + luvut[b+1]; if (merkit.length > 1) return laske(tmp1, ind+1); return tmp1; } else if (merkit[a] == '-') { for (b = 0; b < a; b++) tmp1 += (""+luvut[b]) + merkit[b]; tmp1 += luvut[a] - luvut[a+1]; for (b++; b < merkit.length; b++) tmp1 += (""+merkit[b]) + luvut[b+1]; if (merkit.length > 1) return laske(tmp1, ind+1); else return tmp1; } if (merkit.length > 0) return tulos; else return lasku; } public static boolean neg(String lasku, int a) { if (lasku.charAt(a) == '-') if (a == 0) return true; else if (!num(lasku.charAt(a-1)-48) && lasku.charAt(a-1) != '!') return true; return false; } public static boolean num(int l) // onko osa lukua { return ((l >= 0 && l <= 9) || l+48 == '.'); } public static double sum(double l) // laskee 1+2+3+...+l { return .5*l*(l+1); } public static void tulosta(char[] taul) { System.out.print("tulostus:"); for (int a = 0; a < taul.length; a++) System.out.print(taul[a]+","); System.out.print("\n"); } public static double kert(double a) // palauttaa kertoman a! { if (a % 1 > 0) // loistava virheen käsittely :) System.out.println("VIRHE"); int t = 1; for (int l = 2; l <= a; l++) t*=l; return t; } }
ihmesisennykset...
void funktio_a(int i) { ++i; if(i) { funktio_b(i); } }
Eihän tuota pysty millään lukemaan...
void funktio_a(int i) { ++i; if(i) { funktio_b(i); } }
Heti parani.
Aivan hyvät sievennykset. Älä valita juippi.
mikäs vika lausekkeessa (-3)^0.5 on? ihan hyvinhän siitä tulos tulee, joskin se on imaginääriluku, mutta tulos nyt kuitenkin :)
Kertoman laskemiseen taas kannattaisi käyttää tietotyyppinä vähintään long:ia, sillä int menee ympäri jo hyvinkin pienestä kertomasta (13!), long sentään pysyy vielä kärryillä luvun 20 kertomassa.
Tuolla (-3)^0.5 tarkoitetaan ilmeisesti, että tällöin lausekkeeseen tulee eri arvoja riippuen mikä neliöjuuren haara valitaan. Nopeasti katsottuna ohjelmassa ei näytä otetun huomioon eri haarojen avulla saadut tulokset.
Jaska: Enpä usko. Lausekkeella (-3)^0.5 ei ole reaalilukuarvoa, koska ei ole olemassa reaalilukua, jonka toinen potenssi (tai mikään parillinen potenssi) olisi negatiivinen.
Toiseksi, neliöjuurella ei ole kahta haaraa, vaan sen arvo on aina positiivinen. Toisen asteen yhtälöstä tulee kaksi ratkaisua, koska:
x^2 = a =>
|x| = sqrt(a) =>
x = +- sqrt(a)
Aihe on jo aika vanha, joten et voi enää vastata siihen.