programing

1.0 곱셈 정밀도 및 부동 변환으로의 int

mytipbox 2023. 6. 7. 23:59
반응형

1.0 곱셈 정밀도 및 부동 변환으로의 int

그 상태가 다음과 같은 것으로 가정해도 안전한가요?(int)(i * 1.0f) == i임의의 정수에 대해 참입니다.i?

아니요.

한다면i충분히 큽니다.int(float(i)) != i(플로트가 IEEE-754 단일 정밀도라고 가정함)i = 0x1000001이를 나타내기에 충분함) 그렇다면 이것은 거짓입니다. 왜냐하면 곱셈은1.0f강제로 로 변환float이는 후속 곱셈이 변경되지 않더라도 값이 변경됩니다.

하지만, 만약에i는 32비트 정수이고doubleIEEE-754가 이중인 경우, 다음이 사실입니다.int(i*1.0) == i.


확실히 말하자면, 곱셈은1.0f 정확합니다.로부터의 변환입니다.int로.float그렇지 않을 수도 있습니다.

아니요, IEEE-754 부동 소수점 번호는 동일한 비트 폭에 대한 정수 정밀도를 희생하여 정수보다 큰 동적 범위를 갖습니다.

이 작은 스니펫의 출력 예를 참조하십시오.

int main() {
        int x = 43046721;

        float y = x;

        printf("%d\n", x);
        printf("%f\n", y);
}

4304672132비트에서 사용할 수 있는 24비트의 정밀도로 정확하게 표현할 수 없습니다.float숫자. 따라서 출력은 다음과 같습니다.

43046721
43046720.000000

실제로 16,777,216보다 큰 홀수는 32비트로 변환할 때 동일한 문제가 발생할 것으로 예상됩니다.float번호.

몇 가지 관심사:

  • 이는 곱셈 자체보다는 암묵적인 int-to-float 변환과 더 많은 관련이 있습니다.

  • 이것은 C에만 국한된 것이 아닙니다. 예를 들어 Java도 동일한 문제의 영향을 받습니다.

  • 대부분의 컴파일러에는 표준의 특정 제한 사항을 무시하여 이러한 변환 처리 방법에 영향을 줄 수 있는 최적화 옵션이 있습니다.이런 경우에는,(int)((float)x * 1.0f) == x항상 그럴 수도 있습니다.true컴파일러가 변환을 최적화하면float그리고 뒤로.

아니요, C와 C++는 IEEE-754를 필요로 하지 않기 때문에 동작은 구현으로 정의됩니다. 비록 그것이 지금까지 가장 일반적인 표현이기는 하지만요.

IEEE-754가 사용되는지 확인하려면:

  • C에서 사용#ifdef __STDC_IEC_559__
  • C++에서, 사용합니다.std::numeric_limits<float>::is_iec559상수

아니요, 주조된 유형 때문에 모든 정수에 대해 완전히 잘못된 것입니다.체크 코드

#include <stdio.h>

int main()
{
    int i = 0;
    for (; i < 2147483647; ++i) {
        if ((int)(i * 1.0f) != i) {
            printf("not equal\n");
            break;
        }
    }
    printf("out of the loop\n");
    getchar();
    return 0;
}

이 코드는 32비트 정수를 사용한다고 가정합니다.

언급URL : https://stackoverflow.com/questions/13400742/precision-of-multiplication-by-1-0-and-int-to-float-conversion

반응형