如何在二进制或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" 

如果你导入NumericData.Char模块,你可以这样做:

 showIntAtBase 2 intToDigit 10 "" => "1010" showIntAtBase 16 intToDigit 1023 "" => "3ff" 

这将适用于任何基地高达16,因为这是所有intToDigit作品。 上述示例中额外的空string参数的原因是showIntAtBase返回一个showIntAtBasetypes的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到数字。

希望有所帮助! 好编程!