Другие уже сказали вам, что 5 и 9 являются целыми числами, поэтому результат усекается.
Я добавлю объяснение для более глубокого понимания того, что на самом деле происходит между строками:
double tempC;
double tempF;
tempC = (5/9) * (tempF-32); // removed unnecessary parenthesis
В зависимости от которых порядка оценки, слева направо или справа налево, что ваш конкретный компилятор использует, он либо начнет оценивать подвыражение (5/9)
, либо (tempF-32)
.
Вы не можете знать, какой из этих двух оценивается первым! Поскольку порядок оценки - это неуказанное поведение в C, это означает, что компилятор может сделать это в любом случае без документирования. Поэтому никогда не следует писать код, основанный на порядке оценки, или он не будет переносимым и, возможно, неправильным.
Предположим, что один конкретный компилятор использует оценку слева направо.
- Правила приоритета оператора C определяют, где начинается оценка. Оператор скобки имеет наивысший приоритет в C, поэтому компилятор начнет с оценки содержимого первой скобки.
- Поэтому оно начинается с выражения
(5/9)
.
- Компилятор проверяет тип каждого операнда.
- В этом случае они являются постоянными целыми литералами. Целочисленные литералы всегда имеют тип
int
в C.
- Поскольку оба операнда одного типа, не требуется неявных преобразований типов.
- Расчет производится по типу
int
, а результат - int
.
Так что теперь выражение теперь оценивается в:
tempC = (int)0 * (tempF-32);
- Компилятор затем оценивает (tempF-32).
- Типы операндов
double
и int
. Они не одного типа.
- Имеются неявные преобразования типов. В этом случае что-то называемое балансировкой (формально называемое обычными арифметическими преобразованиями).
- Правила балансировки говорят, что если один тип является двойным, а другой - чем-то другим, другой тип должен быть преобразован в double.
- После неявного преобразования типов выражение теперь эквивалентно
(double)tempF - (double)32.0
. Результат этого рассчитывается и сохраняется во временной, невидимой переменной типа double
. Эта невидимая переменная хранится в регистре CPU или в стеке.
Теперь выражение может быть описана как
tempC = (int)result1 * (double)result2;
, где "результат1" равно 0 и "результат2" является результатом tempF - 32,0.
- Затем компилятор оценивает это новое выражение. Он находит
int
и double
.
- Снова происходит балансировка, а int преобразуется в двойную.
- Умножение выполняется в двух двухместных, а результат - в двойном.
- Результат сохраняется в еще одной временной, невидимой переменной.
tempC = (double)result3;
- компилятор оценивает это новое выражение.Он обнаруживает, что двойник должен быть сохранен внутри двойника. Это не проблема, поэтому никаких неявных преобразований не требуется. «result3» хранится в tempC.
Это усечение, хотя и не округление. – jmkeyes
Спасибо за терминологию. :) – Mysticial
doh! Спасибо ... это имеет смысл сейчас. Я видел несколько примеров с десятичной точкой, но ни копейки не упал. Всем спасибо! –