Мне нужно вычислить простое математическое выражение, но когда я делаю это в одной строке, результат всегда будет равен нулю. Но правильный результат явно не ноль. И это интересно, но когда я разделяю части выражения, я получаю правильный ответ.
Позже я разделю с этим результатом, поэтому он не должен быть 0.
Выражение выглядит так:
(X-X1)/(X2-X1)
В этом случае дельта: 0
double delta = (x - x1) / (x2 - x1);
Но так дельта будет правильно:
double top = x - x1;
double bottom = x2 - x1;
double delta = top/bottom;
У вас есть идеи, как это могло произойти?
Это типичный случай «целочисленного деления, используемого для получения значения с плавающей запятой». Если x
, x1
а также x2
все целые числа, то компилятор должен, согласно правилам C и C ++, использовать целочисленные вычисления для вычисления x-x1
а также x2-x1
, а затем разделить различия тех, как целочисленное деление. Если x2-x1
больше, чем x-x1
, тогда результат равен нулю [при условии положительных значений, таких как 7/14. -14 / -7, очевидно, 2].
Простое решение — преобразовать тип одного выражения в тип с плавающей точкой:
double delta = static_cast<double>(x - x1) / (x2 - x1);
В первом случае целое число / целое число, результат по-прежнему целое число, затем преобразуйте целое число в двойное число.
Во втором случае дважды / дважды, тогда вы получите правильный результат.
В первом случае вы выполняете int / int
что приведет к int
значение. Таким образом, если ваш знаменатель больше числителя, результат будет усечен до 0.
Во втором случае вы оцениваете double/double
выражение, которое будет оценивать double
значение, следовательно, сохраняя дробные и целые части.
Вы должны разыграть целочисленное деление, чтобы удвоить.
тип литья