IT박스

소수점 정밀도 조정, .net

itboxs 2020. 11. 25. 07:46
반응형

소수점 정밀도 조정, .net


C #의이 줄

decimal a = 2m;
decimal b = 2.0m;
decimal c = 2.00000000m;
decimal d = 2.000000000000000000000000000m;

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);

다음 출력을 생성합니다.

2
2.0
2.00000000
2.000000000000000000000000000

따라서 리터럴에서 십진 변수를 생성하면 정밀도를 제어 할 수 있음을 알 수 있습니다.

  • 리터럴을 사용하지 않고 소수 변수의 정밀도를 조정할 수 있습니까?
  • a에서 b를 어떻게 만들 수 있습니까? c에서 b를 어떻게 만들 수 있습니까?

이와 같이 후행 0을 유지하는 것은 ECMA CLI 사양을보다 엄격하게 준수하기 위해 .NET 1.1에서 도입되었습니다.

MSDN에 대한 정보가 있습니다 .

다음과 같이 정밀도를 조정할 수 있습니다.

  • Math.Round (또는 Ceiling, Floor 등)로 정밀도 감소 (b에서 c)

  • 정밀도를 높이려면 1.000 ... (원하는 소수 자릿수 포함)을 곱하십시오. 예를 들어 a에서 b를 얻으려면 1.0M을 곱하십시오.


정확히 동일한 데이터의 다른 표현을보고 있습니다. a의 정밀도는 decimal(이유 내에서) 필요한만큼 크게 조정됩니다.

에서 System.Decimal:

10 진수는 부호, 값의 각 숫자 범위가 0에서 9 사이 인 숫자 값 , 정수 부분과 소수 부분을 구분하는 부동 소수점의 위치를 ​​나타내는 배율 인수로 구성된 부동 소수점 값입니다. 숫자 값의.

Decimal 값의 이진 표현은 1 비트 부호, 96 비트 정수 및 96 비트 정수를 나누고 소수점 이하 부분을 지정하는 데 사용되는 배율 인수로 구성됩니다. 스케일링 계수는 암시 적으로 숫자 10이며 0에서 28까지의 지수로 올립니다. 따라서 Decimal 값의 이진 표현은 ((-2 96 to 2 96 ) / 10 (0 to 28) ) 형식입니다. , 여기서 -2 96 -1은 MinValue와 같고 2 96 -1은 MaxValue와 같습니다.

배율 인수는 또한 Decimal 숫자의 후행 0을 유지합니다. 후행 0은 산술 또는 비교 연산의 10 진수 값에 영향을주지 않습니다. 그러나 적절한 형식 문자열이 적용되면 ToString 메서드에 의해 후행 0이 표시 될 수 있습니다.


무엇에 대한 Math.Round (진수 D, INT 소수) ?


1을 곱하거나 나눔으로써 스케일을 "변조"할 수 있음을 발견했습니다.

decimal a = 2m;
decimal c = 2.00000000m;
decimal PreciseOne = 1.000000000000000000000000000000m;
  //add maximum trailing zeros to a
decimal x = a * PreciseOne;
  //remove all trailing zeros from c
decimal y = c / PreciseOne;

알려진 크기로 축척 계수를 변경하기 위해 충분히 정확한 1을 제작할 수 있습니다.

decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;

for (int i = 0; i < scaleFactorSize; i++)
{
  scaleFactor *= scaleFactorBase;
}

decimal z = a * scaleFactor;

decimalSQL Server와 decimal.NET 을 혼동 하고 싶은 유혹이 있습니다 . 그들은 아주 다릅니다.

SQL Server decimal는 열 또는 변수가 정의 될 때 정밀도와 배율이 고정되는 고정 소수점 숫자입니다.

A .NET decimal is a floating-point number like float and double (the difference being that decimal accurately preserves decimal digits whereas float and double accurately preserve binary digits). Attempting to control the precision of a .NET decimal is pointless, since all calculations will yield the same results regardless of the presence or absence of padding zeros.


The question is - do you really need the precision stored in the decimal, rather than just displaying the decimal to the required precision. Most applications know internally how precise they want to be and display to that level of precision. For example, even if a user enters an invoice for 100 in an accounts package, it still prints out as 100.00 using something like val.ToString("n2").

How can I create b from a? How can I create b from c?

c to b is possible.

Console.WriteLine(Math.Round(2.00000000m, 1)) 

produces 2.0

a to b is tricky as the concept of introducing precision is a little alien to mathematics.

I guess a horrible hack could be a round trip.

decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);

produces 2.0


This will remove all the trailing zeros from the decimal and then you can just use ToString().

public static class DecimalExtensions
{
    public static Decimal Normalize(this Decimal value)
    {
        return value / 1.000000000000000000000000000000000m;
    }
}

Or alternatively, if you want an exact number of trailing zeros, say 5, first Normalize() and then multiply by 1.00000m.

참고URL : https://stackoverflow.com/questions/1132765/adjusting-decimal-precision-net

반응형