본문 바로가기

Haskell

숫자값 타입간의 형 변환

하스켈의 숫자 타입들

1 : Integral

Integral 타입 클래스는 소수점이 없는 숫자를 말하며 여기에는 IntegerInt 타입이 속한다.

  • Integer : 임의 정밀도를 가지는, 자리수의 제한을 받지 않는 숫자값
  • Int : 고정크기 정수로 64비트 정수

이러한 정수형으로부터의 변형은 fromIntegral 함수를 쓰며, 이는 임의의 Intergral 타입속의 값을 Num 타입속의 값으로 전환한다. (여기에는 Int, Integer, Rational, Double이 들어간다.)

fromIntegral :: (Num b, Integral a) => a -> b

예를 들어 Int 타입의 n이라는 값이 있고, 그 제곱근을 구하고자 한다면 sqrt n을 쓰고 싶어진다. 하지만 sqrt 함수는 Floating 족 타입에만 쓸 수 있고, 따라서 sqrt (fromIntegral n) 이라고 써서 명시적으로 n을 부동소수점 숫자로 변경해야 한다. Integer로부터 변환하는 케이스는 크게 세 경우가 있을 수 있다.

  1. fromInteger :: Num a => Integer -> a
  2. toInteger :: Integral a => a -> Integer

2 : real 과 real-fractional 타입간의 변형

RealFrac은 실수값을 나타내는 타입 클래스로 다음의 두 타입을 포함한다.

  • Rational : 임의 정밀도의 실수
  • Double : 배정밀도 실수

Real 타입은 IntegralRealFrac 타입을 합친 것이다. 이 이름인 real에서 이 타입에는 복소수를 나타내는 Complex는 제외된다는 것을 알 수 있다. 실수타입을 다른 형으로 변경하는 함수는 readToFrac으로 이는 임의의 Real 값을 Fractional 값으로 변경한다. (Fractional 타입은 RationalDouble을 포함한다.)

readToFrac :: (Real a, Fractional b) => a -> b

실수-유리수 값 타입 간의 변형도 가능하다. fromRational, toRational을 이용해서 배정밀도 실수값을 임의 정밀도 유리수로 변경할 수 있다.

fromRational :: Fractional a => Rational -> a
toRational :: Real a => a -> Rational

3 : 실수-유리수값을 정수형 숫자로 변환하기

유리수,실수 값을 정수로 변형하는 것은 전체 숫자가 다 변형되지 못하기 때문에 필수불가결하게 손실이 따르는 변형이 된다. 여기에는 다음의 네 가지 변형이 존재한다.

  • ceiling :: (RealFrac a, Integral b) => a -> b
  • floor :: (RealFrac a, Integral b) => a -> b
  • truncate :: (RealFrac a, Integral b) => a -> b
  • round :: (RealFrac a, Integral b) => a -> b

4 : 서로다른 정확도의 부동소수점값끼리 변환하기

FloatDouble간의 변화는 GHC.Float 모듈에 있는 함수에 의해서 변환한다.

  • float2Double :: Float -> Double
  • double2Float :: Double -> Float

5 : 자동 변환

엄격한 타입 체크 때문에 계산식에서 자동 변환 방법을 찾는 사람이 많이 있는데, 그건 별로 좋은 생각이 아니다. 대신에 제네릭 숫자 타입에 대해서 좀 연구해보시라.