[project @ 2001-08-20 11:41:13 by simonpj]
authorsimonpj <unknown>
Mon, 20 Aug 2001 11:41:13 +0000 (11:41 +0000)
committersimonpj <unknown>
Mon, 20 Aug 2001 11:41:13 +0000 (11:41 +0000)
Add two digits-of-e programs

imaginary/digits-of-e1/Main.lhs [new file with mode: 0644]
imaginary/digits-of-e1/Makefile [new file with mode: 0644]
imaginary/digits-of-e1/digits-of-e1.stdout [new file with mode: 0644]
imaginary/digits-of-e2/Main.lhs [new file with mode: 0644]
imaginary/digits-of-e2/Makefile [new file with mode: 0644]
imaginary/digits-of-e2/digits-of-e2.stdout [new file with mode: 0644]

diff --git a/imaginary/digits-of-e1/Main.lhs b/imaginary/digits-of-e1/Main.lhs
new file mode 100644 (file)
index 0000000..03cf541
--- /dev/null
@@ -0,0 +1,43 @@
+Compute the digits of "e" using continued fractions.
+Original program due to Dale Thurston, Aug 2001
+
+> module Main where
+
+> type ContFrac = [Integer]
+
+Compute the decimal representation of e progressively.
+
+A continued fraction expansion for e is
+
+[2,1,2,1,1,4,1,1,6,1,...]
+
+> eContFrac :: ContFrac
+> eContFrac = 2:aux 2 where aux n = 1:n:1:aux (n+2)
+
+We need a general function that applies an arbitrary linear fractional
+transformation to a legal continued fraction, represented as a list of
+positive integers.  The complicated guard is to see if we can output a
+digit regardless of what the input is; i.e., to see if the interval
+[1,infinity) is mapped into [k,k+1) for some k.
+
+> -- ratTrans (a,b,c,d) x: compute (a + bx)/(c+dx) as a continued fraction 
+> ratTrans :: (Integer,Integer,Integer,Integer) -> ContFrac -> ContFrac
+> -- Output a digit if we can
+> ratTrans (a,b,c,d) xs |
+>   ((signum c == signum d) || (abs c < abs d)) && -- No pole in range
+>   (c+d)*q <= a+b && (c+d)*q + (c+d) > a+b       -- Next digit is determined
+>      = q:ratTrans (c,d,a-q*c,b-q*d) xs
+>   where q = b `div` d
+> ratTrans (a,b,c,d) (x:xs) = ratTrans (b,a+x*b,d,c+x*d) xs
+
+Finally, we convert a continued fraction to digits by repeatedly multiplying by 10.
+
+> toDigits :: ContFrac -> [Integer]
+> toDigits (x:xs) = x:toDigits (ratTrans (10,0,0,1) xs)
+
+> e :: [Integer]
+> e = toDigits eContFrac
+
+> main = print (take 1000 e)
+
+
diff --git a/imaginary/digits-of-e1/Makefile b/imaginary/digits-of-e1/Makefile
new file mode 100644 (file)
index 0000000..53e5abe
--- /dev/null
@@ -0,0 +1,6 @@
+TOP = ../..
+include $(TOP)/mk/boilerplate.mk
+
+
+include $(TOP)/mk/target.mk
+
diff --git a/imaginary/digits-of-e1/digits-of-e1.stdout b/imaginary/digits-of-e1/digits-of-e1.stdout
new file mode 100644 (file)
index 0000000..cedbce7
--- /dev/null
@@ -0,0 +1 @@
+[2,7,1,8,2,8,1,8,2,8,4,5,9,0,4,5,2,3,5,3,6,0,2,8,7,4,7,1,3,5,2,6,6,2,4,9,7,7,5,7,2,4,7,0,9,3,6,9,9,9,5,9,5,7,4,9,6,6,9,6,7,6,2,7,7,2,4,0,7,6,6,3,0,3,5,3,5,4,7,5,9,4,5,7,1,3,8,2,1,7,8,5,2,5,1,6,6,4,2,7,4,2,7,4,6,6,3,9,1,9,3,2,0,0,3,0,5,9,9,2,1,8,1,7,4,1,3,5,9,6,6,2,9,0,4,3,5,7,2,9,0,0,3,3,4,2,9,5,2,6,0,5,9,5,6,3,0,7,3,8,1,3,2,3,2,8,6,2,7,9,4,3,4,9,0,7,6,3,2,3,3,8,2,9,8,8,0,7,5,3,1,9,5,2,5,1,0,1,9,0,1,1,5,7,3,8,3,4,1,8,7,9,3,0,7,0,2,1,5,4,0,8,9,1,4,9,9,3,4,8,8,4,1,6,7,5,0,9,2,4,4,7,6,1,4,6,0,6,6,8,0,8,2,2,6,4,8,0,0,1,6,8,4,7,7,4,1,1,8,5,3,7,4,2,3,4,5,4,4,2,4,3,7,1,0,7,5,3,9,0,7,7,7,4,4,9,9,2,0,6,9,5,5,1,7,0,2,7,6,1,8,3,8,6,0,6,2,6,1,3,3,1,3,8,4,5,8,3,0,0,0,7,5,2,0,4,4,9,3,3,8,2,6,5,6,0,2,9,7,6,0,6,7,3,7,1,1,3,2,0,0,7,0,9,3,2,8,7,0,9,1,2,7,4,4,3,7,4,7,0,4,7,2,3,0,6,9,6,9,7,7,2,0,9,3,1,0,1,4,1,6,9,2,8,3,6,8,1,9,0,2,5,5,1,5,1,0,8,6,5,7,4,6,3,7,7,2,1,1,1,2,5,2,3,8,9,7,8,4,4,2,5,0,5,6,9,5,3,6,9,6,7,7,0,7,8,5,4,4,9,9,6,9,9,6,7,9,4,6,8,6,4,4,5,4,9,0,5,9,8,7,9,3,1,6,3,6,8,8,9,2,3,0,0,9,8,7,9,3,1,2,7,7,3,6,1,7,8,2,1,5,4,2,4,9,9,9,2,2,9,5,7,6,3,5,1,4,8,2,2,0,8,2,6,9,8,9,5,1,9,3,6,6,8,0,3,3,1,8,2,5,2,8,8,6,9,3,9,8,4,9,6,4,6,5,1,0,5,8,2,0,9,3,9,2,3,9,8,2,9,4,8,8,7,9,3,3,2,0,3,6,2,5,0,9,4,4,3,1,1,7,3,0,1,2,3,8,1,9,7,0,6,8,4,1,6,1,4,0,3,9,7,0,1,9,8,3,7,6,7,9,3,2,0,6,8,3,2,8,2,3,7,6,4,6,4,8,0,4,2,9,5,3,1,1,8,0,2,3,2,8,7,8,2,5,0,9,8,1,9,4,5,5,8,1,5,3,0,1,7,5,6,7,1,7,3,6,1,3,3,2,0,6,9,8,1,1,2,5,0,9,9,6,1,8,1,8,8,1,5,9,3,0,4,1,6,9,0,3,5,1,5,9,8,8,8,8,5,1,9,3,4,5,8,0,7,2,7,3,8,6,6,7,3,8,5,8,9,4,2,2,8,7,9,2,2,8,4,9,9,8,9,2,0,8,6,8,0,5,8,2,5,7,4,9,2,7,9,6,1,0,4,8,4,1,9,8,4,4,4,3,6,3,4,6,3,2,4,4,9,6,8,4,8,7,5,6,0,2,3,3,6,2,4,8,2,7,0,4,1,9,7,8,6,2,3,2,0,9,0,0,2,1,6,0,9,9,0,2,3,5,3,0,4,3,6,9,9,4,1,8,4,9,1,4,6,3,1,4,0,9,3,4,3,1,7,3,8,1,4,3,6,4,0,5,4,6,2,5,3,1,5,2,0,9,6,1,8,3,6,9,0,8,8,8,7,0,7,0,1,6,7,6,8,3,9,6,4,2,4,3,7,8,1,4,0,5,9,2,7,1,4,5,6,3,5,4,9,0,6,1,3,0,3,1,0,7,2,0,8,5,1,0,3,8,3,7,5,0,5,1,0,1,1,5,7,4,7,7,0,4,1,7,1,8,9,8,6,1,0,6,8,7,3,9,6,9,6,5,5,2,1,2,6,7,1,5,4,6,8,8,9,5,7,0,3,5,0,3,5]
diff --git a/imaginary/digits-of-e2/Main.lhs b/imaginary/digits-of-e2/Main.lhs
new file mode 100644 (file)
index 0000000..0638bf8
--- /dev/null
@@ -0,0 +1,54 @@
+Compute digits of e
+Due to John Hughes, Aug 2001
+
+> module Main where
+
+Here's a way to compute all the digits of e. We use the series
+
+   e = 2  +  1  +  1  +  1  +  ...
+             --    --    --  
+             2!    3!    4!
+
+which we can think of as representing e as 2.11111... in a strange
+number system with a varying base. In this number system, the fraction
+0.abcd... represents
+
+             a  +  b  +  c  +  d  +  ...
+            --    --    --    --
+            2!    3!    4!    5!
+
+To convert such a fraction to decimal, we multiply by 10, take the
+integer part for the next digit, and continue with the fractional
+part. Multiplying by 10 is easy: we just multiply each "digit" by 10,
+and then propagate carries.
+
+The hard part is knowing how far carries might propagate: since we
+carry leftwards in an infinite expansion, we must be careful to avoid
+needing to inspect the entire fraction in order to decide on the first
+carry. But each fraction we work with is less than one, so after
+multiplying by 10, it is less than 10. The "carry out" from each digit
+can be at most 9, therefore. So if a carry of 9 from the next digit
+would not affect the carry out from the current one, then that carry
+out can be emitted immediately. Since the base soon becomes much
+larger than 10, then this is likely to happen quickly. No doubt there
+are much better ways than this of solving the problem, but this one
+works.
+
+> carryPropagate base (d:ds)
+>   | carryguess == (d+9) `div` base 
+>       = carryguess : (remainder+nextcarry) : fraction
+>   | otherwise
+>       = (dCorrected `div` base) : (dCorrected `mod` base) : fraction
+>   where carryguess = d `div` base
+>         remainder = d `mod` base
+>        nextcarry:fraction = carryPropagate (base+1) ds
+>         dCorrected = d + nextcarry
+
+> e :: String
+> e = ("2."++) $ 
+>     tail . concat $
+>     map (show.head) $
+>     iterate (carryPropagate 2 . map (10*) . tail) $
+>     2:[1,1..]
+
+> main = print (take 2000 e)
diff --git a/imaginary/digits-of-e2/Makefile b/imaginary/digits-of-e2/Makefile
new file mode 100644 (file)
index 0000000..53e5abe
--- /dev/null
@@ -0,0 +1,6 @@
+TOP = ../..
+include $(TOP)/mk/boilerplate.mk
+
+
+include $(TOP)/mk/target.mk
+
diff --git a/imaginary/digits-of-e2/digits-of-e2.stdout b/imaginary/digits-of-e2/digits-of-e2.stdout
new file mode 100644 (file)
index 0000000..5aad4e6
--- /dev/null
@@ -0,0 +1 @@
+"2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981"