div是整数除法。所以这意味着div 188 100,你得到:
Prelude> div 188 100
1
所以这意味着在 之后div,88是“走了”。此外div截断为负无穷大。结果,如果数字为负,我们得到:
Prelude> div (-210) 100
-3
但是您可能最好不要将数字转换为 a Float:Floats 无法精确表示十进制数:使用近似值。例如,如果您编写0.82,将存储一个看起来像的值0.8200000000000001(尽管这又不是确切的表示形式)。如果数字相当大,尾数并不总是能够代表整个数字,因此转换时可能会出现错误。最后,如果您打印小数或大数,默认情况下show将使用科学记数法(这当然不是“固有”的问题,但我认为如果您打印价格会很奇怪,我从未见过有标签的超市$ 9e-2):
Prelude> 0.01 :: Float
1.0e-2
这可能不是你想要的。
您可以简单地将数字分成三部分:小数点前的值和小数点后的两位数。喜欢:
import Data.Char(intToDigit)
formatDollars :: Price -> String
formatDollars pr = show pr0 ++ ['.', pr1, pr2]
where pr0 = quot pr 100
digit n = intToDigit (abs (rem n 10))
pr1 = digit (quot pr 10)
pr2 = digit pr
[ Decimalhackage]包也可能是一个选项。ADecimalRaw的表示方式是,对于十进制系统,它可以精确地表示数字。例如:
Prelude> import Data.Decimal
Prelude Data.Decimal> Decimal 2 188
1.88
所以我们可以避免所有的麻烦,写成这样:
import Data.Decimal(DecimalRaw(Decimal))
formatDollars :: Price -> String
formatDollars = show . Decimal 2