program story

모든 정수 값이 double로 완벽하게 표현됩니까?

inputbox 2021. 1. 7. 07:57
반응형

모든 정수 값이 double로 완벽하게 표현됩니까?


이 질문에 이미 답변이 있습니다.

내 질문은 모든 정수 값이 완벽한 이중 ​​표현을 보장하는지 여부입니다.

"Same"을 인쇄하는 다음 코드 샘플을 고려하십시오.

// Example program
#include <iostream>
#include <string>

int main()
{
  int a = 3;
  int b = 4;
  double d_a(a);
  double d_b(b);

  double int_sum = a + b;
  double d_sum = d_a + d_b;

  if (double(int_sum) == d_sum)
  {
      std::cout << "Same" << std::endl;
  }
}

이것은 모든 아키텍처, 컴파일러, a값에 대해 사실이 보장 b됩니까? i로 변환 된 정수 double는 항상로 표시되고 표시 i.0000000000000되지 i.000000000001않습니까?

나는 다른 숫자를 위해 그것을 시도했고 그것은 항상 사실이지만 이것이 우연인지 디자인인지에 대해서는 아무것도 찾지 못했습니다.

참고 : 이것은 두 정수를 더하기 때문에이 질문 (언어 제외 )과 다릅니다 .


면책 조항 (Toby Speight에서 제안한대로) : IEEE 754 표현이 매우 일반적이지만 구현시 언어 요구 사항을 충족하는 다른 표현을 사용할 수 있습니다.


double은 형식으로 표시됩니다. mantissa * 2^exponent즉, 일부 비트는 double 숫자의 정수가 아닌 부분에 사용됩니다.

             bits        range                       precision
  float        32        1.5E-45   .. 3.4E38          7- 8 digits
  double       64        5.0E-324  .. 1.7E308        15-16 digits
  long double  80        1.9E-4951 .. 1.1E4932       19-20 digits

IEEE 754 이중 유형의 회로도

분수의 부분은 점 뒤의 모든 숫자를 제거하는 지수를 사용하여 정수를 나타내는 데 사용할 수도 있습니다.

예 : 2,9979 · 10 ^ 4 = 29979.

common int은 일반적으로 32 비트 이므로 모든 ints를 double로 나타낼 수 있지만 64 비트 정수의 경우 더 이상 사실이 아닙니다. 더 정확하게 말하면 (LThode가 주석에서 언급했듯이) : IEEE 754 배정 밀도는 최대 53 비트 (유의 52 비트 + 암시 적 선행 1 비트)에 대해이를 보장 할 수 있습니다.

답변 : 32 비트 정수의 경우 예, 64 비트 정수의 경우 아니오.

(이것은 서버 / 데스크톱 범용 CPU 환경에 적합하지만 다른 아키텍처는 다르게 동작 할 수 있습니다.)

Malcom McLean이 말한 실용적인 대답 : 64 비트 double은 실제 생활에서 계산할 가능성이있는 거의 모든 정수에 적합한 정수 유형입니다.


경험적으로 기울이는 경우 다음을 시도 하십시오 .

#include <iostream>
#include <limits>
using namespace std;

int main() {
    double test;
    volatile int test_int;
    for(int i=0; i< std::numeric_limits<int>::max(); i++) {
        test = i;
        test_int = test;

        // compare int with int:
        if (test_int != i)
            std::cout<<"found integer i="<<i<<", test="<<test<<std::endl;
    }
    return 0;
}

성공 시간 : 0.85 메모리 : 15240 신호 : 0


Subquestion : 분수 차이에 대한 질문에 대해. 분수에 의해 정확한 값을 벗어나지 만 반올림으로 인해 동일한 정수로 다시 변환되는 double로 변환되는 정수를 가질 수 있습니까?

The answer is no, because any integer which converts back and forth to the same value, actually represents the same integer value in double. For me the simplemost explanation (suggested by ilkkachu) for this is that using the exponent 2^exponent the step width must always be a power of two. Therefore, beyond the largest 52(+1 sign) bit integer, there are never two double values with a distance smaller than 2, which solves the rounding issue.


No. Suppose you have a 64-bit integer type and a 64-bit floating-point type (which is typical for a double). There are 2^64 possible values for that integer type and there are 2^64 possible values for that floating-point type. But some of those floating-point values (in fact, most of them) do not represent integer values, so the floating-point type can represent fewer integer values than the integer type can.


The answer is no. This only works if ints are 32 bit, which, while true on most platforms, isn't guaranteed by the standard.

The two integers can share the same double representation.

For example, this

#include <iostream>
int main() {
    int64_t n = 2397083434877565865;
    if (static_cast<double>(n) == static_cast<double>(n - 1)) {
        std::cout << "n and (n-1) share the same double representation\n";
    }
}    

will print

n and (n-1) share the same double representation

I.e. both 2397083434877565865 and 2397083434877565864 will convert to the same double.

Note that I used int64_t here to guarantee 64-bit integers, which - depending on your platform - might also be what int is.


You have 2 different questions:

Are all integer values perfectly represented as doubles?

That was already answered by other people (TL;DR: it depends on the precision of int and double).

Consider the following code sample that prints "Same": [...] Is this guaranteed to be true for any architecture, any compiler, any values of a and b?

Your code adds two ints and then converts the result to double. The sum of ints will overflow for certain values, but the sum of the two separately-converted doubles will not (typically). For those values the results will differ.


짧은 대답은 "가능하다"입니다. 휴대용 대답은 "모든 곳이 아닙니다"입니다.

실제로 플랫폼에 따라 다르며 특히

  • 크기 및 표현 double
  • 범위 int

IEEE-754 double을 사용하는 플랫폼의 경우 53 비트 이하 이면 참일 있습니다 int. int보다 큰 플랫폼 double의 경우 분명히 거짓입니다.

std::numeric_limits및을 사용하여 런타임 호스트의 속성을 조사 할 수 있습니다 std::nextafter.

참조 URL : https://stackoverflow.com/questions/43655668/are-all-integer-values-perfectly-represented-as-doubles

반응형