286 lines
8.5 KiB
Plaintext
286 lines
8.5 KiB
Plaintext
#include <basico.h>
|
|
|
|
#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
|