음, 여기서 가장 먼저 말할 것은 화재로 여기에서 놀고 있다는 것입니다. 동일한 내용으로 Integer
, Double
및 Currency
을 혼합합니다. 불합리한 혼합은, 솔직히, 문제를 요구하고 있습니다.
아직까지는 모르는 경우에 대비하여 모든 값을 나타낼 수있는 것은 아닙니다. 여기서, 소스 값은 다음
a
는 Double
입력 값 30.1
이다. 이 값은 2 진 부동 소수점에서 정확하게 표현할 수 없습니다. closest Double
value은 30.10000000000000142108547152020037174224853515625
입니다.
b
은 Integer
, 값은 10
입니다. 여기에 놀라움이 없습니다.
c
은 Currency
이고 값은 20.1
입니다. 이것은 값이 201000 인 64 비트 정수로 표시됩니다. 이것은 고정 소수점 10 진 데이터 유형입니다. 표현에는 10000의 내재적 시프트가 포함됩니다.
다음 표현식은 a - b - c
입니다. 왼쪽에서 오른쪽으로 평가됩니다.
86 아래의 코드 내 주석으로, 다음과 같습니다
는
// load b into the floating point unit, converting from 32 bit integer
fild dword ptr [$00423ef0]
// subtract b from a, as floating point
fsubr qword ptr [$00423ed8]
// multiply by 10000 to convert to currency
fmul dword ptr [$0041c5e0]
// load c into the floating point unit, converting from 64 bit integer
fild qword ptr [$00423ee8]
// subtract c from (b - a)
fsubp st(1)
// divide by 10000, that is convert the result to a floating point value
fdiv dword ptr [$0041c5e0]
// store this floating point value into d
fstp qword ptr [$00423ee0]
우리가 d
에 다시 저장 값은 0이 아닌. 본질적으로 그 이유는 (a - b)*10000 <> 20100
입니다. 이제 (a - b)*10000 <> 20100
을 알면 놀랄 것입니다. 그러나 위의 첫 번째 글 머리 기호에서 알 수 있듯이 a
은 30.1
의 정확한 표현이 아닙니다.
이야기의 도덕은 같은 표현에서 이진수와 십진법 피연산자를 섞어서는 안된다고 생각합니다. 적어도 그렇게 할 필요가 있다면, 어떻게하는지에 대해 명확하고 정확해야합니다. 예를 들어.
따라서 계산을 모두 Currency
으로 수행하면 예상 한 답변을 얻을 수 있습니다. Currency
은 10 진수 표현이며 이러한 모든 값과 모든 중간 값을 정확하게 저장할 수 있기 때문입니다.
double type 변수 "30.1"실제로 값 "30.10000000000000142108547152020037174224853515625"를 받는다는 것은 놀라운 가치입니다! 논리적으로 나는 타입 변환을 할 필요가없는 방식으로 이해할 수 있는가? –
무슨 뜻인지 모르겠다. 도움이 더 필요하십니까? –
나는 OP가 [모든 컴퓨터 과학자가 부동 소수점 산술에 관해 알아야 할 내용] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)을 살펴보고 싶다고 생각합니다. –