С:ошибочный вывод для «(long long int) = (long long int) * (double)»?
-
06-07-2019 - |
Вопрос
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);