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)