我想采取类似1/7(0.142857142857 ...)的东西并将其转换为“0.142857142857”或“142857142857” [1,4,2,8,5,7,1 ,4,2,8,5,7]。使用
map ((+) (-48) . ord) . show
当分母很小但是分母较大时,Haskell开始使用科学记数法。如何将小数字一直转换为数字列表?
答案 0 :(得分:14)
这不是一个完整的解决方案,但它会让你开始。这将获得0到1之间的数字的数字列表。用适当的方法包装它以获得所需格式的输出。
digits :: (RealFrac a) => a -> [Int]
digits 0 = []
digits x = d : digits (10*x - fromIntegral d)
where
d = floor (10*x)
玩弄它:
ghci> digits (1/4)
[2,5]
ghci> digits (1/3)
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,7,2,7,3,8,6,0,0,9,
9,9,5,8,2,5,5,8,8,7,0,3,1,5,5,5,1,7,5,7,8,1,2,5]
-- rounding error got us, let's use an exact rational
ghci> import Data.Ratio
ghci> digits (1%3)
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
...
当然,您可以从无限的数字列表中获取前缀。
答案 1 :(得分:4)
例如,这将显示1/7到12位小数。它永远不会使用科学记数法。
Numeric.showFFloat (Just 12) (1/7) ""
答案 2 :(得分:1)
我想是直截了当的方式。
showDigits :: Int -> Double -> String
showDigits n x = show (floor x) ++ "." ++ showRest n x
showRest :: Int -> Double -> String
showRest n x | n <= 0 = ""
| otherwise = digitToInt dig : showRest (pred n) x'
where dig = (floor x') `mod` 10
x' = x * 10
但这只能与Double
表示一样精确。此外,它永远不会围绕最后的数字;它只是显示它(向下舍入)。测试:
ghci> showDigits 5 (1/7)
"0.14285"
答案 3 :(得分:0)
我想你需要Text.Printf.printf:
import Data.Char
import Text.Printf
getDigits :: Double -> [Int]
getDigits=map ((subtract 48).Data.Char.ord) . (Text.Printf.printf "%f")