개발/C#&unity

C# 반올림, 올림, 버림

로 얄 2024. 3. 9. 21:16
반응형

올림

Math.Ceiling(double a) 사용

double[] numbers = {1.0d, 1.1d, 1.2d, 1.3d, 1.4d, 1.5d, 1.6d, 1.7d, 1.8d, 1.9d};

foreach (var number in numbers)
{
    Console.WriteLine($"{number} => {Math.Ceiling(number)}");
}

// output
1 => 1
1.1 => 2
1.2 => 2
1.3 => 2
1.4 => 2
1.5 => 2
1.6 => 2
1.7 => 2
1.8 => 2
1.9 => 2

 

버림

Math.Truncate(double a) 사용

double[] numbers = {1.0d, 1.1d, 1.2d, 1.3d, 1.4d, 1.5d, 1.6d, 1.7d, 1.8d, 1.9d};

foreach (var number in numbers)
{
    Console.WriteLine($"{number} => {Math.Truncate(number)}");
    // Console.WriteLine($"{number} => {(int)number}"); // 결과 동일
}

// output
1 => 1
1.1 => 1
1.2 => 1
1.3 => 1
1.4 => 1
1.5 => 1
1.6 => 1
1.7 => 1
1.8 => 1
1.9 => 1

사실 버림의 경우 Trucate함수를 사용하기보단 int 형변환을 통해 버리는 방식을 더 많이 사용하고 있는 것 같다.

 

반올림

Math.Round(double a) 사용

double[] numbers = {2.0d, 2.1d, 2.2d, 2.3d, 2.4d, 2.5d, 2.6d, 2.7d, 2.8d, 2.9d};

foreach (var number in numbers)
{
    Console.WriteLine($"{number} => {Math.Round(number)}");
}

// output
2 => 2
2.1 => 2
2.2 => 2
2.3 => 2
2.4 => 2
2.5 => 2  ???
2.6 => 3
2.7 => 3
2.8 => 3
2.9 => 3

 

반올림의 경우 뭔가 이상한게 끼어있는 것을 확인할 수 있다.

2.5의 반올림은 2???

조사를 해보니 해당 메소드에는 추가적인 파라존재했다. MidpointRounding이라는 enum값인데 상세 내용은 아래와 같다.

0 ToEven : 가장 가까운 숫자로 반올림하는 전략이며, 숫자가 다른 두 숫자 사이의 중간이면 가장 가까운 짝수로 반올림됩니다.

1 AwayFromZero : 가장 가까운 숫자로 반올림하는 전략이며, 숫자가 다른 두 숫자 사이에 중간이면 0에서 멀리 떨어진 가장 가까운 숫자로 반올림됩니다.

2 ToZero : 결과가 무한정 정확한 결과보다 더 가깝고 크기가 크지 않은 0으로 반올림하는 전략입니다.

3 ToNegativeInfinity : 결과가 가장 가깝고 무한정 정확한 결과보다 크지 않은 하향 방향 반올림 전략입니다.

4 ToPositiveInfinity : 결과가 무한정 정확한 결과에 가장 가깝고 보다 작지 않은 상향 지향 반올림 전략입니다.

 

Math.Round의 기본값은 ToEven이기 때문에 2.5 = 2로 짝수쪽으로 반올림이 된다. 만약 1.5였다면 2로 올라가 이질감을 느끼지 못했을 것이다.

decimal result;

// Round a positive value using different strategies.
// The precision of the result is 1 decimal place.

result = Math.Round(3.45m, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result} = Math.Round({3.45m}, 1, MidpointRounding.ToEven)");
result = Math.Round(3.45m, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result} = Math.Round({3.45m}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(3.47m, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result} = Math.Round({3.47m}, 1, MidpointRounding.ToZero)\n");

// Round a negative value using different strategies.
// The precision of the result is 1 decimal place.

result = Math.Round(-3.45m, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result} = Math.Round({-3.45m}, 1, MidpointRounding.ToEven)");
result = Math.Round(-3.45m, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result} = Math.Round({-3.45m}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(-3.47m, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result} = Math.Round({-3.47m}, 1, MidpointRounding.ToZero)\n");

/*
This code example produces the following results:

3.4 = Math.Round(3.45, 1, MidpointRounding.ToEven)
3.5 = Math.Round(3.45, 1, MidpointRounding.AwayFromZero)
3.4 = Math.Round(3.47, 1, MidpointRounding.ToZero)

-3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
-3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
-3.4 = Math.Round(-3.47, 1, MidpointRounding.ToZero)
*/

위는 마소 에 나온 예시 코드를 붙여왔다. 

개인적으로 생각하는 반올림이란 AwayFromZero옵션으로 생각되지만 상황 혹은 필요에 따라 옵션을 활용하면 좋을 것으로 보여진다.

 

references

* https://learn.microsoft.com/ko-kr/dotnet/api/system.midpointrounding?view=net-8.0

 

MidpointRounding 열거형 (System)

수학적 반올림 메서드가 숫자를 반올림하는 데 사용해야 하는 전략을 지정합니다.

learn.microsoft.com

 

반응형