Google 계산기 결함은 부동 대 부동(float)이 될 수 있습니다.이중 가능한 이유가 있습니까?

StackOverflow https://stackoverflow.com/questions/27095

  •  09-06-2019
  •  | 
  •  

문제

나는 단지 재미삼아 이 작업을 수행했지만(따라서 정확히 질문은 아니지만 이미 다운모딩이 진행되고 있음을 알 수 있습니다) Google의 새로운 발견 대신 할 수 없음 할 것 수학 바르게 (확인해 봐!Google 500,000,000,000,002 - 500,000,000,000,001 = 0)에 따르면, 나는 약간의 이론을 실행하기 위해 C에서 다음을 시도해 볼 것이라고 생각했습니다.

int main()
{
   char* a = "399999999999999";
   char* b = "399999999999998";

   float da = atof(a);
   float db = atof(b);

   printf("%s - %s = %f\n", a, b, da-db);

   a = "500000000000002";
   b = "500000000000001";
   da = atof(a);
   db = atof(b);
   printf("%s - %s = %f\n", a, b, da-db);
}

이 프로그램을 실행하면 다음과 같은 결과가 나옵니다.

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

Google이 단순한 32비트 부동 정밀도(여기서는 오류)를 사용하는 것처럼 보입니다. 위 코드에서 부동 소수점을 double로 전환하면 문제가 해결됩니다!이게 아닐까?

/mp

도움이 되었습니까?

해결책

C #에서 (double.maxvalue== (double.maxvalue-100)) 시도하면 true가됩니다 ...

하지만 그게 당연한 것입니다 :

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

생각해 보면 2 ^ 64 (double.maxvalue)보다 큰 숫자를 나타내는 64 비트가 있으므로 부정확성이 예상됩니다.

다른 팁

<인용구>

Google이 단순한 32 비트 부동 정밀도 (여기서는 오류)를 사용하는 것 같습니다. 위 코드에서 float를 double로 전환하면 문제가 해결됩니다!이것이 가능할까요?

아니요, 문제를 연기하면됩니다.복식은 더 큰 숫자로만 동일한 문제를 나타냅니다.

@ebel

생각해 보면 2^64(double.maxvalue)보다 큰 숫자를 나타내는 64비트가 있으므로 부정확성이 예상됩니다.

2^64는 double의 최대값이 아닙니다.2^64는 double(또는 다른 64비트 유형)이 보유할 수 있는 고유 값의 수입니다. Double.MaxValue 1.79769313486232e308과 같습니다.

부동 소수점 숫자의 부정확성은 다음보다 큰 값을 나타내는 데서 발생하지 않습니다. Double.MaxValue (이를 제외하면 불가능합니다. Double.PositiveInfinity).이는 원하는 값 범위가 너무 커서 데이터 유형에 맞지 않는다는 사실에서 비롯됩니다.그래서 우리는 더 큰 유효 범위를 대가로 정밀도를 포기합니다.본질적으로 우리는 더 큰 지수 범위에 대한 대가로 유효 숫자를 삭제하고 있습니다.

@DrPizza

심지어는 아닙니다.IEEE 인코딩은 동일한 값에 대해 여러 인코딩을 사용합니다.특히 NaN은 all-bits-1의 지수와 가수의 0이 아닌 값으로 표현됩니다.따라서 복식에는 252개의 NaN이 있고, 단식에는 223개의 NaN이 있습니다.

진실.중복 인코딩을 고려하지 않았습니다.실제로는 2개가 있다52복식의 경우 -1 NaN 및 223그러나 싱글의 경우 -1 NaN입니다.:피

<인용구>

2 ^ 64는 double의 최대 값이 아닙니다.2 ^ 64는 double (또는 다른 64 비트 유형)이 보유 할 수있는 고유 한 값의 수입니다.Double.MaxValue는 1.79769313486232e308과 같습니다.

고르지 않습니다.IEEE 인코딩은 동일한 값에 대해 여러 인코딩을 사용합니다.특히 NaN은 all-bits-1의 지수와 가수에 대해 0이 아닌 모든 값으로 표시됩니다.따라서 복식의 경우 2 52 NaN, 싱글의 경우 2 23 NaN이 있습니다.

<인용구>

맞습니다.중복 인코딩을 고려하지 않았습니다.실제로 복식의 경우 252-1 NaN이 있고 싱글의 경우 223-1 NaN이 있습니다.: p

도우, 무한도 빼는 걸 잊었 네요.

제가 배운이 문제의 대략적인 추정 버전은 32 비트 부동 소수점은 5 자리 정밀도를 제공하고 64 비트 부동 소수점은 15 자리 정밀도를 제공한다는 것입니다.물론 이것은 float가 인코딩되는 방법에 따라 다르지만 꽤 좋은 시작점입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top