728x90
728x170
■ 실수 확장(double extension) 기능을 사용하는 방법을 보여준다.
▶ DoubleExtension.cs
using System;
using System.Runtime.InteropServices;
namespace TestProject
{
/// <summary>
/// 실수 확장
/// </summary>
public static class DoubleExtension
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Structure
////////////////////////////////////////////////////////////////////////////////////////// Private
#region NAN 유니온 - NANUnion
/// <summary>
/// NAN 유니온
/// </summary>
/// <remarks>
/// NANUnion은 double에서 비트를 쉽게 조작할 수 있는 unsigned long으로 효율적으로 변환하는데 사용되는 C++ 스타일 유형 공용체이다.
/// </remarks>
[StructLayout(LayoutKind.Explicit)]
private struct NANUnion
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Internal
#region Field
/// <summary>
/// 부동 값
/// </summary>
[FieldOffset(0)]
internal double FloatingValue;
/// <summary>
/// 정수 값
/// </summary>
[FieldOffset(0)]
internal ulong IntegerValue;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 제로 여부 구하기 - IsZero(double value)
#if !WINDOWS_PHONE
/// <summary>
/// 제로 여부 구하기
/// </summary>
/// <param name="value">값</param>
/// <returns>제로 여부</returns>
public static bool IsZero(this double value)
{
// 실제로 엡실론의 크기 내에서 모든 것을 0으로 간주한다.
return Math.Abs(value) < 2.2204460492503131E-15;
}
#endif
#endregion
#region NAN 여부 구하기 - IsNAN(value)
/// <summary>
/// NAN 여부 구하기
/// </summary>
/// <param name="value">값</param>
/// <returns>NAN 여부</returns>
public static bool IsNAN(this double value)
{
NANUnion union = new NANUnion { FloatingValue = value };
ulong exponent = union.IntegerValue & 0xfff0000000000000L;
if((exponent != 0x7ff0000000000000L) && (exponent != 0xfff0000000000000L))
{
return false;
}
ulong mantissa = union.IntegerValue & 0x000fffffffffffffL;
return mantissa != 0L;
}
#endregion
#region 밀접 여부 구하기 - AreClose(leftValue, rightValue)
/// <summary>
/// 밀접 여부 구하기
/// </summary>
/// <param name="leftValue">왼쪽 값</param>
/// <param name="rightValue">오른쪽 값</param>
/// <returns>밀접 여부</returns>
public static bool AreClose(double leftValue, double rightValue)
{
if(leftValue == rightValue)
{
return true;
}
double a = (Math.Abs(leftValue) + Math.Abs(rightValue) + 10.0) * 2.2204460492503131E-16;
double b = leftValue - rightValue;
return (-a < b) && (a > b);
}
#endregion
#region 초과 여부 구하기 - IsGreaterThan(leftValue, rightValue)
/// <summary>
/// 초과 여부 구하기
/// </summary>
/// <param name="leftValue">왼쪽 값</param>
/// <param name="rightValue">오른쪽 값</param>
/// <returns></returns>
public static bool IsGreaterThan(double leftValue, double rightValue)
{
return (leftValue > rightValue) && !AreClose(leftValue, rightValue);
}
#endregion
#region 미만이거나 밀접 여부 구하기 - IsLessThanOrClose(leftValue, rightValue)
#if !WINDOWS_PHONE
/// <summary>
/// 미만이거나 밀접 여부 구하기
/// </summary>
/// <param name="leftValue"></param>
/// <param name="rightValue"></param>
/// <returns>미만이거나 밀접 여부</returns>
public static bool IsLessThanOrClose(double leftValue, double rightValue)
{
return (leftValue < rightValue) || AreClose(leftValue, rightValue);
}
#endif
#endregion
}
}
728x90
그리드형(광고전용)