IT이야기

0.1 float가 0.1 double보다 크다.나는 그것이 거짓이라고 기대했다.

cyworld 2022. 4. 27. 21:40
반응형

0.1 float가 0.1 double보다 크다.나는 그것이 거짓이라고 기대했다.

허용:

double d = 0.1;
float f = 0.1;

라고 표현하면

(f > d)

돌아오다true또는false?

경험적으로 답은true. 하지만, 나는 그렇게 될 것이라고 기대했다.false.

로서0.12진법으로 완벽히 표현할 수 없는 반면, 2진법은1516소수 자릿수의 정밀도와 부동 소수점만 포함7그래서 둘 다 보다 작다.0.1, 반면 더블은 에 더 가깝다.0.1.

정확한 설명이 필요하다.true.

회전을 변환할 때 라운딩 모드에 따라 답이 달라지는 것 같다.doublefloat.float24개의 이진 비트의 정밀도를 가지고 있고double53개가 있다.이진수에서 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'

따라서 단일 정밀도 근사치가 더 크다는 것을 알 수 있다.

변환하는 경우.12진수하려면

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;
}

참조URL: https://stackoverflow.com/questions/19292283/0-1-float-is-greater-than-0-1-double-i-expected-it-to-be-false

반응형