c# numericupdown 사용법




십진수 대신 double을 사용해야하는 경우는 언제입니까? (8)

당신이 필요로하는 것에 달려 있습니다.

float과 double은 바이너리 데이터 유형이기 때문에 라운드 수에서 실수와 실수가 있습니다. 예를 들어 double은 0.1에서 0.100000001490116으로 반올림하고 double은 1/3에서 0.33333334326441로 반올림합니다. 간단히 말해 모든 실수가 이중형에서 정확한 표현을 갖는 것은 아닙니다.

운 좋게도 C #은 이진 부동 소수점 산술을 지원합니다. 여기서 숫자는 이진 시스템이 아닌 십진 숫자 시스템을 통해 표현됩니다. 따라서 소수점 부동 소수점 산술 부동 소수점 숫자를 저장하고 처리 할 때 정확성을 잃지 않습니다 . 따라서 높은 수준의 정확도가 필요한 계산에 매우 적합합니다.

decimal 대신 double (또는 float )을 사용하는 double 세 가지 장점이 있습니다.

  1. 메모리를 적게 사용합니다.
  2. 부동 소수점 연산이 기본적으로 프로세서에서 지원되므로 더 빠릅니다.
  3. 더 큰 범위의 수를 나타낼 수 있습니다.

그러나 이러한 장점은 모델링 소프트웨어와 같은 계산 집약적 인 작업에만 적용되는 것처럼 보입니다. 물론 재무 계산과 같이 정밀도가 필요할 때 복식을 사용하면 안됩니다. 그래서 "정상적인"어플리케이션에서 decimal 대신 double (또는 float )을 선택하는 실제적인 이유가 있습니까?

추가 편집 : 모든 위대한 응답 주셔서 감사합니다, 나는 그들로부터 배웠습니다.

또 하나의 질문 : 몇몇 사람들은 복식이 실수를 더 정확하게 나타낼 수 있다는 견지를 나타 냈습니다. 선언 할 때 나는 그들이 일반적으로 그들을 더 정확하게 대표한다고 생각할 것이다. 그러나 부동 소수점 연산이 수행 될 때 정확도가 (때로는 상당히) 감소 할 수 있다는 것은 진실한 진술입니까?


기저 값 10에 소수점을 사용하십시오 (예 : 재무 계산).

그러나 double은 일반적으로 임의의 계산 된 값에 대해 더 정확합니다.

예를 들어, 포트폴리오의 각 행의 가중치를 계산하려면 double을 사용하면 결과가 거의 100 %가됩니다.

다음 예제에서 doubleResult는 decimalResult보다 1에 가깝습니다.

// Add one third + one third + one third with decimal
decimal decimalValue = 1M / 3M;
decimal decimalResult = decimalValue + decimalValue + decimalValue;
// Add one third + one third + one third with double
double doubleValue = 1D / 3D;
double doubleResult = doubleValue + doubleValue + doubleValue;

다시 포트폴리오의 예를 들자면 다음과 같습니다.

  • 포트폴리오의 각 라인의 시장 가치는 화폐 가치이며 십진수로 가장 잘 표현됩니다.

  • 포트폴리오 (= 시장 가치 / 합계 (시장 가치))에서 각 라인의 가중치는 대개 더 두 배로 표현됩니다.


다른 언어 또는 플랫폼과 바이너리 상호 작용이 필요한 경우 표준화 된 float 또는 double을 사용해야 할 수도 있습니다.


부동 소수점 유형을 사용하면 얻을 수있는 이점을 발견 할 수 있습니다. 필자는 모든 경우에 십진수로 설계하는 경향이 있으며 십진수 연산이 병목 현상이나 속도 저하를 일으키는 지 알 수있는 프로파일 러에 의존합니다. 이러한 경우, 나는 "다운 캐스트 (double cast)"또는 "부동 (float)"하지만 내부적으로 만 수행하고, 수행되는 수학 연산의 유효 자릿수를 제한함으로써 정밀 손실을 조심스럽게 관리하려고합니다.

일반적으로 값이 일시적 (재사용되지 않음)이라면 부동 소수점 형식을 사용하는 것이 안전합니다. 부동 소수점 유형의 실제 문제는 다음 세 가지 시나리오입니다.

  1. 부동 소수점 값을 집계하고 있습니다 (이 경우 정밀도 오차 화합물)
  2. 부동 소수점 값을 기반으로 값을 생성합니다 (예 : 재귀 알고리즘)
  3. 숫자의 유효 숫자가 매우 넓습니다 (예 : 123456789.1 * .000000000000000987654321 ).

편집하다

C # 소수에 대한 참조 문서에 따르면 :

decimal 키워드는 128 비트 데이터 유형을 나타냅니다. 부동 소수점 유형과 비교할 때 소수점 유형은 정밀도가 높고 범위가 작으므로 재정적 및 금전적 계산에 적합합니다.

그래서 위의 진술을 명확히하기 위해 :

필자는 모든 경우에 십진수로 설계하는 경향이 있으며 십진수 연산이 병목 현상이나 속도 저하를 일으키는 지 알 수있는 프로파일 러에 의존합니다.

