1

これは非常に単純なコードです。整数を取り、商と剰余を使用して10進数を分解します。呼び出しごとに、r文字の「I」(rは最後の桁)を含む行を出力し、商を新しい引数として呼び出します。

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

10桁未満の数値では正しく機能しますが、10桁以上の場合は出力をスクランブルします。私は何を間違っているのですか、そしてなぜそれがこのように機能するのですか?出力の例を次に示します。最初の例は正しく、2番目の例は間違っています。

*Main> decToUnary 5432
II
III
IIII
IIIII

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

1 に答える 1

13

これは整数のオーバーフローの質問です。maxBound :: Intは2147483647(32ビットマシンの場合)であるため、それより大きい値はオーバーフローします。

Integerの代わりに使用するIntIntegerは固定長整数ではないため、オーバーフローしません。

編集:take r "IIIIIIIIII"アプリケーションノートとして、take (fromIntegral r) "IIIIIIIIII"またはgenericTake r "IIIIIIIIII";に置き換える必要があります。私は好きgenericReplicate r 'I'です。

genericTakegenericReplicateは両方ともData.Listにあります。

于 2013-03-01T19:37:12.087 に答える