Ответ 1
Похоже, у вас есть целочисленное деление во втором случае:
tempC=((5/9)*(tempF-32))
5 / 9
будет усекаться до нуля.
Чтобы исправить это, вам нужно сделать один из них типа с плавающей запятой:
tempC=((5./9.)*(tempF-32))
Преподавая себя C и обнаружив, что когда я выполняю уравнение для временного преобразования, он не будет работать, если я не изменю дробь на десятичную. то есть,
tempC=(.555*(tempF-32))
будет работать, но tempC=((5/9)*(tempF-32))
не будет работать.
Почему?
Согласно C Primer Plus, он должен работать, поскольку я использую float для tempC и tempF.
Похоже, у вас есть целочисленное деление во втором случае:
tempC=((5/9)*(tempF-32))
5 / 9
будет усекаться до нуля.
Чтобы исправить это, вам нужно сделать один из них типа с плавающей запятой:
tempC=((5./9.)*(tempF-32))
Другие уже говорили вам, что 5 и 9 являются целыми числами, и поэтому результат усекается.
Я добавлю объяснение для более глубокого понимания того, что действительно происходит между строк:
double tempC;
double tempF;
tempC = (5/9) * (tempF-32); // removed unnecessary parenthesis
В зависимости от того, какой порядок оценки (слева направо или справа налево) использует конкретный компилятор, он начнет (tempF-32)
(5/9)
или (tempF-32)
.
Вы не можете знать, какой из этих двух оценивается первым! Поскольку порядок оценки - неопределенное поведение в C, это означает, что компилятор может сделать это в любом случае, не документируя как. Поэтому никогда не следует писать код, основанный на порядке оценки, иначе он не будет переносимым и, возможно, некорректным.
Предположим, что один конкретный компилятор использует оценку слева направо.
(5/9)
.5
и 9
всегда имеют тип int
в C.int
, неявные преобразования типов не требуются.int
а результатом является int
.До сих пор выражение оценивается как:
tempC = (int)0 * (tempF-32);
double
и int
. Они не того же типа.(double)tempF - (double)32
. Результат этого вычисляется и сохраняется во временной невидимой переменной типа double
. Эта невидимая переменная хранится в регистре процессора или в стеке.Теперь выражение можно описать как
tempC = (int)result1 * (double)result2;
где "result1" равен 0, а "result2" является результатом tempF - (double) 32.
int
и double
. tempC = (double)result3;
Когда вы делаете 5/9, 5 и 9 - оба целых числа и целочисленное деление. Результатом целочисленного деления является целое число, и это фактор двух операндов. Итак, фактор в случае 5/9 равен 0, и поскольку вы умножаетесь на 0, tempC получается равным 0. Чтобы не иметь целочисленного деления, по крайней мере один из двух операндов должен быть float
.
например. если вы используете 5.0/9 или 5/9.0 или 5.0/9.0, он будет работать, как ожидалось.
5/9 - целочисленное деление, а не деление с плавающей запятой. Вот почему вы получаете неправильный результат.
Сделайте 5 или 9 переменных с плавающей запятой, и вы получите правильный ответ.
Подобно 5.0/9 OR 5/9.0
5/9
является целочисленным выражением, поэтому он усекается до 0. Ваш компилятор должен предупредить вас об этом, иначе вы должны изучить возможность включения предупреждений.
Если вы помещаете 5/9 в круглую скобку, это будет сначала вычисляться, и поскольку это два целых числа, это будет выполняться с помощью целочисленного деления, и результат будет равен 0, пока не будет оценена остальная часть выражения.
Вы можете изменить свое выражение так, чтобы сначала было преобразование в float:
tempC=((5/9)*(tempF-32));
→ tempC=(5*(tempF-32))/9;
или, конечно, как говорят другие, используйте константы с плавающей запятой.