Имеет ли присутствие один тип данных с плавающей точкой (например, double
) обеспечить, чтобы все математические операции +, -, *, /,% и т. д. принимали двойные операнды?
Если история сложнее этого, есть ли ресурс, который описывает эти правила? Я не должен задавать такие вопросы и всегда явно int
в double
когда результат уравнения double
, Вот некоторые уравнения, о которых я думаю. Я специально не скомпилировал и не запустил тогда в моей системе, так как это тот тип вещей, который может зависеть от компилятора.
int a(1), b(2), c(3);
double d(4.);
double result1 = a + b/d + c; // equal to 4 or to 4.5?
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?
double result3 = a/b + d; // equal to 4 or to 4.5?
Я специально не скомпилировал и не запустил тогда в моей системе, так как это тот тип вещей, который может зависеть от компилятора.
Это не зависит от компилятора. C ++ четко определяет порядок этих операций и как они обращаются.
То, как происходит преобразование, зависит от порядка операций.
double result1 = a + b / d + c; // equal to 4 or to 4.5?
В этом примере деление происходит первым. Поскольку это int, деленное на double, компилятор обрабатывает это путем преобразования int в double. Таким образом, результат b / d
это двойной.
Следующее, что делает C ++, это добавляет a
к результату b / d
, Это int, добавляемый к double, поэтому он конвертирует int в double и добавляет, в результате чего получается double. То же самое происходит с c
,
double result3 = a / b + d; // equal to 4 or to 4.5?
В этом примере деление обрабатывается первым. a
а также b
оба целые, поэтому конвертация не производится. Результат a / b
имеет тип int и равен 0.
Затем результат этого добавляется к d
, Это int плюс double, поэтому C ++ конвертирует int в double, и в результате получается double.
Хотя в этом выражении присутствует двойная буква, a / b
оценивается первым, и double ничего не значит, пока выполнение не достигнет double. Следовательно, происходит целочисленное деление.
Я нахожу правила продвижения и конверсии довольно сложными. Обычно целочисленные числа (short, int, long) переводятся в эквиваленты с плавающей точкой (float, double). Но все усложняется разницей в размерах и знаками.
Увидеть этот вопрос для подробностей о конверсии.
Делает один
double
продвигать каждыйint
в уравнении кdouble
?
Нет. Только результат одной операции (относительно приоритета).
double result1 = a + b/d + c; // equal to 4 or to 4.5?
4,5.
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?
3,75.
double result3 = a/b + d; // equal to 4 or to 4.5?
4.
Вы должны учитывать приоритет каждого оператора, вы должны думать как парсер:
double result1 = a + b/d + c; // equal to 4 or to 4.5?
Это похоже на + (b / d) + c, потому что оператор ‘/’ имеет наибольший приоритет. Тогда не имеет значения, какая из этих 2 операций выполняется в первую очередь, потому что операнд с плавающей запятой находится в середине, и он «заражает» другие операнды и делает их двойными. Так что это 4.5.
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?
То же самое здесь, это похоже на ((a + b) / d) + c, поэтому a + b равно 3, что 3 становится числом с плавающей запятой, потому что повышается до двойного, потому что это дивиденд от d, который является двойным, поэтому это 0,75 + 3, то есть 3,75.
double result3 = a/b + d; // equal to 4 or to 4.5?
Это как (a / b) + d, поэтому a / b равно нулю, а d равно 4, так что это 4.
Парсер выполняет все операции в порядке приоритета, чтобы вы могли точно знать, что будет результатом выражения.
Как правило, если один операнд бинарного оператора является плавающей запятой, а другой — целым числом, целое число преобразуется в число с плавающей запятой, а результат — с плавающей запятой.
В составном выражении с несколькими подвыражениями каждый оператор обрабатывается индивидуально с использованием правил приоритета, которые вы, вероятно, знаете. Таким образом, в a*b + c*d
, a*b
оценивается, и c*d
оценивается, и результаты суммируются. Что бы ни было в c*d
не имеет никакого эффекта в a*b
и наоборот.
С ++, конечно, сложен, и пользовательские операторы могут иметь другое поведение.
Авторитетным ресурсом, который определяет правила, является стандарт C ++. Стандарт довольно большой и технический. Вы могли бы предпочесть сначала изучить стандарт C. Увидеть этот ответ для ссылок на стандарты. Любая хорошая книга по C или C ++ должна описывать преобразования типов по умолчанию и оценку выражений.