domingo, 13 de abril de 2008

Convertir Decimal a Fraccion con Power Builder

En la universidad, se nos presento una ocasion donde nos pedian a nosotros, alumnos, una aplicacion que permita el ingreso de decimales en forma de fraccion con power builder. En internet no habia mucha informacion sobre este tema.

Encontrando solamente un paper interesante para estos fines escrito por John Kennedy, el paper lo pueden encontrar en su sitio web. http://homepage.smc.edu/kennedy%5Fjohn/

John Kennedy desarrollo un algoritmo muy preciso para la generacion de fracciones a partir del decimal de entrada.

Entonces puse manos a la obra y salio esta funcion, que es practicamente una traslacion del lenguaje Turbo Pascal a Power Builder.

Esta funcion utiliza dos parametros: uno por valor, y otro por referencia (que es el String, que servirá de variable de salida).


double ld_decimal, ld_numerador, ld_denominador, ld_denominador_anterior

double ld_z, ld_scratch

integer li_signo_decimal

if ad_valor < 0 then

li_signo_decimal = -1

else

li_signo_decimal = 1

end if

ld_decimal = abs(ad_valor)

if ld_decimal = 0 then

as_valor = string(0)

return

end if

if ld_decimal = int(ld_decimal) then

ld_numerador = li_signo_decimal * ld_decimal

ld_denominador = 1

as_valor = string(ld_numerador)// + '/'+string(ld_denominador)

return

end if

if ld_decimal < 1.0E-19 then

ld_numerador = li_signo_decimal

ld_denominador = 999999999999999999.0

as_valor = string(ld_numerador) + '/'+string(ld_denominador)

return

end if

if ld_decimal > 1.0E+19 then

ld_numerador = 999999999999999999.0 * li_signo_decimal

ld_denominador = 1

as_valor = string(ld_numerador)// + '/'+string(ld_denominador)

return

end if

ld_z = ld_Decimal

ld_Denominador_anterior = 0

ld_denominador = 1

do

ld_z = 1 / (ld_z - int(ld_z))

ld_scratch = ld_Denominador

ld_denominador = ld_denominador * int(ld_z) + ld_denominador_anterior

ld_denominador_anterior = ld_scratch

ld_numerador = int(ld_decimal * ld_denominador + 0.5)

loop until (Abs((ld_Decimal - (ld_numerador / ld_denominador))) < 0.000005 ) or (ld_z = int(ld_z))

ld_numerador = li_signo_decimal * ld_numerador

if ld_denominador = 1 then

as_valor = string(ld_numerador) //+ '/'+string(ld_denominador)

else

as_valor = string(ld_numerador) + '/'+string(ld_denominador)

end if

return




Utilizacion de la funcion:

string ls_salida
f_decimal_a_fraccion(1.5, ls_salida)
Messagebox(string(1.5), ls_salida)

No hay comentarios: