Почему (1/2) * x отличается от 0.5 * x?

Это ведет себя как нужно:

double t = r[1][0] * .5;

Но это не так:

double t = ((1/2)*r[1][0]);

r является двумерным вектором.

Просто подумал о возможности. Это потому, что (1/2) считается int и (1/2) == 0?

Ответ 1

Это потому, что (1/2) считается int и (1/2) == 0?

Да, оба этих литерала имеют тип int, поэтому результат будет иметь тип int, и этот результат равен 0.

Вместо этого сделайте один из этих литералов a float или double, и вы получите результат с плавающей запятой 0.5, то есть:

double t = ((1.0/2)*r[1][0]);

Поскольку 1.0 имеет тип double, int 2 будет продвигаться до double, и результат будет double.

Ответ 2

Вместо этого напишите:

  double t = ((1/2.0)*r[1][0]);

1 / 2 - целочисленное деление, а результат 0.

1 / 2.0 - это деление с плавающей запятой (с double значениями после обычных арифметических преобразований), и его результат 0.5.

Ответ 3

Потому что 1/2 - это int/int деление. Это означает, что любой результат будет иметь что-либо после удаления десятичной точки (усеченный). Итак, 1/2= 0,5 = 0.

Обычно я всегда записываю первое число в double: 1.0/2.....

Если вы сделаете самый первый номер a double, то все оставшиеся вычисления выполняются только в double.

Ответ 4

double t = r[1][0] * .5;

эквивалентно:

double t = ((1/2f)*r[1][0]);

и не:

double t = ((1/2)*r[1][0]);

Из-за потери десятичной части, когда временный результат 1/2 сохраняется в переменной int.

Как правило, всякий раз, когда есть разделение, и существует вероятность того, что ответ будет действительным числом, не используйте int или создайте один из операндов float или double или используйте cast.

Ответ 5

Вместо этого вы можете написать 1.0/2.0. 1/2 отображает это поведение, потому что как знаменатель, так и числитель имеют целочисленный тип, а переменная целочисленного типа, деленная на другую переменную целочисленного типа, всегда усекается до целого числа.

Ответ 6

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

Есть ли способ избежать этой ситуации?

Возможно

ИЛИ

Более важно знать монстра (C, C++), поскольку большинство людей указывают выше

Я хотел бы знать, есть ли другие способы отследить эти проблемы "усечения" во время компиляции