부동소수점 처리 질문

double (과 float)은 {부호, 정수, exponent }로 이뤄진 반면,
decimal 은 {부호, 정수, fractional factor} 로 이뤄져 구성 방식이 다릅니다.

이 구성 방식이 둘 사이의 정밀도 차이보다 훨씬 중요한 차이입니다.

double 의 구성 방식은 간편하기는 하지만, 정확한 소수 값을 가리킬 수 없는 한계가 있습니다. 즉, 아래 코드에서 d 가 가진 데이터는 정확히 0.1을 가리키지 못합니다.

double d = 0.1d;

여기에 2를 곱해본 들, 그 결과 역시 정확히 0.2 를 가리키지 못합니다.

decimal 은 이러한 float, double 의 한계를 해결하기 위해 탄생한 형식이라, 아래의 m은 정확히 0.1을 가리킵니다.

decimal m = 0.1m;

여기에 2를 곱한 결과도 정확히 0.2를 가리킵니다.

double d = 0;
decimal m = 0;

for (int i = 1; i <= 10; i++)
{
   d += 0.1d; 
   m += 0.1m;   
}

// d : 0.99999...
// m : 1

decimal은 한 마디로 금융 계산을 위해서 태어난 것이라 할 수 있어, decimal을 사용하는 게 좋습니다. (속도는 느리지만요)

다만, decimal.ToString() 에는 trailing zero가 포함되는 경우가 있습니다.

var mString = m.ToString(); // mString: "1.00"

이 경우, m이 가진 00 은 산술 계산에 영향을 미치지 않지만, Api 가 문자열에 포함된 trailing zero 에 대해 에러를 뱉어내면 보내기 전에 제거해야 합니다.

9개의 좋아요