2012-12-10 3 views
1
var numberFormat = new NumberFormatInfo(); 
numberFormat.NumberDecimalSeparator = "."; 
numberFormat.NumberDecimalDigits = 2; 

decimal a = 10.00M; 
decimal b = 10M; 

Console.WriteLine(a.ToString(numberFormat)); 
Console.WriteLine(b.ToString(numberFormat)); 
Console.WriteLine(a == b ? "True": "False"); 

: 10.00 진정한홀수 소수 유형의 행동 콘솔에서

왜 다른가요? 더 중요한 것은 어떻게 변수가 초기화 되더라도 동일한 출력을 보장하기 위해 ToString()을 호출하는 것입니다.

+0

예상되는 출력은 무엇입니까? 10, 10, 맞나요? –

+0

글쎄, 나는 사실 10.00 10.00을 기대했지만, 적어도 10 10이면 numberFormat이 잘못되었다는 것이 분명 할 것이다. 이것은 단지 나를 혼란스럽게 만들었다. (실제 코드는 그리 간단하지 않기 때문에 소수점 이하 자릿수는 왜 숫자 형식이 좋았는지 알 수 있지만 시간이 좀 걸렸다.) – Damir

+0

사이드 노트 : bool은 사용 가능한 ToString을 구현하므로 콘솔 .WriteLine (a == b);'는 예제에서와 같은 것을 출력 할 것입니다. –

답변

2

NumberDecimalDigits 속성은 "F""N" 표준 형식 문자열과 함께 사용되며 형식 문자열없이 호출되는 ToString 메서드는 사용할 수 없습니다.

당신은 사용할 수 있습니다

Console.WriteLine(a.ToString("N", numberFormat)); 
1

이 시도 : 출력은 항상 2 진수의 경우를해야합니다

Console.WriteLine(String.Format("{0:0.00}", a)); 
Console.WriteLine(String.Format("{0:0.00}", b)); 

. 여기에 더 많은 예제 :

decimal 값은 내부적으로 포함

, 필드 : 여기

http://www.csharp-examples.net/string-format-double/

+0

그러나 항상 소수점 구분 기호로 마침표가있는 것은 아닙니다. – Guffa

+0

숫자에 소수점 구분 기호가 있는지 여부는 중요하지 않습니다. 출력은 항상 소수점 2 자리를 갖습니다. 'Console.WriteLine (String.Format ("{0 : 0.00}", 10M));을 실행하면 출력이'10.00' 인 것을 보게됩니다 –

+1

요점을 놓치고 있습니다. 소수점 구분 기호가 마침표 여야하는 숫자 형식으로 지정된 OP입니다. 숫자 형식을 사용하지 않을 경우 소수 구분 기호는 기본 문화권에 지정된 구분 기호가됩니다. 이 코드를 사용하면 출력이 '10,00'이라는 것을 알 수 있습니다. – Guffa

4

을, 그것은 출력이 지속적으로 대답했습니다 만드는 방법의 문제 만은 왜 처음부터 다르게 그들이 출력 척도와 계수에 대해서. 10M의 경우, 인코딩 된 값 (10)의 계수가 0의 규모 가지고

: 10.00M의 경우

10M = 10 * 10^0 

를 부호화 값 (1000)의 계수를 2의 비율을 가지고

10.00M = 1000 * 10^(-2) 

당신은 종류의 메모리 값을 검사하여이 문제를 볼 수 있습니다

unsafe 
{ 
    fixed (decimal* array = new decimal[2]) 
    { 
     array[0] = 10M; 
     array[1] = 10.00M; 
     byte* ptr = (byte*)array; 

     Console.Write("10M: "); 
     for (int i = 0; i < 16; i++) 
      Console.Write(ptr[i].ToString("X2") + " "); 

     Console.WriteLine(""); 

     Console.Write("10.00M: "); 
     for (int i = 16; i < 32; i++) 
      Console.Write(ptr[i].ToString("X2") + " "); 
    } 
} 

출력

,
10M: 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 
10.00M: 00 00 02 00 00 00 00 00 E8 03 00 00 00 00 00 00 

(0xa는 16 진수에서 10이며, 0x3E8 16 진수로 1000)이 문제는 C# 1 명세의 섹션 2.4.4.3에 약술되어

:

실제 문자 M 또는 접미사 m은 10 진수 형식입니다. 예를 들어, 리터럴 1m, 1.5m, 1e10m 및 123.456M은 모두 십진 형식입니다. 이 리터럴은 정확한 값을 취하여, 필요하다면 은행가의 반올림 (4.1.7)을 사용하여 가장 가까운 표현 가능한 값으로 반올림하여 10 진수 값으로 변환됩니다. 값이 반올림되지 않거나 값이 0 (리터럴에서 부호와 배율이 0이 아닌 경우) 인 경우를 제외하고는 리터럴에있는 모든 눈금이 보존됩니다. 따라서 문자 2.900m은 부호 0, 계수 2900 및 눈금 3이있는 소수로 구성됩니다.

+0

흥미 롭다. 노력해 주셔서 감사합니다. 그러나 ToString은 어떻게 다른지 설명합니다. 왜 ToString이 메모리에서 어떻게 표현되는지에 관심이있는 것은 아닙니다. 원시 타입의 ToString은 논리적으로 똑같은 입력을 제공함으로써 같은 결과를 반환한다는 보장을 제공합니까? 또는 디자인에 의해 (ToString의 동작이 아닌 소수)? – Damir