Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite lazy lists of digits

So I'm trying to do some number theory work, and I was using Mathematica but thought that Haskell would be more suited to dealing with infinite lists (as AFAIK Mathematica doesn't have lazy evaluation). What I want to do is have Haskell store all the digits of 1/x in an infinite lazy list. So far my searching has not turned up a way to split a ratio into its digits that returns a list of digits rather than an actual floating point number.

like image 683
gallabytes Avatar asked Jan 14 '14 20:01

gallabytes


People also ask

Can Haskell have infinite list?

As you all know, lists in Haskell can be infinite. This capability is a natural consequence of Haskell's lazy evaluation. An infinite list in Haskell is no problem since Haskell will lazily generate only as much of the list as is needed, when it is needed.

How do you make an infinite list in Haskell?

But in Haskell, you only need to allocate space for the items in the list that actually get evaluated. The two most basic functions for creating an infinite list are "repeat" and "cycle". The first makes an infinite number of the same element, while the second allows you to cycle through a specific series of elements.


2 Answers

We can also implement this as a simple stream producer:

divDigits :: Int -> Int -> [Int]
divDigits x y = x `div` y : divDigits (10 * (x `mod` y)) y

There are actually libraries for this kind of "infinite"-precision number representation using lazy lists, see Haskell Wiki.

like image 168
Peter Wortmann Avatar answered Oct 17 '22 16:10

Peter Wortmann


Big thanks to Sam Yonnou, the link he provided had the right formula
The formula used:
the nth digit of x/y is the 1st digit of (10^(n-1)*x mod y)/y = floor(10 * (10^(n-1)*x mod y) / y) mod 10

The ending code looked like this:

nDigRat :: Int -> Int -> Int -> Int
nDigRat num denom n = floor (fromIntegral (10*(10^(n-1)*num `rem` denom)) / 
                             fromIntegral denom) 
                      `rem` 10

decExpansionRecipRat :: Int -> [Int]
decExpansionRecipRat n = map (nDigRat 1 n) [1..]
like image 38
gallabytes Avatar answered Oct 17 '22 14:10

gallabytes