문제

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);

long long int out = A + B*D;

printf("%lld",out);

결과는 다음과 같습니다. -2147483648

왜 그런지 알 수 없습니다 (긍정적 인 결과가되어야합니다). 누군가 도울 수 있습니까?

도움이 되었습니까?

해결책

내 생각에 컴파일러는 결과를 int 필드 내에 저장하기 때문에 결과를 "A+B*D"에서 정수로 먼저 반올림해야한다고 생각합니다. 기본적으로 데이터 유형 충돌이 있습니다.

A와 B는 여전히 길이 긴 int의 경우 여전히 유효한 숫자이며, 이는 8 바이트 길이입니다. 당신은 그것들에 1.000을 곱할 수도 있고 여전히 유효한 긴 긴 INT 값을 가질 수 있습니다. 다른 언어에서는 int64라고도합니다.

그러나 더블은 64 비트이지만 그 중 일부는 지수로 사용됩니다. INT64에 더블을 곱하면 결과는 또 다른 두 배가됩니다. 다른 int64를 추가하면 여전히 두 배로 유지됩니다. 그런 다음 특정 반올림 방법을 사용하지 않고 결과를 Int64에 다시 할당합니다. 컴파일러가이를 위해 4 비트 반올림 함수를 사용한다면 놀라지 않을 것입니다. 컴파일러가 그 진술을 멈추지 않고 깨지지 않는다는 것에 놀랐습니다!

어쨌든, 이와 같은 많은 숫자를 사용할 때는 다른 유형을 혼합 할 때 더 조심해야합니다.

다른 팁

어쩌면 그 상수를 "긴 긴"리터럴로 지정해야할까요? 예를 들어 3289168178315264LL

어떤 컴파일러/운영 체제를 사용하고 있습니까? Windows XP에서 Visual C ++ 2008 Express Edition을 사용하여 코드를 실행했으며 작동합니다. 답변 : 6578333356630528 (이것은 53 비트 번호이므로 더블에 맞습니다).

또한 운영 순서가 중요한지 확인하기 위해 두 가지 변형을 시도했습니다.

긴 긴 int out = a; out+= b*d;

긴 긴 int out = b*d; out+= a;

이 둘 다 작동합니다!

궁금한.

귀하의 답변 (확인해야 함)은 성공적으로 석회화되지만 부호 비트로 오버플로가 발생하여 답변이 음수로 만듭니다. 해결책 : 모든 변수를 서명하지 않도록하십시오.

왜:

숫자는 컴퓨터의 메모리에 일련의 비트로 저장됩니다. 해당 시리즈의 첫 번째 비트는 세트가 숫자가 음수임을 의미합니다. 따라서 계산은 작동하지만 부호 비트로 넘쳐납니다.

추천:

이 큰 숫자로 작업하는 경우 Multiprecision 산술 라이브러리를 얻는 것이 좋습니다. 'T는 당신에게 많은 시간과 문제를 절약 할 것입니다.

SQRT의 매개 변수는 있어야합니다 더블.

#include <math.h>
double sqrt( double num );

또한 우리는 결과를 b * d에서 오래까지 시전하는 것을 설명해야합니다.

    long long int A = 3289168178315264;
    long long int B = 1470960727228416;
    double D = sqrt(5.0);
    printf("%f\n",D);
    long long int out = A + (long long) (B * D);
    printf("%lld",out);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top