div
- это целое число деление.Таким образом, это означает, что div 188 100
, вы получите:
Prelude> div 188 100
1
Так что это означает, что после div
, 88
исчезает.Кроме того div
усекает до отрицательной бесконечности.В результате, если число отрицательное, мы получаем:
Prelude> div (-210) 100
-3
Но вам, вероятно, лучше не преобразовывать число в Float
в любом случае: Float
s не способны точно представлять десятичные числа: приближенияиспользуются.Например, если вы напишите 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
Пакет Decimal
[hackage] также может быть вариантом.DecimalRaw
представляется таким образом, что для десятичной системы 1035 * он может точно представлять числа.Например:
Prelude> import Data.Decimal
Prelude Data.Decimal> Decimal 2 188
1.88
Таким образом, мы можем избежать всех неприятностей и написать это как:
import Data.Decimal(DecimalRaw(Decimal))
formatDollars :: Price -> String
formatDollars = show . Decimal 2