考虑这个简短的 GHCi 会议:
ghci> import Data.Ratio
ghci> import Data.Word
ghci> 128 % 3 + 127 % 3 :: Ratio Word8
253 % 9
为什么结果是
253 % 9
而不是255 % 3 (= 85 % 1)
?
这确实是我的问题,但我很乐意详细说明。
首先,如果我删除类型,结果就是我所期望的:
ghci> 128 % 3 + 127 % 3
85 % 1
类型
Word8
似乎很重要。我知道潜在的整数溢出,但即便如此,我也无法理解结果。例如
ghci> 128 + 127 :: Word8
255
这里没有溢出。这首先发生在
ghci> 128 + 128 :: Word8
0
ghci> 128 + 129 :: Word8
1
如果我除以二而不是三,我仍然可以理解结果:
ghci> 128 % 2 + 127 % 2 :: Ratio Word8
255 % 2
ghci> 128 % 2 + 128 % 2 :: Ratio Word8
128 % 1
ghci> 128 % 2 + 129 % 2 :: Ratio Word8
1 % 2
ghci> 129 % 2 + 129 % 2 :: Ratio Word8
1 % 1
这里
128 % 2 + 128 % 2
甚至会产生 128 % 1
正如人们所希望的那样。所有这些似乎都作为“正常”模 256 算术完全有意义,但是当我以三分之一而不是一半计算时会发生什么?为什么分母是9
?
这是因为有理数的加法定义为
(x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
由于这里的一切都是
Word8
,所以每个操作都是单独执行的mod 256
。
(128*3) `mod` 256 = 128
(127*3) `mod` 256 = 125
(128+125) `mod` 256 = 253