For*_*ost 11 double haskell rounding show
在程序中,我计算一个百分比并将其打印给用户.问题是打印的百分比显示的小数点太多.我搜索了一个解决这个问题的函数,没找到,并编写了下面的舍入函数,但我想知道是否有更标准的方法来代替.此外,这个Java主题中描述的想法非常简洁,如果已经有功能这样做,我很想知道.
roundTo :: (Integral int1, Integral int2) => int1 -> Double -> Either int2 Double
roundTo digitsAfterComma value
| (digitsAfterComma >= 1) =
let
factor = fromIntegral (10 ^ digitsAfterComma)
result = ((/ factor) . fromIntegral . round . (* factor)) value
in
Right result
| (digitsAfterComma == 0) = Left (round value)
| otherwise = error "minimal precision must be non-negative"
Run Code Online (Sandbox Code Playgroud)
更新:接下来是一个更完整的版本,这要归功于我收到的一些答案.
import qualified Text.Printf as T
showPercentage :: (Integral a, Show a) => a -> Double -> String
showPercentage digitsAfterComma fraction
| (digitsAfterComma >= 1) =
let formatString = "%." ++ (show digitsAfterComma) ++ "f%%"
in T.printf formatString percentage
| (digitsAfterComma == 0) =
let formatString = "%d%%"
in T.printf formatString (round percentage :: Int)
| otherwise = error "minimal precision must be non-negative"
where percentage = 100 * fraction
Run Code Online (Sandbox Code Playgroud)
chi*_*chi 11
> import Text.Printf
> printf "%.2f" 0.22324 :: String
"0.22"
Run Code Online (Sandbox Code Playgroud)
您可以使用大多数格式字符串C的printf支持.
但请记住,Haskell printf涉及一些复杂的类型类机制,并且可能会产生难以读取的类型错误.它也很通用,因为它也可以返回IO动作,即
> printf "%.2f" 0.22324 :: IO ()
0.22
Run Code Online (Sandbox Code Playgroud)
不返回字符串但直接打印它.我建议你:: String在每次调用之后总是添加一个类型注释(例如上面的内容)printf,除非从上下文中清楚什么是返回类型(例如在do具有其他IO操作的块中).
printf是可靠的,另一个值得了解的库是格式化(基于可爱的HoleyMonoid库):
Prelude Formatting> format ("to two decimal places: " % prec 2 % "!") 0.2222
"to two decimal places: 0.22!"
Run Code Online (Sandbox Code Playgroud)
请注意,这formatting是类型安全的,不同于printf:
Prelude Text.Printf Formatting> :t printf "%.2f" "hi"
printf "%.2f" "hi" :: PrintfType t => t
Prelude Text.Printf Formatting> printf "%.2f" "hi"
*** Exception: printf: bad formatting char 'f'
Prelude Text.Printf Formatting> :t format (prec 2) "hi"
-- type error
Run Code Online (Sandbox Code Playgroud)