haskell에서 정수 리터럴을 이진 또는 16 진수로 출력하는 방법은 무엇입니까?


2 Answers

NumericData.Char 모듈을 가져 오는 경우 다음을 수행 할 수 있습니다.

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

이것은 intToDigit 작동하기 때문에 16까지의 기지에서 작동 할 것입니다. 위의 예제에서 여분의 빈 문자열 인수가 사용되는 showIntAtBaseshowIntAtBase 가 표시 표현을 기존 문자열에 연결하는 ShowS 유형의 함수를 반환하기 때문입니다.

Question

haskell에서 정수 리터럴을 이진 또는 16 진수로 출력하는 방법은 무엇입니까?

printBinary 5 => "0101"

printHex 5 => "05"

어떤 라이브러리 / 함수가 이것을 허용합니까?

Numeric 모듈과 showIntAtBase 함수를 보았지만 제대로 사용할 수 없었습니다.

> :t showIntAtBase 

showIntAtBase :: (Integral a) => a -> (Int -> Char) -> a -> String -> String



다음과 같이 자신 만의 재귀 함수를 정의 할 수 있습니다.

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- 값을 10 진수로 변환합니다. 매핑 함수는 특수 문자를 10 진수 값 (예 : A = 10, B = 11, ... 16 진수)으로 매핑합니다. 바이너리 매핑의 경우 binToDec에서 보듯이 람다 식을 사용할 수도 있습니다.

반면 toKBaseVal 함수는 반대이며 십진수를 k 기반 값으로 변환합니다. 다시 우리는 역함수를 나타내는 매핑 함수가 필요합니다. 십진수부터 k- 기반 값의 해당 특수 문자까지입니다.

테스트로 다음을 입력 할 수 있습니다.

binToDec(decToBin 7) = 7

십진수에서 8 진수로 변환한다고 가정 해보십시오.

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

다시 말하지만, 매핑은 간단하기 때문에 람다 표현식을 사용합니다.

희망이 도움이됩니다! 좋은 프로그래밍!




16 진수는 0x 와 접두어가 0b 이진수로 쓰여질 수 있습니다 :

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

바이너리에는 BinaryLiterals 확장이 필요합니다.



Related