Programació II
Pràctica 2
Pau Santesmasses
Octubre 2005
GMMD | UOC
/*PER VEURE EL MONITOR D'ACIVITAT CAL BORRAR EL SELECTOR #DEBUG DEL FULL D'ESTIL*/
//inicialitzem les variables
a = "" //el primer nombre de la operacio
operador="" //l'operador
b = "" //el nombre de la dreta de l'operador
reserva="" //aqui hi guardarem les sumes i restes mentre
//fem els productes i divisions
resultat="" //el resultat
operacioFinalitzada=false //aquesta booleana ens permet determinar si
//cal reiniciar l'entrada de l'usuari o
//concatenar-la amb l'existent
aEsDecimal=false //booleanes que indiquen si l'entrada es decimal
bEsDecimal=false
rad=false //booleanes que indiquen si el resultat de les
deg=true //operacions trigonomètriques es en graus o radians
E=0 //per si de cas...
//actualitza la pantalla
function actualitzaPantalla(valor){
document.getElementById("pantalla").value = valor;
}
//actualitza la pantalla del mode trigonometric
function actualitzaMode(valor){
document.getElementById("mode").value = valor;
document.getElementById("deg").className=""
document.getElementById("rad").className=""
document.getElementById(valor).className="actiu"
}
//reinicia algunes variables, es fa servir
//quan la operacio finalitza
function reinicia(){
a=""
reserva=""
operador=""
b=""
resultat=""
operacioFinalitzada=false
aEsDecimal=false
bEsDecimal=false
actualitzaPantalla(0)
}
//monitor d'activitat
function debug(){
document.forms[0].a.value=a
document.forms[0].reserva.value=reserva
document.forms[0].operador.value=operador
document.forms[0].b.value=b
document.forms[0].resultat.value=resultat
}
//registra l'entrada de l'usuari
function apreta(entrada){
switch (entrada){
//la coma (al menys aquí, a washington)
case ".":
//si no hi ha operador previ i la operacio
//esta finalitzada, la coma indica 0.
//actualitzem la pantalla
//activem la booleana que indica que a es decimal
//a partir d'ara la tecla coma ja no te efecte.
if(!operador && operacioFinalitzada){
a = "0."
actualitzaPantalla(a)
aEsDecimal=true
operacioFinalitzada=false
//si no tenim operador i la operacio no esta finalitzada,
//vol dir que l'usuari esta entrant el primer nombre.
//Amb l'operador ternari '?'
//si 'a' encara no te valor: 0.
//si a te valor: a.
}else if(!operador && !operacioFinalitzada){
if (!aEsDecimal){
a=(a=="")? "0." : a + "."
actualitzaPantalla(a)
aEsDecimal=true
}
//si l'operador existeix, hem de modificar el segon nombre.
//Amb l'operador ternari '?'
//si 'b' no existeix: b es 0.
//en cas de que b ja existeixi: b es b.
}else if(operador){
if (!bEsDecimal){
b=(b=="")? "0." : b + "."
actualitzaPantalla(b)
bEsDecimal=true
}
}
break;
'
//El 'clear'
case "C": //reinicia la calculadora
reinicia();
break;
//Els nombres
case "0": //introduim els nombres.
case "1": //Si no detectem un operador:
case "2": //sila operacio previa ha acabat
case "3": //assignem el nombre a 'a';
case "4": //si pel contrari la operacio previa
case "5": //ja ha acabat, afegim l'entrada a
case "6": //el valor existent de 'a'
case "7": //Si detectem un operador:
case "8": //assignem el valor a b.
case "9":
if(!operador && operacioFinalitzada){
aEsDecimal=false
a=entrada
actualitzaPantalla(a)
operacioFinalitzada=false
}else if (!operador && !operacioFinalitzada){
a += entrada
actualitzaPantalla(a)
}else if(operador){
b += entrada
actualitzaPantalla(b)
}
break;
//El canvi de signe
case "+-": //Canvi de signe a o b segons hi hagi operador o no
if(!operador){
a = -a
actualitzaPantalla(a)
}else if(operador){
b = -b
actualitzaPantalla(b)
}
break;
//Suma i resta
case "+":
case "-":
//si trobem una suma o resta en curs, la resolem,
//assignem el resultat a 'a' i assignem el nou operador
if (a && operador==("+"||"-") && b){
resultat = eval(a + operador + b)
actualitzaPantalla(resultat)
a=resultat
b=""
bEsDecimal=false
operador = entrada
//si trobem una operacio guardadea en un reserva i l'operador
//es el producte o la divisió, actualitzem la reserva amb el nou
//operador i reiniciem 'b' (aixo ens grantira la
//correcta precedencia d'operadors)
//assignem el nou operador
} else if (reserva && operador==("*"||"http://cv.uoc.edu/~psantesmasses/")){
reserva=reserva + operador + b
b=""
bEsDecimal=false
operador = entrada
//si no hi ha reserva pero l'operador anterior era un producte o
//divisio, guardem la operacio anterior a la reserva i reiniciem 'b'
//assignem el nou operador
} else if (operador==("*"||"http://cv.uoc.edu/~psantesmasses/")){
reserva=a + operador + b
b=""
bEsDecimal=false
operador = entrada
//Si no hi cap operacio en curs, nomes cal que
//assignem el nou operador
} else
operador = entrada
break;
//producte i divisio
case "*":
case "http://cv.uoc.edu/~psantesmasses/":
//si trobem un reserva, l'actualitzem
//assignem el nou operador
if(reserva && operador && b){
reserva=reserva + operador + b
b=""
bEsDecimal=false
operador=entrada
}
//si trobem una multiplicació o divisió en curs,
//la resolem, passem el resulta a 'a'
//assignem el nou operador
//si en canvi trobem una suma o resta, l'hem de gurdar a la reserva
//per poderla efectuar posteriorment
//assignem el nou operador i reiniciem el valor de 'b'
if (a && operador && b){
if (operador=="*" || operador=="http://cv.uoc.edu/~psantesmasses/"){
resultat = eval(a + operador + b)
actualitzaPantalla(resultat)
a=resultat
b=""
bEsDecimal=false
operador = entrada
}else if (operador=="+" || operador=="-"){
reserva=a + operador + b
b=""
bEsDecimal=false
operador = entrada
}
//si no hi ha operacio, assignem al nou operador
} else{
operador = entrada
}
break;
//Potencia
case "^":
//si detectem una operacio en curs, passem el valor de 'b' a 'a'
//per volem que 'b' sigui la base de la potencia i hem de guardar
//'a' i l'operador en unes variables de reserva. L'exponent el
//recollirem a la propera entrada.
/*13/11/05 He trobat bugs a les cadenes de operacions que inclouen
una potencia. Just abans de l'entrega... */
if (a && operador && b){
reserva=a
preoperador=operador
a=b
b=""
bEsDecimal=false
operador = entrada
//i si no nomes cal que... assignem el nou operador
} else {
operador=entrada
}
break;
// l'igual
case "=":
//si l'operador es la potencia:
if (operador=='^'){
//si tenim reserva
//resolem la potencia i hi afegim la reserva
//actualitzem la pantalla i assignem el resultat a 'a'
if (reserva){
potencia=Math.pow(a,b)
resultat =eval(reserva + potencia)
actualitzaPantalla(resultat)
a=resultat
reserva=""
operador=""
b=""
bEsDecimal=false
operacioFinalitzada=true
//si no hi reserva, resolem la potencia,
//actualitzem la pantalla i assignem el resultat a 'a'
}else{
resultat = Math.pow(a, b);
actualitzaPantalla(resultat)
a=resultat
operador=""
operacioFinalitzada=true
b=""
bEsDecimal=false
}
}
//sitenim una cadena d'operacions guardada en reserva
//la resolem junt amb la ultima operació
//actualitzem la pantalla i assignem el resultat a 'a'
if(reserva && b){
resultat=eval(reserva + operador + b)
actualitzaPantalla(resultat)
a=resultat
operador=""
operacioFinalitzada=true
reserva=""
b=""
bEsDecimal=false
//si tenim reserva pero no tenim 'b'
//ignorem l'operador i resolem la reserva
}else if(reserva){
resultat=eval(reserva)
actualitzaPantalla(resultat)
a=resultat
operador=""
operacioFinalitzada=true
reserva=""
b=""
bEsDecimal=false
//si en comptes de reserva tenim a,operador i b
//resolem la operacio
}else if (a && operador && b){
resultat = eval(a + operador + b)
actualitzaPantalla(resultat)
a=resultat
operador=""
operacioFinalitzada=true
b=""
bEsDecimal=false
}
break;
//el percentatge
case "%":
//necessitem una operació previa...
if (a && operador && b){
//si l'operacio es una suma o una resta calcularem
//calculareem el percentatge i els umarem o restarem
//al nombre inicial
if (operador=="+" || operador=="-") resultat = eval(a + operador +(a*b/100))
//fent servir l'operador ternari com a condicional,
//si l'operacio es un producte, dividim percent el resultat
//d'aquest, obtenint el 'b' per cent de 'a'
//si fos una divisio, multipliquem el resulta per 100,
//lo qual ens dona la fraccio a/b en forma de tant per cent
else resultat=(operador=="*")? eval(a + operador + b)/100 : eval(a + operador + b)*100
actualitzaPantalla(resultat)
a=resultat
operador=""
operacioFinalitzada=true
b=""
bEsDecimal=false
}
break;
//les funcions trigonomètriques son predefinides.
//Els resultat son en radians per defecte amb la qual cosa
//si els volem en graus els haurem de convertir multiplicant per PI i
//dividint per 180 o a l'inrev´s
//En cas de error, per exemple l'arcsinus de un n > 1, mostrarem la
//classica E
case "sin":
case "cos":
case "tan":
metode = eval("Math."+entrada)
if (rad){
resultat = metode(a)
resultat=(isNaN(resultat))? "E" : resultat
actualitzaPantalla(resultat)
}else if (deg){
a = a * Math.PI / 180
resultat = metode(a)
resultat=(isNaN(resultat))? "E" : resultat
actualitzaPantalla(resultat)
}
a=(resultat=="E")? "" : resultat
operacioFinalitzada=true
break;
case "asin":
case "acos":
case "atan":
metode = eval("Math."+entrada)
if (rad){
resultat = metode(a)
resultat=(isNaN(resultat))? "E" : resultat
actualitzaPantalla(resultat)
}else if (deg){
resultat = metode(a) * 180 / Math.PI
resultat=(isNaN(resultat))? "E" : resultat
actualitzaPantalla(resultat)
}
a=(resultat=="E")? "" : resultat
operacioFinalitzada=true
break;
//altres metodes de l'objecte math:
//simplement apliquem el metode al valor de 'a'
case "abs":
case "sqrt":
case "log":
case "round":
case "floor":
case "ceil":
metode = eval("Math."+entrada)
resultat = metode(a)
resultat=(isNaN(resultat))? "E" : resultat
a=resultat
actualitzaPantalla(resultat)
operacioFinalitzada=true
break;
//botons deg i rad:
//activem les booleanas tal i com convingui
// i acutlitzem la pantalla del mode
case "deg":
deg=true
rad=false
actualitzaMode(entrada)
break;
case "rad":
deg=false
rad=true
actualitzaMode(entrada)
break;
}
debug() //enviar dades al monitor d'activitat
}