0.1 float는 0.1 double보다 큽니다. 나는 그것이 거짓 일 것으로 예상했다 [중복]
이 질문에 이미 답변이 있습니다.
허락하다:
double d = 0.1;
float f = 0.1;
표현해야
(f > d)
반환 true
또는 false
?
경험적으로 대답은 true
입니다. 그러나 나는 그것이 false
.
로이 0.1
두 번있는 동안 완벽하게, 이진수로 표현할 수없는 15
에 16
정밀의 진수, 및 플로트는있다 7
. 따라서 둘 다보다 작으며 0.1
이중이 더 가깝습니다 0.1
.
에 대한 정확한 설명이 필요합니다 true
.
나는를 변환 할 때 대답은 반올림 모드에 따라 달라집니다 말하고 싶지만 double
으로 float
. float
24 개의 이진 비트 정밀도를 double
가지며 53을 갖습니다. 이진법에서 0.1은 다음과 같습니다.
0.1₁₀ = 0.0001100110011001100110011001100110011001100110011…₂
^ ^ ^ ^
1 10 20 24
우리는 반올림이 경우 최대 24 자리에서, 우리는거야
0.1₁₀ ~ 0.000110011001100110011001101
이는 정확한 값보다 크고 53 자리에서 더 정확한 근사값입니다.
숫자 0.1은 주어진 정밀도로 가장 가까운 부동 소수점 표현으로 반올림됩니다. 이 근사는 0.1보다 크거나 작을 수 있으므로 실제 값을 보지 않고는 단 정밀도 또는 배정 밀도 근사가 더 큰지 예측할 수 없습니다.
다음은 배정 밀도 값이 반올림되는 값입니다 (Python 인터프리터 사용).
>>> "%.55f" % 0.1
'0.1000000000000000055511151231257827021181583404541015625'
다음은 단 정밀도 값입니다.
>>> "%.55f" % numpy.float32("0.1")
'0.1000000014901161193847656250000000000000000000000000000'
따라서 단 정밀도 근사가 더 크다는 것을 알 수 있습니다.
.1
바이너리 로 변환하면 다음 을 얻을 수 있습니다.
0.000110011001100110011001100110011001100110011001100 ...
영원히 반복
데이터 유형에 매핑하면 다음을 얻을 수 있습니다.
float (.1) = % .00011001100110011001101 ^ --- 반올림 참고 double (.1) = % .0001100110011001100110011001100110011001100110011010
10 진수로 변환 :
float (.1) = .10000002384185791015625 double (.1) = .100000000000000088817841970012523233890533447265625
이것은 Bruce Dawson이 쓴 기사에서 가져온 것입니다. 여기에서 찾을 수 있습니다.
복식은 수레가 아니므로 비교하지 마십시오.
질문에 대한 Eric Lippert의 의견 이 실제로 가장 명확한 설명 이라고 생각 하므로 답변으로 다시 게시하겠습니다.
3 자리 십진수와 6 자리 십진수로 1/9를 계산한다고 가정합니다. 0.111 <0.111111, 맞죠?
이제 6/9를 계산한다고 가정합니다. 0.667> 0.666667, 맞죠?
6/9에 가장 가까운 3 자리 10 진수가 아니기 때문에 3 자리 십진수의 6/9가 0.666이라는 것을 가질 수 없습니다!
정확히 표현할 수 없기 때문에 2 진법에서 1/10을 비교하는 것은 10 진법에서 1/7을 비교하는 것과 같습니다.
1/7 = 0.142857142857 ...하지만 다른 기본 10 정밀도 (소수점 3 대 6 자리)에서 비교하면 0.143> 0.142857이됩니다.
Just to add to the other answers talking about IEEE-754 and x86: the issue is even more complicated than they make it seem. There is not "one" representation of 0.1 in IEEE-754 - there are two. Either rounding the last digit down or up would be valid. This difference can and does actually occur, because x86 does not use 64-bits for its internal floating-point computations; it actually uses 80-bits! This is called double extended-precision.
So, even among just x86 compilers, it sometimes happen that the same number is represented two different ways, because some computes its binary representation with 64-bits, while others use 80.
In fact, it can happen even with the same compiler, even on the same machine!
#include <iostream>
#include <cmath>
void foo(double x, double y)
{
if (std::cos(x) != std::cos(y)) {
std::cout << "Huh?!?\n"; //← you might end up here when x == y!!
}
}
int main()
{
foo(1.0, 1.0);
return 0;
}
See Why is cos(x) != cos(y)
even though x == y
? for more info.
The rank of double is greater than that of float in conversions. By doing a logical comparison, f is cast to double and maybe the implementation you are using is giving inconsistent results. If you suffix f so the compiler registers it as a float, then you get 0.00 which is false in double type. Unsuffixed floating types are double.
#include <stdio.h>
#include <float.h>
int main()
{
double d = 0.1;
float f = 0.1f;
printf("%f\n", (f > d));
return 0;
}
'program tip' 카테고리의 다른 글
Go를 사용하여 대용량 파일을 효율적으로 다운로드하려면 어떻게해야합니까? (0) | 2020.08.20 |
---|---|
두 개의 변수가있는 "for 루프"? (0) | 2020.08.20 |
git log로만 변경된 파일 이름을 표시하는 방법은 무엇입니까? (0) | 2020.08.20 |
HTML 스팬 정렬 센터가 작동하지 않습니까? (0) | 2020.08.20 |
CSS : 요소의 내용 앞에 공백을 추가하는 방법은 무엇입니까? (0) | 2020.08.20 |