Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Paul Rubin Newsgroups: comp.lang.forth Subject: Re: real to rational number Date: Wed, 19 Apr 2017 00:41:09 -0700 Organization: A noiseless patient Spider Lines: 53 Message-ID: <87zifcetey.fsf@nightsong.com> References: <87efwpf7cw.fsf@nightsong.com> <718428df-9808-4765-a9a1-48d43a971d24@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="47e0bd6af43efb397f12aac8c938d83c"; logging-data="12518"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18hpfNq3orKPTZHdL9sO4/x" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:Dv5ghFRz2Sr7xh3q6si7tU4GFfk= sha1:bmeDCEyjV1uoBPeGsPsVrPwXluY= Xref: csiph.com comp.lang.forth:57584 krishna.myneni@ccreweb.org writes: > Just so the problem is clear, I have a double precision value for r, > which means I know it to about 16 significant digits. I know r, with > infinite precision, is a rational number, but my machine > representation is a rounded version to the limited precision. Now, I > want to find "a" and "b" where r = a/b. Dividing the floating point > representations of a and b, ra and rb, should give me a number equal > to r in the machine representation. For the r you gave, it's 8/105 in 64-bit gforth: 7.61904761904762e-02 fvariable r 8e 105e f/ fvariable q q r f- f. => 0. ok If you want to find the ratio by continued fractions, here's Haskell code that I just wrote: import Data.Ratio import Control.Monad (forM_) r = 7.61904761904762e-02 -- turn real number into continued fraction sequence contFrac :: RealFrac a => a -> [Integer] contFrac x = a : contFrac (1/b) where (a,b) = properFraction x -- turn truncated continued fraction into a rational number unFrac :: Integral a => [a] -> Ratio Integer unFrac [c] = fromIntegral c unFrac (c:cs) = fromIntegral c + 1/unFrac cs -- make rational from first n terms of cont frac of a real approx :: RealFrac a => Int -> a -> Ratio Integer approx n x = unFrac . take n . contFrac $ x -- print first 4 rational approximations of r main = forM_ [1..4] $ \i -> do print (approx i r) The output for the first 4 terms is: *Main> main 0 % 1 1 % 13 8 % 105 70368744177665 % 923589767331853 You can see the 4th approximant is basically noise. The 5th is much worse noise, several dozen digits.