如何在二进制或hex中打印整数文字在哈斯克尔?
如何在二进制或hex中打印整数文字在哈斯克尔?
printBinary 5 => "0101" printHex 5 => "05"
哪些库/函数允许这个?
我遇到了Numeric模块及其showIntAtBase函数,但无法正确使用它。
> :t showIntAtBase showIntAtBase :: (Integral a) => a -> (Int -> Char) -> a -> String -> String
数字模块包含几个函数,用于在不同的基础上显示Integraltypes ,包括showIntAtBase
。 以下是一些使用示例:
import Numeric (showHex, showIntAtBase) import Data.Char (intToDigit) putStrLn $ showHex 12 "" -- prints "c" putStrLn $ showIntAtBase 2 intToDigit 12 "" -- prints "1100"
如果你导入Numeric
和Data.Char
模块,你可以这样做:
showIntAtBase 2 intToDigit 10 "" => "1010" showIntAtBase 16 intToDigit 1023 "" => "3ff"
这将适用于任何基地高达16,因为这是所有intToDigit
作品。 上述示例中额外的空string参数的原因是showIntAtBase
返回一个showIntAtBase
types的ShowS
,它将显示表示连接到一个现有的string。
您还可以使用printf包的printf格式化您的输出与c风格格式描述符:
import Text.Printf main = do let i = 65535 :: Int putStrLn $ printf "The value of %d in hex is: 0x%08x" ii putStrLn $ printf "The html color code would be: #%06X" i putStrLn $ printf "The value of %d in binary is: %b" ii
输出:
hex中的65535的值是:0x0000ffff
html颜色代码将是:#00FFFF
二进制中的65535的值是:1111111111111111
您可以将整数转换为二进制,如下所示:
decToBin x = reverse $ decToBin' x where decToBin' 0 = [] decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
GHCi中的用法:
Prelude> decToBin 10 [1,0,1,0]
hex可以写入0x
和二进制前缀为0b
例如:
> 0xff 255 >:set -XBinaryLiterals > 0b11 3
请注意,二进制文件需要BinaryLiterals
扩展名。
你可以定义你自己的recursion函数,如:
import Data.Char (digitToInt) import Data.Char (intToDigit) -- generic function from base to decimal toNum :: [Char] -> Int -> (Char -> Int) -> Int toNum [] base map = 0 toNum s base map = base * toNum (init(s)) base map + map(last(s)) -- generic function from decimal to base k toKBaseNum :: Int -> Int -> (Int -> Char) -> [Char] toKBaseNum x base map | x < base = [map x] | otherwise = toKBaseNum (x `div` base) base map ++ [map(x `mod` base)] -- mapping function for hex to decimal mapHexToDec :: Char -> Int mapHexToDec x | x == 'A' = 10 | x == 'B' = 11 | x == 'C' = 12 | x == 'D' = 13 | x == 'E' = 14 | x == 'F' = 15 | otherwise = digitToInt(x) :: Int -- map decimal to hex mapDecToHex :: Int -> Char mapDecToHex x | x < 10 = intToDigit(x) | x == 10 = 'A' | x == 11 = 'B' | x == 12 = 'C' | x == 13 = 'D' | x == 14 = 'E' | x == 15 = 'F' -- hex to decimal hexToDec :: String -> Int hexToDec [] = 0 hexToDec s = toNum s 16 mapHexToDec -- binary to decimal binToDec :: String -> Int binToDec [] = 0 binToDec s = toNum s 2 (\x -> if x == '0' then 0 else 1) -- decimal to binary decToBin :: Int -> String decToBin x = toKBaseNum x 2 (\x -> if x == 1 then '1' else '0') -- decimal to hex decToHex :: Int -> String decToHex x = toKBaseNum x 16 mapDecToHex
说明:如您所见, toNum函数使用给定的基数和映射函数将基于k的值转换为十进制数。 映射函数将特殊字符映射为十进制值(例如,A = 10,B = 11,…,hex)。 对于二进制映射,您也可以使用像在binToDec中看到的lambdaexpression式。
而toKBaseVal函数则相反,将小数转换为基于k的值。 再一次,我们需要一个映射函数,它相反:从十进制到基于k值的对应特殊字符。
作为一个testing,你可以input:
binToDec(decToBin 7) = 7
假设你想从十进制转换为八进制:
-- decimal to octal decToOct :: Int -> String decToOct x = toKBaseNum x 8 (\x -> intToDigit(x))
再次,我只使用一个lambdaexpression式,因为映射是简单的:只是int到数字。
希望有所帮助! 好编程!