enrique
enrique

Reputation: 512

Scrambled number conversion for numbers with 10 or more digits

This is a quite simple piece of code. It takes an integer and decomposes its decimal digits using quotient and remainder. On each call, it prints a line with r characters 'I', where r is the last digit, then calls itself with the quotient as its new argument.

decToUnary 0 = return ()
decToUnary n = let (q, r) = quotRem n 10 in 
    do  
      putStrLn (take r "IIIIIIIIII")
      decToUnary q

It works correctly for numbers with less than 10 digits, but for 10 or more digits it scrambles the output. What am I doing wrong, and why does it work this way? Here are some examples of output, the first is correct, the second is wrong:

*Main> decToUnary 5432
II
III
IIII
IIIII

*Main> decToUnary 5432101234
IIIIIIII
III
IIIIIIIII
III
III
I
IIIIIII
III
I
I

Upvotes: 1

Views: 281

Answers (1)

dave4420
dave4420

Reputation: 47062

This is an integer overflow question. maxBound :: Int is 2147483647 (on 32-bit machines), so values greater than that overflow.

Use Integer instead of Int: Integer is not a fixed length integer so it won't overflow.

Edit: As applicative notes, you will then need to replace the take r "IIIIIIIIII" with take (fromIntegral r) "IIIIIIIIII" or genericTake r "IIIIIIIIII"; I'd prefer genericReplicate r 'I'.

genericTake and genericReplicate are both in Data.List.

Upvotes: 13

Related Questions