2011-04-22 4 views
14

.net 10 진수 값 1m과 1.0000m 사이에 실제적인 차이점이 있습니까? "유효 숫자"의 지식은 BCL의 방법으로 사용되는 상황이있다,.net 10 진수 값 1m과 1.0000m 사이에 실제적인 차이점이 있습니까?

1m  : 0x00000001 0x00000000 0x00000000 0x00000000 
1.0000m : 0x000186a0 0x00000000 0x00000000 0x00050000 

그러나 :

내부 스토리지는 다른가요?

나는 디스크 저장 장치 나 네트워크 전송에 필요한 10 진수 값을 압축하는 방법을 연구하고 있기 때문에 압축성을 향상시키기 위해 저장하기 전에 그 값을 "표준화"한다는 아이디어를 가지고 놀고있다. 하지만 문제가 발생할 가능성이 있는지 알고 싶습니다. 나는 그 값의 정밀도를 드러내는 어떤 메서드 나 속성도 보지 않기 때문에 그것이 괜찮을 것이라고 추측하고 있습니다. 다른 사람이 아는 사람 있습니까?

답변

4

생각할 수있는 유일한 이유는 ToString을 호출하면 소스 코드에서 정확한 텍스트 표현을 반환합니다. 제수를 형성하는데 사용되는 스케일 소수점 데이터 유형을 저장 정수 (96 비트 정수)와 같은 수의 분수를 얻을 수 있기 때문에

Console.WriteLine(1m); // 1 
Console.WriteLine(1.000m); // 1.000 
+1

-1 : "ToString"이 소스 코드에 대해 어떻게 알 수 있습니까? –

+0

흥미 롭습니다. 나는 상관 여부에 대해 생각했다. – MarkPflug

+0

@ 존 - 분명히 그렇습니다. – ChaosPandion

11

부호화에서의 차이에 대한 이유이다. 이 값에 대해 자세히 Decimal.GetBits의 문서를 참조 본질적 내부적 소수 유형 int32를 4로 표현

integer/10^scale 

이다. 요약 GetBits가 1.0000m이 소수로 인코딩 될 때, 아주 단순히 실제 표현 10000/10^4이다 넣어 각 요소 소수점 인코딩하여 예에 따라서

Element 0,1,2 - Represent the low, middle and high 32 bits on the 96 bit integer 
Element 3  - Bits 0-15 Unused 
       Bits 16-23 exponent which is the power of 10 to divide the integer by 
       Bits 24-30 Unused 
       Bit 31 the sign where 0 is positive and 1 is negative 

의 후속 부분을 나타내는 4 Int32s의 배열을 반환 1m은 수학적으로 동일한 값이 다르게 인코딩 된 1/10^0으로 표시됩니다.

소수 유형에 네이티브 .NET 연산자를 사용하고 비트/바이트를 직접 조작/비교하지 않으면 안전해야합니다.

문자열 변환도이 2 진 표현을 고려하여 다른 문자열을 생성하므로 문자열 표현에 의존하는 경우 조심해야합니다.

+0

작은 nitpick : 그것은 Byte 1,2,3가 아니라 (4 바이트 4 중주)입니다. 또는 처음 12 바이트가 정수 값을 보유한다고 말할 수 있습니다. –

+0

@Matt Brunell, 틀림없이 옳습니다! 그에 따라 답변을 수정 해 주셔서 감사합니다. –

5

decimal 유형 트랙은 연산에서 중요하기 때문에 축척됩니다. 당신은 곱셈을 수행하려면 두 개의 숫자 예를 들어 —, 3.14 * 5.00 — 결과가 정밀의 6 개 자리가 있고 규모 4.

의 손으로, 긴 곱셈을 할 경우, 소수점을 무시 (현재는) 두 숫자를 정수로 취급하십시오.

3.14 
* 5.00 
------ 
    0000 -- 0 * 314 (0 in the one's place) 
00000 -- 0 * 314 (0 in the 10's place) 
157000 -- 5 * 314 (5 in the 100's place) 
------ 
157000 

이렇게하면 확대되지 않은 결과가 나타납니다. 이제, 식 소수점의 오른쪽 자리의 총 수를 카운트 (즉, 4 것)과 왼쪽 소수점 4 곳에 삽입 :

15.7000 

결과 값에 상응하는 반면 15.도 7에 도시 된 바와 같이, 은 정확하게이고 값은 15.7이다. 값 15.7000은 6 자리의 정밀도와 4의 스케일을가집니다. 15.7은 3 자리의 정밀도와 1의 눈금을 가지고 있습니다.

정밀 연산을 시도하는 경우 결과의 정밀도에 대해 알려주므로 값과 결과의 정밀도와 크기를 추적하는 것이 중요합니다 (정밀도는 정확도와 동일하지 않습니다. 눈금자를 1/10 인치 눈금으로 측정하고 소수점 오른쪽에 몇 개의 후행 0이 있더라도 결과 측정에 대해 말할 수있는 최고치를 측정하십시오 기껏해야 10 분의 1 인치 정도 정확하다는 것입니다. 또 다른 방법으로는 측정 값이 명시된 값의 +/- 5/100 범위 내에서 정확하다는 것입니다.

+0

불행하게도, 'Decimal'이 정밀도를 추적하는 방식은 관련 숫자의 정밀도에 대한 정보를 안정적으로 유지하지 못합니다. 2^n * 5^n 형식이 아닌 숫자로 나누면 해당 숫자가 실제 정확도를 나타내는 지 여부에 관계없이 표현 가능한 최대 자릿수가 산출되고 빼기가 치명적인 취소를 초래할 때는 아무 것도 표시되지 않습니다. – supercat

관련 문제