Re: Converting decimal number to carpenter's fractions

new topic     » goto parent     » topic index » view thread      » older message » newer message

Comments:

1. Negative lengths make no sense in the real world.

I would prefer to reject a request for an equivalent screw size of -38mm in 64ths of an inch as a type error.

2. The code as written has problems.

   denominator = base 
 
   -- *** 0, base is not normalised: GCD(0,3) = 3, not 0. 
   if numerator > 0 then 
      -- First, normalize the fraction in terms of GCD 
      x = gcd(numerator, denominator) 
      numerator /= x 
      denominator /= x 
 
      -- *** the following code will never run 
      -- Next, normalize the fraction until either top or bottom is an odd number. 
      while remainder(numerator,2) = 0 and remainder(denominator,2) = 0 do 
         numerator /= 2 
         denominator /= 2 
      end while 
       -- *** 
    end if 
    -- *** returns incorrect result when numerator is zero 
    return {units, numerator, denominator, sign} 
 
? carp(0)       -- {0,0,64,1}        -- *** should be {0,0,1,1} 
? carp(1)       -- {1,0,64,1}        -- *** should be {1,0,1,1} 
? carp(-0.625)  -- {0,5,8,-1} 
? carp(2.314)   -- {2,5,16,1} 
 
? carp(127/128) -- {1,0,64,1}        -- *** should be {1,0,1,1} 
? carp(127/128,,128) -- {1,127,128,1} 
? carp(1/128)   -- {0,1,64,1} 
? carp(257/256) -- {1,0,64,1}        -- *** should be {1,0,1,1} 
include std/math.e 
 
constant MAXINT = 2e30 
 
type Real(atom x) 
  return x >= 0 
end type 
 
type Nat(integer x) 
  return x >= 0 and x <= MAXINT 
end type 
 
type PNat(integer x) 
  return x > 0 and x <= MAXINT 
end type 
 
function carp(Real size, PNat base=64) 
   Nat t = floor(size * base + 0.5) 
   Nat n = mod(t, base) 
   Nat U = floor(t / base) 
   if n = 0 then 
      return {U, 0, 1}  -- accounting for a bug in gcd function 
   else 
      PNat g = gcd(n, base) 
		return {U, n/g, base/g} 
   end if 
end function 
 
/* 

? carp(0)       -- {0,0,1} 
? carp(1)       -- {1,0,1} 
? carp(2.314)   -- {2,5,16} 
? carp(1/128)   -- {0,1,64} 
? carp(127/128) -- {1,0,1} 
? carp(257/256) -- {1,0,1} 
*/ 
function GCD(integer a, integer b) 
   if a < 0 then 
      return GCD(-a, b) 
   elsif b < 0 then 
      return GCD(a, -b) 
   elsif b < a then 
      return GCD(b, a) 
   elsif a = 0 then 
      if b = 0 then 
         return {1, 0} -- error 
      else 
         return {0, b} 
      end if 
   else 
      return GCD(mod(b,a), a) 
   end if 
end function 
 
? GCD(3,4)  -- {0, 1} 
? GCD(0,0)  -- {1, 0} 
? GCD(-4,8) -- {0, 4} 
? GCD(3,0)  -- {0, 3} 
 
new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu