- jtos' n' cs'
- | n' < 10 = case unsafeChr (ord '0' + fromInteger n') of
- c@(C# _) -> c:cs'
- | otherwise = case unsafeChr (ord '0' + fromInteger r) of
- c@(C# _) -> jtos' q (c:cs')
+ jtos' n cs
+ | n < BASE = jhead (fromInteger n) cs
+ | otherwise = jprinth (jsplitf (BASE*BASE) n) cs
+
+ -- Split n into digits in base p. We first split n into digits
+ -- in base p*p and then split each of these digits into two.
+ -- Note that the first 'digit' modulo p*p may have a leading zero
+ -- in base p that we need to drop - this is what jsplith takes care of.
+ -- jsplitb the handles the remaining digits.
+ jsplitf :: Integer -> Integer -> [Integer]
+ jsplitf p n
+ | p > n = [n]
+ | otherwise = jsplith p (jsplitf (p*p) n)
+
+ jsplith :: Integer -> [Integer] -> [Integer]
+ jsplith p (n:ns) =
+ if q > 0 then fromInteger q : fromInteger r : jsplitb p ns
+ else fromInteger r : jsplitb p ns
+ where
+ (q, r) = n `quotRemInteger` p
+
+ jsplitb :: Integer -> [Integer] -> [Integer]
+ jsplitb p [] = []
+ jsplitb p (n:ns) = q : r : jsplitb p ns
+ where
+ (q, r) = n `quotRemInteger` p
+
+ -- Convert a number that has been split into digits in base BASE^2
+ -- this includes a last splitting step and then conversion of digits
+ -- that all fit into a machine word.
+ jprinth :: [Integer] -> String -> String
+ jprinth (n:ns) cs =
+ if q > 0 then jhead q $ jblock r $ jprintb ns cs
+ else jhead r $ jprintb ns cs