Comment imprimer des littéraux entiers en binary ou hexadécimal dans un haskell?

Comment imprimer des littéraux entiers en binary ou hexadécimal dans un haskell?

printBinary 5 => "0101" printHex 5 => "05" 

Quelles bibliothèques / fonctions permettent cela?

Je suis tombé sur le module numérique et sa fonction showIntAtBase mais je n’ai pas pu l’utiliser correctement.

 > :t showIntAtBase showIntAtBase :: (Integral a) => a -> (Int -> Char) -> a -> Ssortingng -> Ssortingng 

Le module numérique comprend plusieurs fonctions permettant d’afficher un type Integral sur différentes bases, y compris showIntAtBase . Voici quelques exemples d’utilisation:

 import Numeric (showHex, showIntAtBase) import Data.Char (intToDigit) putStrLn $ showHex 12 "" -- prints "c" putStrLn $ showIntAtBase 2 intToDigit 12 "" -- prints "1100" 

Si vous importez les modules Numeric et Data.Char , vous pouvez le faire:

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

Cela fonctionnera pour toutes les bases jusqu’à 16, car c’est tout ce pour quoi intToDigit travaille. La raison de l’argument de chaîne vide supplémentaire dans les exemples ci-dessus est que showIntAtBase renvoie une fonction de type ShowS , qui concaténera la représentation d’affichage sur une chaîne existante.

Vous pouvez également utiliser printf du package printf pour formater votre sortie avec des descripteurs de format de style 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 

Sortie:

La valeur de 65535 en hex est: 0x0000ffff
Le code couleur html serait: # 00FFFF
La valeur de 65535 en binary est: 1111111111111111

Vous pouvez convertir un entier en binary avec quelque chose comme ceci:

 decToBin x = reverse $ decToBin' x where decToBin' 0 = [] decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a 

utilisation dans GHCi:

 Prelude> decToBin 10 [1,0,1,0] 

Hex peut être écrit avec 0x et binary avec le préfixe 0b par exemple:

 > 0xff 255 >:set -XBinaryLiterals > 0b11 3 

Notez que binary requirejs l’extension BinaryLiterals .

Vous pouvez définir vos propres fonctions récursives comme:

 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 :: Ssortingng -> Int binToDec [] = 0 binToDec s = toNum s 2 (\x -> if x == '0' then 0 else 1) -- decimal to binary decToBin :: Int -> Ssortingng decToBin x = toKBaseNum x 2 (\x -> if x == 1 then '1' else '0') -- decimal to hex decToHex :: Int -> Ssortingng decToHex x = toKBaseNum x 16 mapDecToHex 

Explication: Comme vous pouvez le voir, la fonction toNum convertit une valeur basée sur k en décimale, en utilisant la base donnée et une fonction de mappage. La fonction de mappage mappera les caractères spéciaux à une valeur décimale (par exemple, A = 10, B = 11, … en hexadécimal). Pour le mappage binary, vous pouvez également utiliser une expression lambda comme vous le voyez dans binToDec.

Alors que la fonction toKBaseVal est l’inverse, convertir un décimal en valeur basée sur k. Encore une fois, nous avons besoin d’une fonction de mappage qui fait le contraire: d’un caractère décimal au caractère spécial correspondant de la valeur basée sur k.

En tant que test, vous pouvez taper:

 binToDec(decToBin 7) = 7 

Supposons que vous souhaitiez convertir de décimal en octal:

 -- decimal to octal decToOct :: Int -> Ssortingng decToOct x = toKBaseNum x 8 (\x -> intToDigit(x)) 

Encore une fois, j’utilise juste une expression lambda, car le mappage est simple: juste pour numériser.

J’espère que cela pourra aider! Bonne programmation!