#include #proto verificarconstante(_X_) #synon _verificarconstante se verifica constante en #proto verificarfunción(_X_) #synon _verificarfunción se verifica función en algoritmo pila de trabajo 50 números (largo de datos) decimales '13' preparar datos(DATA_EXPRESIONES) obtener tamaño de datos, guardar en 'largo de datos' imprimir ("Negativos deben escribirse entre parentesis\nEjemplo: (-3)\n\n") iterar matrices ( pila, p, q ) cadenas (expresión) obtener dato, copiar en 'expresión' ir a subs ( convierte a matriz --> convierte a notación polaca \ --> evalúa expresión --> despliega resultados ) --largo de datos mientras ' largo de datos' terminar subrutinas convierte a matriz: argumentos 'expr' transformar(" ","",\ transformar("(-","(0-",expr)), guardar en 'expr' l=0, #( l = len(expr) ) v="", num="", cte="" para cada caracter (v, expr, l) cuando ( #(typechar(v,"digit") || v==".")){ num, v, concatenar esto, guardar en 'num' continuar } cuando ( #(typechar(v,"alpha") )){ cte, v, concatenar esto, guardar en 'cte' continuar } cuando (num) {num, meter en 'q', num=""} cuando (cte) {cte, meter en 'q', cte=""} v, meter en 'q' siguiente cuando (num) {num, meter en 'q'} cuando (cte) {cte, meter en 'q'} "(", meter en 'pila' ")", meter en 'q' // imprimir( "Q = {", q, "}\n" ) retornar convierte a notación polaca: l="", m="" iterar mientras '#( not(is empty(q)) )' sw = 1 ///imprimir("P = ",p,"\nQ = ",q,"\nPILA = ",pila,NL) extraer tope 'q' para 'l' // ¿es un operando? cuando ' #(not( occurs(l,"+-*^/)(%") )) ' { si ' se verifica constante en (l) ' meter en 'p' sino si ' se verifica función en (l) ' l, meter en 'pila' sino #( number(l) ), meter en 'p' fin si continuar } // es un simbolo... // es un parentesis izquierdo? cuando ( #( l=="(" ) ) { l, meter en 'pila' continuar } // es un operador? cuando ( #( occurs(l,"+-*^/%")) ) { iterar mientras ' sw ' extraer cabeza 'pila' para 'm' cuando ' #(m=="(") '{ m,l, apilar en 'pila' sw=0, continuar } cuando ' #(l=="^") '{ si ' #(m=="^") ' //m,l, apilar en 'p' m, meter en 'p' sino m,l, apilar en 'pila' sw=0 fin si, continuar } cuando ' #(l=="*") ' { si ' #(occurs(m, "^*/%"))' m, meter en 'p' sino m,l, apilar en 'pila' sw=0 fin si, continuar } //cuando ' #(l=="/") ' { // decisión de diseño para resto módulo cuando ' #( occurs(l,"/%")) ' { si ' #( occurs(m, "/^*%") )' m, meter en 'p' l, meter en 'pila' sino m,l, apilar en 'pila' fin si sw=0, continuar } cuando ' #(occurs(l, "+-"))' { m, meter en 'p' // saber si ya hay un símbolo "-" en pila tmp=0 tope(pila), mover a 'tmp' si ' #( occurs(tmp,"+-") ) ' extraer cabeza (pila) meter en 'p' fin si l, meter en 'pila' sw=0 } reiterar si ' #( length (pila)==0 ) ' "(", meter en 'pila' fin si continuar } // es un paréntesis derecho? cuando( #(l==")") ) { extraer cabeza (pila) para 'm' iterar mientras ' #( m<>"(") ' m, meter en 'p' extraer cabeza 'pila' para 'm' reiterar } reiterar retornar evalúa expresión: l = " ", a=0, b=0 iterar mientras ' #( not(is empty(p)) ) ' extraer tope 'p' para 'l' si ' es numérico (l) ' l, meter en 'pila' sino si ' se verifica función en (l) ' extraer cabeza 'pila' para 'b' seleccionar 'l' caso ("sqrt"){ #(sqrt(b)), salir } caso ("log"){ #(log10(b)), salir } caso ("ln"){ #(log(b)), salir } caso ("fact"){ si ' #(int(b)<>b) ' // límite de Euler x=0,i=2, xb=1, // aproximación muy burda. #basic{ b = b + 1 x = fact(163)*(163^b) xb = b*(b+1) while( i<=163 ) xb = xb * ( i+b ) i+=1 wend x/xb } sino // normal #(fact(b)) fin si salir } fin seleccionar sino extraer cabeza 'pila' para 'b' extraer cabeza 'pila' para 'a' seleccionar 'l' caso ("+"){ #(a+b), salir } caso ("-"){ #(a-b), salir } caso ("*"){ #(a*b), salir } // n/0 = inf, no es necesario detectar esto: caso ("/"){ #(a/b), salir } caso ("^"){ #(a^b), salir } caso ("%"){ #(a%b), salir } fin seleccionar fin si meter en 'pila' fin si reiterar retornar despliega resultados: imprimir(expresión," : ", \ tomar si( #(length(pila)==1),pila, \ #(utf8("expresión mal formada!"))), NL) retornar verificar constante (x) seleccionar 'x' caso ("pi"){ M_PI, 1, salir } caso ("e") { M_E, 1, salir } caso ("phi"){ M_PHI, 1, salir } // etcétera... caso por defecto{ 0, salir } fin seleccionar retornar verificar función (f) seleccionar 'f' caso ("sqrt"){ '1', salir } caso ("log"){ '1', salir } caso ("ln"){ '1', salir } caso ("fact"){ '1', salir } // etcétera... caso por defecto { '0', salir } fin seleccionar retornar DATA_EXPRESIONES: datos("((30+4.5) * ( 7 / 9.67 )+3)-4*(-1)") //31.9741468459168 datos("1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1") // 60! datos("(1 - 5) * 2 / (20 + 1)") // -8/21 datos("(3 * 2) - (1 + 2) / (4") // error! datos("(3 * 2) a - (1 + 2) / 4") // error! datos("(6^2)*2/3") //24 datos("6^2*2/3") //24 datos("(6^2)*2/0") //inf datos("2 * (3 + ((5) / (7 - 11)))") // 3.5 datos("1 - 5 * 2 / 20 + 1") //1,5! datos ("(1 + 2) * 10 / 100") // 0.3 datos("1+3.78") // 4.78 datos("2.5 * 2 + 2 * pi") // 11.28 datos("1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10") // 71 datos("1+1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1/15)/14)/13)/12)/11)/10)/9)/8)/7)/6)/5)/4)/3)/2") // 2.7182818284589946 datos("((11+15)*15)*2-(3)*4*1") // 768 datos(" 2*(-3)-(-4)+(-0.25)") //-2.25 datos(" 2-25 % 3+1") // 2 datos(" 2-(25 % 3)+1") // 2 datos(" (2-25) % (3+1)") // -3 datos(" 2- 25 % 3 % 2") // 1 datos(" 2- 25 / 3 % 2") // 1.66666 datos(" 2- ((25 / 3) % 2)") // 1.66666 datos(" 2- 25 / 3 / 2") // 2.166666 datos(" (-23) %3") // -2 datos(" (6*pi-1)^0.5-e") // 1,506591651... datos("2^2^3^4") datos("(4-2*phi)*pi") // 2,3999632297286 datos("( (1+sqrt(5))/2)^(2/pi)") // 1.3584562741830 datos("1-(1+ln(ln(2)))/ln(2)") // 0.0860713320559 datos("pi / (2 * ln(1+sqrt(2)))") // 1,7822139781 .... datos("( (e^(pi/8)) * sqrt(pi)) /(4 * (2^(3/4)) * (fact(1/4))^2) ") //0,47494 93799... datos(" fact(1/2)") // 0.906402477055... back