응용프로그램 작성 도중 C#의 소수점 반올림 관련 코드에서 몇몇 자주 사용되는 기능들을 보완하는 코드를 작성하여 올려봅니다. 이 코드는 http://www.latiumsoftware.com/en/delphi/00033.php 의 코드를 바탕으로 작성된 것입니다.
namespace System
{
// Original Source: http://www.latiumsoftware.com/en/delphi/00033.php
public static class MathExtension
{
public static int Sign(
#if CS3
this
#endif // CS3
decimal x)
{
return Math.Sign(x);
}
public static int Sign(
#if CS3
this
#endif // CS3
double x)
{
return Math.Sign(x);
}
public static int Integer(
#if CS3
this
#endif // CS3
decimal x)
{
return (int)Math.Truncate(x);
}
public static int Integer(
#if CS3
this
#endif // CS3
double x)
{
return (int)Math.Truncate(x);
}
public static decimal Fraction(
#if CS3
this
#endif // CS3
decimal x)
{
return x - Math.Truncate(x);
}
public static double Fraction(
#if CS3
this
#endif // CS3
double x)
{
return x - Math.Truncate(x);
}
public static decimal RoundUp(
#if CS3
this
#endif // CS3
decimal x)
{
return Integer(x) + Sign(Fraction(x));
}
public static double RoundUp(
#if CS3
this
#endif // CS3
double x)
{
return Integer(x) + Sign(Fraction(x));
}
public static decimal RoundDown(
#if CS3
this
#endif // CS3
decimal x)
{
return Integer(x);
}
public static double RoundDown(
#if CS3
this
#endif // CS3
double x)
{
return Integer(x);
}
public static decimal Round(
#if CS3
this
#endif // CS3
decimal x)
{
return Integer(x) + Integer(Fraction(x) * 2m);
}
public static double Round(
#if CS3
this
#endif // CS3
double x)
{
return Integer(x) + Integer(Fraction(x) * 2d);
}
public static decimal Fix(
#if CS3
this
#endif // CS3
decimal x)
{
if (x >= 0m || Fraction(x) == 0m)
return Integer(x);
else
return Integer(x) - 1;
}
public static double Fix(
#if CS3
this
#endif // CS3
double x)
{
if (x >= 0d || Fraction(x) == 0d)
return Integer(x);
else
return Integer(x) - 1;
}
public static decimal RoundDownFix(
#if CS3
this
#endif // CS3
decimal x)
{
return Fix(x);
}
public static double RoundDownFix(
#if CS3
this
#endif // CS3
double x)
{
return Fix(x);
}
public static int Absolute(
#if CS3
this
#endif // CS3
int x)
{
return Math.Abs(x);
}
public static decimal RoundUpFix(
#if CS3
this
#endif // CS3
decimal x)
{
return Fix(x) + Absolute(Sign(Fraction(x)));
}
public static double RoundUpFix(
#if CS3
this
#endif // CS3
double x)
{
return Fix(x) + Absolute(Sign(Fraction(x)));
}
public static decimal RoundFix(
#if CS3
this
#endif // CS3
decimal x)
{
return Fix(x + 0.5m);
}
public static double RoundFix(
#if CS3
this
#endif // CS3
double x)
{
return Fix(x + 0.5d);
}
public static decimal RoundTo(
#if CS3
this
#endif // CS3
decimal x, int d)
{
decimal n = (decimal)Math.Pow(10, d);
x *= n;
return (Integer(x) + Integer(Fraction(x) * 2m)) / n;
}
public static double RoundTo(
#if CS3
this
#endif // CS3
double x, int d)
{
double n = Math.Pow(10, d);
x *= n;
return (Integer(x) + Integer(Fraction(x) * 2d)) / n;
}
}
}
사용 예시는 다음과 같습니다.
using System;
namespace ConsoleApplication1
{
public static class Program
{
[STAThread]
public static void Main(string[] args)
{
#if CS3
Console.WriteLine("{0}", (3.3m).RoundUp() == 4m);
Console.WriteLine("{0}", (-3.3m).RoundUp() == -4m);
Console.WriteLine("{0}", (3.7m).RoundDown() == 3m);
Console.WriteLine("{0}", (-3.7m).RoundDown() == -3m);
Console.WriteLine("{0}", (3.5m).Round() == 4m);
Console.WriteLine("{0}", (-3.5m).Round() == -4m);
Console.WriteLine("{0}", (3.1m).Round() == 3m);
Console.WriteLine("{0}", (-3.1m).Round() == -3m);
Console.WriteLine("{0}", (3.7m).Integer() == 3);
Console.WriteLine("{0}", (-3.7m).Integer() == -3);
Console.WriteLine("{0}", (3.7m).Fix() == 3m);
Console.WriteLine("{0}", (-3.7m).Fix() == -4m);
Console.WriteLine("{0}", (3.7m).RoundDownFix() == 3m);
Console.WriteLine("{0}", (-3.7m).RoundDownFix() == -4m);
Console.WriteLine("{0}", (3.1m).RoundDownFix() == 3m);
Console.WriteLine("{0}", (-3.1m).RoundDownFix() == -4m);
Console.WriteLine("{0}", (3.1m).RoundUpFix() == 4m);
Console.WriteLine("{0}", (-3.7m).RoundUpFix() == -3m);
Console.WriteLine("{0}", (3.5m).RoundFix() == 4m);
Console.WriteLine("{0}", (-3.5m).RoundFix() == -3m);
Console.WriteLine("{0}", (123.456m).RoundTo(0) == 123.00m);
Console.WriteLine("{0}", (123.456m).RoundTo(2) == 123.46m);
Console.WriteLine("{0}", (123456m).RoundTo(-3) == 123000m);
Console.WriteLine("{0}", (3.3d).RoundUp() == 4d);
Console.WriteLine("{0}", (-3.3d).RoundUp() == -4d);
Console.WriteLine("{0}", (3.7d).RoundDown() == 3d);
Console.WriteLine("{0}", (-3.7d).RoundDown() == -3d);
Console.WriteLine("{0}", (3.5d).Round() == 4d);
Console.WriteLine("{0}", (-3.5d).Round() == -4d);
Console.WriteLine("{0}", (3.1d).Round() == 3d);
Console.WriteLine("{0}", (-3.1d).Round() == -3d);
Console.WriteLine("{0}", (3.7d).Integer() == 3);
Console.WriteLine("{0}", (-3.7d).Integer() == -3);
Console.WriteLine("{0}", (3.7d).Fix() == 3d);
Console.WriteLine("{0}", (-3.7d).Fix() == -4d);
Console.WriteLine("{0}", (3.7d).RoundDownFix() == 3d);
Console.WriteLine("{0}", (-3.7d).RoundDownFix() == -4d);
Console.WriteLine("{0}", (3.1d).RoundDownFix() == 3d);
Console.WriteLine("{0}", (-3.1d).RoundDownFix() == -4d);
Console.WriteLine("{0}", (3.1d).RoundUpFix() == 4d);
Console.WriteLine("{0}", (-3.7d).RoundUpFix() == -3d);
Console.WriteLine("{0}", (3.5d).RoundFix() == 4d);
Console.WriteLine("{0}", (-3.5d).RoundFix() == -3d);
Console.WriteLine("{0}", (123.456d).RoundTo(0) == 123.00d);
Console.WriteLine("{0}", (123.456d).RoundTo(2) == 123.46d);
Console.WriteLine("{0}", (123456d).RoundTo(-3) == 123000d);
#else // !CS3
Console.WriteLine("{0}", MathExtension.RoundUp(3.3m) == 4m);
Console.WriteLine("{0}", MathExtension.RoundUp(-3.3m) == -4m);
Console.WriteLine("{0}", MathExtension.RoundDown(3.7m) == 3m);
Console.WriteLine("{0}", MathExtension.RoundDown(-3.7m) == -3m);
Console.WriteLine("{0}", MathExtension.Round(3.5m) == 4m);
Console.WriteLine("{0}", MathExtension.Round(-3.5m) == -4m);
Console.WriteLine("{0}", MathExtension.Round(3.1m) == 3m);
Console.WriteLine("{0}", MathExtension.Round(-3.1m) == -3m);
Console.WriteLine("{0}", MathExtension.Integer(3.7m) == 3);
Console.WriteLine("{0}", MathExtension.Integer(-3.7m) == -3);
Console.WriteLine("{0}", MathExtension.Fix(3.7m) == 3);
Console.WriteLine("{0}", MathExtension.Fix(-3.7m) == -4);
Console.WriteLine("{0}", MathExtension.RoundDownFix(3.7m) == 3m);
Console.WriteLine("{0}", MathExtension.RoundDownFix(-3.7m) == -4m);
Console.WriteLine("{0}", MathExtension.RoundDownFix(3.1m) == 3m);
Console.WriteLine("{0}", MathExtension.RoundDownFix(-3.1m) == -4m);
Console.WriteLine("{0}", MathExtension.RoundUpFix(3.1m) == 4m);
Console.WriteLine("{0}", MathExtension.RoundUpFix(-3.7m) == -3m);
Console.WriteLine("{0}", MathExtension.RoundFix(3.5m) == 4m);
Console.WriteLine("{0}", MathExtension.RoundFix(-3.5m) == -3m);
Console.WriteLine("{0}", MathExtension.RoundTo(123.456m, 0) == 123.00m);
Console.WriteLine("{0}", MathExtension.RoundTo(123.456m, 2) == 123.46m);
Console.WriteLine("{0}", MathExtension.RoundTo(123456m, -3) == 123000m);
Console.WriteLine("{0}", MathExtension.RoundUp(3.3d) == 4d);
Console.WriteLine("{0}", MathExtension.RoundUp(-3.3d) == -4d);
Console.WriteLine("{0}", MathExtension.RoundDown(3.7d) == 3d);
Console.WriteLine("{0}", MathExtension.RoundDown(-3.7d) == -3d);
Console.WriteLine("{0}", MathExtension.Round(3.5d) == 4d);
Console.WriteLine("{0}", MathExtension.Round(-3.5d) == -4d);
Console.WriteLine("{0}", MathExtension.Round(3.1d) == 3d);
Console.WriteLine("{0}", MathExtension.Round(-3.1d) == -3d);
Console.WriteLine("{0}", MathExtension.Integer(3.7d) == 3);
Console.WriteLine("{0}", MathExtension.Integer(-3.7d) == -3);
Console.WriteLine("{0}", MathExtension.Fix(3.7d) == 3);
Console.WriteLine("{0}", MathExtension.Fix(-3.7d) == -4);
Console.WriteLine("{0}", MathExtension.RoundDownFix(3.7d) == 3d);
Console.WriteLine("{0}", MathExtension.RoundDownFix(-3.7d) == -4d);
Console.WriteLine("{0}", MathExtension.RoundDownFix(3.1d) == 3d);
Console.WriteLine("{0}", MathExtension.RoundDownFix(-3.1d) == -4d);
Console.WriteLine("{0}", MathExtension.RoundUpFix(3.1d) == 4d);
Console.WriteLine("{0}", MathExtension.RoundUpFix(-3.7d) == -3d);
Console.WriteLine("{0}", MathExtension.RoundFix(3.5d) == 4d);
Console.WriteLine("{0}", MathExtension.RoundFix(-3.5d) == -3d);
Console.WriteLine("{0}", MathExtension.RoundTo(123.456d, 0) == 123.00d);
Console.WriteLine("{0}", MathExtension.RoundTo(123.456d, 2) == 123.46d);
Console.WriteLine("{0}", MathExtension.RoundTo(123456d, -3) == 123000d);
#endif // CS3
}
}
}
위의 코드에서 CS3 라는 매크로를 프로젝트 내에 설정하면 Extension Method로 사용할 수 있으며, 이 매크로의 선언을 해제하면 일반 정적 메서드로 변경하여 사용할 수 있습니다. 여러 메서드들이 있지만 그 중에서도 RoundTo 메서드는 사용 빈도가 매우 많은 함수일 듯 합니다. :-)
'Software Development > Useful Solutions' 카테고리의 다른 글
| 유용한 멀티 타기팅 팩: Portable Library Tools (1) | 2011/12/26 |
|---|---|
| ASP.NET과 IIS 7을 위한 로드 밸런싱 전략과 기초적인 이야기, 그리고 Azure Platform (0) | 2011/09/12 |
| C# 소수점 반올림 관련 보조 라이브러리 (0) | 2010/11/25 |
| 디자인 타임 컬렉션을 관리하는 데에 어려움이 있으십니까? (0) | 2010/11/01 |
| Client App Dev MVP가 엄선한 닷넷 개발 관련 무료 e-Book 7선 (0) | 2010/10/13 |
| Internet Explorer 9 설치에 문제가 있으신가요? (0) | 2010/09/16 |