这是自计算机问世以来人们一直存在的标准问题,因此它可以通过古老的printf
(Haskell基本上是从C中复制过来的)完美解决。
import Text.Printf
formatPence = printf "%.2f" . (/100) . fromIntegral
哦,需要注意的是...对于非常大的数值,这个方法存在精度问题,因为该方法中隐式使用了Double
来进行除法运算,而Double
的分辨率没有Int
高。
Prelude Text.Printf> formatPence 10000000000000013
"100000000000000.13"
Prelude Text.Printf> formatPence 100000000000000013
"1000000000000000.10"
Prelude Text.Printf> formatPence 1000000000000000013
"10000000000000000.00"
所以如果你处理的金额达到数万亿美元,最好不要使用这个方法。
(我猜如果你正在处理这么多的金额,你可能不会在这里询问这个问题...而且你也不会使用Int
。)
要解决这个问题,你可以使用原始方法,但仍然使用printf
来格式化多余的零:
type Price' = Integer
formatPence' :: Price' -> String
formatPence' a = show (a `div` 100) ++ "." ++ printf "%02u" (a `mod` 100)
这将能够处理任意荒谬的数量:
> formatPence' 1000000000000000103
"10000000000000001.03"
> formatPence' 6529857623987620347562395876204395876395762398417639852764958726398527634972365928376529384
"65298576239876203475623958762043958763957623984176398527649587263985276349723659283765293.84"
请注意,手动计算除余数(div/mod)在处理负数情况下会出现问题,但这很容易解决。
(\f -> showFFloat (Just 2) f "") :: Float -> String
- jlwoodwa