내가보고 싶은 한 가지는 것으로 인식 될 double
수있는 float
반면, 확대 변환으로 간주되어야 float
에 double
(*) 축소된다. 반 직관적 인 것처럼 보일 수 있지만 실제로 유형의 의미를 고려하십시오.
- 0.1f는 "13,421,773.5 / 134,217,728, 플러스 또는 마이너스 1 / 268,435,456 정도"를 의미합니다.
- 0.1은 실제로 3,602,879,701,896,397 / 36,028,797,018,963,968을 의미합니다.
double
수량이 "10 분의 1"로 가장 잘 표현 된 값 을 가지고이를로 변환 float
하면 결과는 "13,421,773.5 / 134,217,728, 플러스 또는 마이너스 1 / 268,435,456 정도"가되며 이는 값에 대한 정확한 설명입니다.
반대로, float
"10 분의 1"을 가장 잘 나타내는 것을 가지고 그것을로 변환하면 double
, 결과는 "13,421,773.5 / 134,217,728, 더하기 또는 빼기 1 / 72,057,594,037,927,936 정도"-암시 적 정확도 수준이됩니다 이는 5 천 5 백만 이상의 요인으로 잘못되었습니다.
비록 IEEE-744 표준이 모든 부동 소수점 숫자가 그 범위의 중심에서 정확한 수치 수량을 나타내는 것처럼 부동 소수점 수학을 수행하도록 요구 하지만 , 부동 소수점 값이 실제로 정확한 것을 나타내는 것을 암시해서는 안됩니다 수량. 오히려, 값이 그 범위의 중심에 있다고 가정하는 요구는 세 가지 사실에서 비롯됩니다. (1) 피연산자가 특정한 정확한 값을 갖는 것처럼 계산을 수행해야합니다. (2) 일관성 있고 문서화 된 가정은 일관성이 없거나 문서화되지 않은 가정보다 더 유용합니다. (3) 일관된 가정을 할 경우, 수량이 그 범위의 중심을 나타낸다고 가정하는 것보다 다른 일관된 가정이 더 나을 것 같지는 않습니다.
우연히도, 25 년 정도 전에 누군가 누군가가 한 쌍의 128 비트 부동 소수점으로 구성된 "범위 유형"을 사용하는 C 용 숫자 패키지를 생각해 냈습니다. 모든 계산은 각 결과에 대해 가능한 최소값과 최대 값을 계산하는 방식으로 수행됩니다. 큰 반복 계산을 수행하고 [12.53401391134 12.53902812673]의 값을 얻었을 경우 많은 자릿수의 반올림 오류가 발생하더라도 결과는 여전히 12.54로 합리적으로 표현 될 수 있습니다. t 실제로 12.9 또는 53.2). 주류 언어에서 이러한 유형에 대한 지원을 보지 못한 것에 놀랐습니다. 특히 여러 값에서 병렬로 작동 할 수있는 수학 단위에 적합하기 때문입니다.
(*) 실제로 단 정밀도 숫자로 작업 할 때 중간 정밀도 계산을 유지하기 위해 배정 밀도 값을 사용하는 것이 도움이되므로 이러한 모든 작업에 대해 유형 캐스트를 사용해야하는 것은 성 가실 수 있습니다. 언어는 "퍼지 더블"유형을 사용하여 도움을 줄 수 있는데,이 유형은 계산을 두 배로 수행 할 수 있으며 싱글과 자유롭게 캐스트 할 수 있습니다. 이것은 타입 double
과 리턴의 매개 변수를 취하는 함수를 double
표시하여 대신 "퍼지 더블"을 받아들이고 리턴하는 과부하를 자동으로 생성 할 수있는 경우에 특히 유용합니다 .