Re: Converting decimal number to carpenter's fractions
- Posted by bill May 06, 2012
- 2880 views
function carp(atom x) integer u = floor(x) integer n = floor((x-u) * 64 + 0.5) -- boundary conditions -- x-u >= 127/128 if n = 64 then return {u+1, 0, 1} -- orginal function returned {u, 1, 1} -- x-u < 1/128 elsif n = 0 then return {u, 0, 1} -- normal form -- n in range 1-63 else integer d = 64 while remainder(n, 2) = 0 do n /= 2 d /= 2 end while return {u, n, d} end if end function
results:
carp(0) : {0,0,1}
carp(1) : {1,0,1}
carp(0.625) : {0,5,8}
carp(2.314) : {2,5,16}
carp(127/128) : {1,0,1} -- rounds up
carp(1/128) : {0,1,64}
Other comment:
In the original code the normaisation loop went
d = 64 while d > 1 do if remainder(n, 2) = 1 then exit end if n /= 2 d /= 2 end while
The only way this loop can normally terminate is if n started as 0 or 64.
Both conditions meet the test:
remainder(n, 2) = 0 the test d > 1 produces: 64 64 0 64 32 32 0 32 ...... .... 1 1 0 1 <eucode> In the case n = 0, n doesn't change. In the case n = 64, the reduction shouldn't be applied as 64/64 is not a proper fraction. From a programming perspective <eucode> while d > 1 do
is a poor choice because it runs until d <= 1. It exits abnormally in almost all cases.
while remainder(n, 2) = 0
works properly because, *given n is in 0-63*, we know n reduces as d reduces and n must reduce to an odd number.

