Math vs. C# Math

[제목] Math vs. C# Math

수학적 공식을 C#에서 그대로 표현했을 때, 간혹 잘못된 결과를 산출하는 경우가 있다. 이 아티클에서는 간단한 예제를 통해 이러한 경우를 살펴보고, 어떤 방식으로 문제를 파악할 수 있는지 그 접근 방식을 설명한다.

섭씨를 화씨로 변화하는 수학적 공식은 다음과 같다.

°F = °C × 9/5 + 32

이를 C# 코드로 작성하면 아래와 같이 표현할 수 있다.

double C = 25.50;

double F = C * 9 / 5 + 32;  // 표현(A)

Console.WriteLine(F); // 77.90F

하지만 만약 다음과 같이 표현하면 어떤 결과가 나올까?

double F = C * (9 / 5) + 32;  // 표현(B)

수학적으로 위 표현(B)는 표현(A)와 동일한 식이다. 하지만, C#에서 표현(B)는 잘못된 결과를 산출한다. 즉, 표현(A)는 77.9F를 산출하는데 반해, 표현(B)는 57.5F 라는 틀린 값을 산출한다.

원인을 좀 더 자세히 알아보기 위해 (물론 이미 짐작하는 분들도 계시겠지만^^) 표현(B) 식을 여러 라인으로 풀어서 살펴 볼 수 있는데, 이때 아주 유용한 C# 키워드가 var 이다. var는 C# 데이타타입을 컴파일러가 추론해서 알아서 정하게 하는데, 따라서 개발자가 특정 타입으로 지정해서 암묵적으로 타입 변환이 일어나는 것을 방지하는 효과가 있다. 위 표현(B)식은 다음과 같은 방식으로 순차적으로 풀어서 표현할 수 있다.

 
var a = 9 / 5;   // (9 / 5)
var b = C * a;   // C * (9 / 5)
var F = b + 32;  // C * (9 / 5) + 32

여기서 한가지 주목할 것은 변수 a가 정수형 타입이 된다는 것이다. 즉, 정수 truncation이 일어나서 1.8 대신 1이 되는 것이다.

C# 정수 Truncation 효과

변수 a 를 var로 지정했으므로, 변수 a가 컴파일러에 의해 int로 인식된다는 것을 알 수 있다. 위의 공식은 상대적으로 간단한 것이지만, 복잡한 수학 공식의 경우 이렇게 var를 사용해서 식을 풀어서 나열해 보면 어떤 타입으로 계산되는지 쉽게 파악할 수 있다.

표현(B)를 올바르게 고치는 방법은 비교적 간단하다. 즉, (9 / 5)가 정수형으로 인식되지 않게 하기 위해 (9.0 / 5) 혹은 (9.0 / 5.0) 등으로 표현하면, 적어도 하나의 피연산자가 double 이 되므로 연산결과는 double로 된다.



본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.