1.0 곱셈 정밀도 및 부동 변환으로의 int
그 상태가 다음과 같은 것으로 가정해도 안전한가요?(int)(i * 1.0f) == i
임의의 정수에 대해 참입니다.i
?
아니요.
한다면i
충분히 큽니다.int(float(i)) != i
(플로트가 IEEE-754 단일 정밀도라고 가정함)i = 0x1000001
이를 나타내기에 충분함) 그렇다면 이것은 거짓입니다. 왜냐하면 곱셈은1.0f
강제로 로 변환float
이는 후속 곱셈이 변경되지 않더라도 값이 변경됩니다.
하지만, 만약에i
는 32비트 정수이고double
IEEE-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);
}
43046721
32비트에서 사용할 수 있는 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
'programing' 카테고리의 다른 글
피드 및 팔로우 시스템을 구성하는 방법은 무엇입니까? (0) | 2023.06.27 |
---|---|
SEEK_CUR과 함께 제로 오프셋 infseeek() 함수가 사용되는 용도는 무엇입니까? (0) | 2023.06.27 |
Google Cloud Platform을 통해 Firebase에서 자동 전자 메일 전송(타사 제품 제외) (0) | 2023.06.07 |
mvc: favicon.ico도 컨트롤러를 찾습니까? (0) | 2023.06.07 |
고해상도 그래프를 그리는 방법 (0) | 2023.06.07 |