Вопрос

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

Я не могу понять, почему (это должен быть положительный результат).Может ли кто-нибудь помочь?

Это было полезно?

Решение

Я полагаю, что компилятору необходимо округлить результат из " A + B * D " сначала к целому числу, потому что вы сохраняете результат в поле int. В общем, у вас конфликт типов данных.

И A, и B по-прежнему являются действительными числами для long long int, длина которого составляет 8 байтов. Вы можете даже умножить их на 1.000 и при этом иметь действительные значения long long int. В некоторых других языках он также известен как int64.

Двойное число также 64-битное, но часть из них используется как показатель степени. Когда вы умножаете double на int64, результатом будет еще один double. Добавление другого int64 к нему все еще сохраняет его двойным. Затем вы снова присваиваете результат для int64 без использования определенного метода округления. Меня не удивит, если для этого компилятор будет использовать 4-битную функцию округления. Я даже поражен тем, что компилятор не вырвался и не нарушил это утверждение!

В любом случае, при использовании таких больших чисел необходимо соблюдать особую осторожность при смешивании разных типов.

Другие советы

возможно, вы должны указать эти константы как "long long" литералы? например <Код> 3289168178315264LL

Какой компилятор/операционную систему вы используете?Я запустил ваш код с использованием Visual C++ 2008 Express Edition в Windows XP, и ЭТО РАБОТАЕТ - ответ:6578336356630528 (это 53-битное число, поэтому оно помещается внутри двойного числа).

Я также попробовал два варианта, чтобы проверить, имеет ли значение порядок операций:

длинный длинный int out = A;выход+=Б*Д;

длинный длинный int out = B*D;выход+=А;

И то, и другое работает!

Любопытный.

Ваш ответ (необходимо проверить) вычисляется успешно, однако он вызывает переполнение знакового бита, что делает ответ отрицательным.Решение :сделайте все ваши переменные беззнаковыми.

Почему:

Числа хранятся в памяти компьютера в виде последовательности битов.Установленный первый бит в такой серии означает, что ваше число отрицательное.Таким образом, расчет работает, но переполняется в знаковый бит.

Рекомендация:

Если вы работаете с такими большими числами, я рекомендую вам приобрести арифметическую библиотеку с повышенной точностью.Это сэкономит вам много времени и хлопот.

Параметр для sqrt должен быть double .

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

А также мы должны объяснить приведение результата из B * D в long long.

    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