0.1 float가 0.1 double보다 크다.나는 그것이 거짓이라고 기대했다.
허용:
double d = 0.1;
float f = 0.1;
라고 표현하면
(f > d)
돌아오다true
또는false
?
경험적으로 답은true
. 하지만, 나는 그렇게 될 것이라고 기대했다.false
.
로서0.1
2진법으로 완벽히 표현할 수 없는 반면, 2진법은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
2진수하려면
0.000110011001100110011001100110011001100110011001100...
영원히 되풀이되는
데이터 유형에 매핑하면 다음과 같은 이점을 얻을 수 있다.
floatsf1) = %0001100110011001101^-- 노트 라운딩doublemp1) = %0001100110011001100110011001100110011001100110011001100110011001100110000101010
기준 10으로 변환:
부동액1) = .100002384185791015625doubleft1) = .10000000000000000088817841970012523233890533447265625
이것은 브루스 도슨이 쓴 글에서 따온 것이다.여기에서 찾을 수 있다:
복식은 부유물이 아니므로 비교하지 마십시오.
이 질문에 대한 에릭 리퍼트의 언급은 사실 가장 명확한 설명이라고 생각되므로, 나는 답으로 다시 게시할 것이다.
1/9을 3자리 십진법과 6자리 십진법으로 계산한다고 가정합시다. 0.111 < 0.1111111, 맞지?
이제 6/9. 0.667 > 0.6667을 계산한다고 가정합시다.
3자리 소수점 중 6/9가 0.666이라고 할 수는 없다. 왜냐하면 그것은 6/9에 가장 가까운 3자리 소수점이 아니기 때문이다!
정확히 표현할 수 없기 때문에 베이스 2에서 1/10을 비교하는 것은 베이스 10에서 1/7을 비교하는 것과 같다.
1/7 = 0.142857142857...그러나 다른 기준 10의 정밀도(3과 소수점 6자리)를 비교하면 0.145 > 0.142857이다.
IEEE-754와 x86에 대해 이야기하는 다른 대답에 덧붙여 말하자면, 이 문제는 그들이 생각하는 것보다 훨씬 더 복잡하다.IEEE-754에서 0.1의 "하나" 표현은 없다. 두 가지가 있다.마지막 숫자를 아래로 반올림하거나 위로 반올림하는 것이 유효하다.x86은 내부 부동소수점 계산에 64비트를 사용하지 않고 실제로 80비트를 사용하기 때문에 이 차이는 실제로 발생할 수 있고 실제로 발생한다.이를 이중 연장정밀이라고 한다.
그래서, 단지 x86 컴파일러들 사이에서도, 어떤 사람들은 64비트로 그것의 이진 표현을 계산하는 반면, 다른 사람들은 80비트를 사용하기 때문에, 동일한 숫자가 두 가지 다른 방법으로 표현되는 것이 가끔 발생한다.
사실, 같은 컴파일러에서도, 심지어 같은 기계에서도 이런 일이 일어날 수 있답니다!
#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;
}
자세한 내용은 "이유인 경우에도"를 참조하십시오.
변환할 때 부동의 순위보다 2배 등급이 더 크다.논리적인 비교를 함으로써, f는 두 배로 주조되고 어쩌면 당신이 사용하고 있는 구현은 일관되지 않은 결과를 주고 있는지도 모른다.만약 당신이 f를 접미사하여 컴파일러가 그것을 플로트로 등록하면, 당신은 0.00을 얻게 되는데, 이것은 이중 타입으로 거짓이다.혼합되지 않은 부동유형은 이중이다.
#include <stdio.h>
#include <float.h>
int main()
{
double d = 0.1;
float f = 0.1f;
printf("%f\n", (f > d));
return 0;
}
'IT이야기' 카테고리의 다른 글
Linux에서 execlp()가 어떻게 작동하는지 이해할 수 없음 (0) | 2022.04.27 |
---|---|
공리 응답의 데이터 처리 (0) | 2022.04.27 |
Vue 앱에서 자동 복구된 사용자의 데이터를 가져오는 최적의 장소? (0) | 2022.04.27 |
범위를 벗어난 배열에 액세스하는 것은 얼마나 위험한가? (0) | 2022.04.27 |
Vuejs는 url에서 이미지를 캐슁하여 다시 fetching하지 마십시오. (0) | 2022.04.27 |