Это ведет себя как нужно:
double t = r[1][0] * .5;
Но это не так:
double t = ((1/2)*r[1][0]);
r
является двумерным вектором.
Просто подумал о возможности. Это потому, что (1/2
) считается int
и (1/2) == 0
?
Это ведет себя как нужно:
double t = r[1][0] * .5;
Но это не так:
double t = ((1/2)*r[1][0]);
r
является двумерным вектором.
Просто подумал о возможности. Это потому, что (1/2
) считается int
и (1/2) == 0
?
Это потому, что (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
.
Вместо этого напишите:
double t = ((1/2.0)*r[1][0]);
1 / 2
- целочисленное деление, а результат 0
.
1 / 2.0
- это деление с плавающей запятой (с double
значениями после обычных арифметических преобразований), и его результат 0.5
.
Потому что 1/2
- это int
/int
деление. Это означает, что любой результат будет иметь что-либо после удаления десятичной точки (усеченный). Итак, 1/2
= 0,5 = 0.
Обычно я всегда записываю первое число в double
: 1.0/2
.....
Если вы сделаете самый первый номер a double
, то все оставшиеся вычисления выполняются только в double
.
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.
Вместо этого вы можете написать 1.0/2.0. 1/2 отображает это поведение, потому что как знаменатель, так и числитель имеют целочисленный тип, а переменная целочисленного типа, деленная на другую переменную целочисленного типа, всегда усекается до целого числа.
Я не могу заслужить или понизить стандарт вопроса, но для меня это очень важный вопрос. Мы предполагаем, что компилятор будет делать стирку для нас все время, но что не соответствует действительности несколько раз.
Есть ли способ избежать этой ситуации?
ИЛИ
Более важно знать монстра (C
, C++
), поскольку большинство людей указывают выше
Я хотел бы знать, есть ли другие способы отследить эти проблемы "усечения" во время компиляции