나는 십진법이 유리한 산업에서만 일 해왔다. phsyics 또는 그래픽 엔진에서 작업하는 경우 부동 소수점 유형 (float 또는 double)을 설계하는 것이 훨씬 더 유용합니다.

십진수는 무한히 정확하지는 않습니다 (원시 데이터 유형에서 비 정수의 무한 정밀도를 표시하는 것은 불가능합니다). 그러나 이것은 두 배보다 훨씬 정확합니다.

  • 십진법 = 28-29 유효 자릿수
  • 두 배 = 15-16 자릿수
  • float = 유효 자릿수 7 자리

2 번 수정

Konrad Rudolph 의 의견에 비추어 항목 # 1 (위)은 분명 정확합니다. 부정확성의 집계는 정말로 복합적입니다. 예를 보려면 아래 코드를 참조하십시오.

private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;

public static void Main(string[] args)
{
    Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
    float asSingle = 0f;
    double asDouble = 0d;
    decimal asDecimal = 0M;

    for (int i = 0; i < ONE_MILLION; i++)
    {
        asSingle += THREE_FIFTHS;
        asDouble += THREE_FIFTHS;
        asDecimal += (decimal) THREE_FIFTHS;
    }
    Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
    Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
    Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
    Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
    Console.ReadLine();
}

그러면 다음과 같이 출력됩니다.

Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000

보시다시피, 동일한 소스 상수로부터 더하기는했지만, double의 결과는 정확하지 않을 수 있습니다 (정확히 반올림 함에도 불구하고). float는 훨씬 덜 정확합니다. 2 자리 유효 숫자.


예를 들어, 내가 쓴 플랫폼 게임에서 정밀도가 필요하지 않을 때는 double 또는 float을 사용하고, 플레이어 속도를 저장하기 위해 float를 사용했습니다. 분명히 화면에서 그림을 그리기 위해 Int로 반올림하기 때문에 여기에 초정밀도가 필요하지 않습니다.


응용 프로그램의 기능에서 유형을 선택하십시오. 재무 분석과 같은 정밀도가 필요하다면 질문에 대답했습니다. 하지만 응용 프로그램이 견적과 함께 두 번 확인으로 해결할 수 있다면.

귀하의 신청서에 빠른 계산이 필요합니까? 아니면 전 세계에서 항상 답변을 드릴 것입니까? 그것은 실제로 응용 프로그램의 유형에 따라 다릅니다.

배고픈 그래픽? float 또는 double이면 충분합니다. 재무 데이터 분석, 유성 정밀도 행성 일종의 타격? 그 사람들은 약간의 정밀도가 필요합니다 :)


참고 :이 게시물은 http://csharpindepth.com/Articles/General/Decimal.aspx 의 십진 유형 기능에 대한 정보와 그 의미에 대한 내 자신의 해석을 기반으로합니다. 나는 Double이 정상적인 IEEE 배정도라고 가정 할 것이다.

주 2 :이 게시물에서 가장 작고 가장 큰 숫자의 크기를 알 수 있습니다.

"십진법"의 장점.

  • "십진수"는 (충분히 짧은) 소수점 이하 자릿수로 쓰여질 수있는 숫자를 정확하게 나타낼 수 있습니다. 이중 수는 없습니다. 재정 원장 등에서 중요한 점은 계산 결과와 인간의 계산 결과가 정확히 일치해야한다는 점입니다.
  • "10 진수"는 "double"보다 훨씬 큰 가수를가집니다. 즉, 정규화 된 범위의 값에 대해 "십진수"는 double보다 훨씬 더 높은 정밀도를 갖습니다.

십진수의 단점

  • 훨씬 느릴 것입니다. (벤치 마크는 없지만 최소 규모는 더 많이 추측 할 것입니다.) 10 진수는 하드웨어 가속과 산술 연산의 이점을 얻지 못할 것이고 10 승수로 비교적 비싸게 곱셈 / 나눗셈을해야합니다. 곱셈과 나눗셈 이후에 지수를 덧셈 / 뺄셈 이전의 지수와 일치시키고 범위 내로 다시 가져 오는 2)의 거듭 제곱에 의한 곱셈과 배분보다 훨씬 더 비쌉니다.
  • 십진수는 이전보다 두 배의 의욕을 초과합니다. 십진수는 최대 ± 2 96 -1의 숫자 만 나타낼 수 있습니다. 비교에 따르면 double은 최대 ± 2 1024의 숫자를 나타낼 수 있습니다.
  • 십진수는 언더 플로우가 일찍 발생합니다. 십진수로 표현할 수있는 가장 작은 숫자는 ± 10 -28 입니다. 비교에 따라 double은 부 번호가 지원되는 경우 2 -149 (약 10 -45 ), 그렇지 않은 경우 2 -126 (약 10 -38 )까지 값을 나타낼 수 있습니다.
  • 십진수는 두 배의 메모리를 두 배로 사용합니다.

제 의견은 돈 계산과 일치하는 인간 계산이 중요하고 다른 부분을 기본 선택으로 사용해야한다는 다른 경우에는 "십진수"를 기본값으로 사용해야한다는 것입니다.


퍼포먼스의 정확성을 중요시한다면 부동 소수점을 사용하십시오.





decimal