Por que a divisão resulta em zero em vez de um decimal?

Ensinando a mim mesmo C e descobrindo que, quando faço uma equação para uma conversão temporária, não funciona a menos que eu mude a fração para um decimal. ou seja,

tempC=(.555*(tempF-32)) funcionará, mas tempC=((5/9)*(tempF-32)) não funcionará.

Por quê?
De acordo com o C Primer Plus, deve funcionar como eu estou usando floats para tempC e tempF.

Parece que você tem divisão inteira no segundo caso:

 tempC=((5/9)*(tempF-32)) 

O 5 / 9 será truncado para zero.

Para corrigir isso, você precisa fazer um deles um tipo de ponto flutuante:

 tempC=((5./9.)*(tempF-32)) 

Outros já lhe disseram, 5 e 9 são ambos inteiros e é por isso que o resultado fica truncado.

Vou adicionar uma explicação para uma compreensão mais profunda do que realmente acontece entre as linhas:

 double tempC; double tempF; tempC = (5/9) * (tempF-32); // removed unnecessary parenthesis 

Dependendo da ordem de avaliação , da esquerda para a direita ou da direita para a esquerda, que o seu compilador específico usa, ele começará a avaliar a sub-expressão (5/9) ou (tempF-32) .

Você não pode saber qual destes dois é avaliado primeiro! Porque a ordem de avaliação é um comportamento não especificado em C, o que significa que o compilador pode fazer isso de qualquer forma sem documentar como. Portanto, nunca se deve escrever código com base na ordem de avaliação, ou não será portável e possivelmente incorreto.


Vamos supor que um compilador específico use a avaliação da esquerda para a direita.

  • As regras de precedência do operador de C decidem onde a avaliação é iniciada. O operador parêntese tem a maior prioridade em C, portanto, o compilador começará avaliando o conteúdo do primeiro parênteses encontrado.
  • Portanto, começará com a expressão (5/9) .
  • O compilador verifica o tipo de cada operando.
  • Neste caso, ambos são literais inteiros constantes. Literais inteiros são sempre do tipo int em C.
  • Como os dois operandos são do mesmo tipo, não são necessárias conversões de tipo implícitas.
  • O cálculo é realizado em um tipo int e o resultado é um int .

Então agora a expressão agora é avaliada para:

tempC = (int)0 * (tempF-32);

  • O compilador então avalia (tempF-32).
  • Os tipos dos operandos são double e int . Eles não são do mesmo tipo.
  • Conversões implícitas de tipo ocorrem. Neste caso, algo chamado balanceamento (formalmente chamado de conversões aritméticas usuais ).
  • As regras de balanceamento dizem que, se um tipo é duplo e o outro é outra coisa, o outro tipo deve ser convertido em duplo.
  • Após a conversão de tipo implícito, a expressão é agora equivalente a (double)tempF - (double)32.0 . O resultado disso é calculado e armazenado em uma variável invisível e temporária do tipo double . Essa variável invisível é armazenada em um registrador da CPU ou na pilha.

Agora a expressão pode ser descrita como

tempC = (int)result1 * (double)result2;

em que “result1” é 0 e “result2” é o resultado de tempF – 32.0.

  • O compilador então avalia essa nova expressão. Ele encontra um int e um double .
  • Novamente, o balanceamento ocorre e o int é convertido em um duplo.
  • A multiplicação é executada em dois duplos e o resultado é um duplo.
  • O resultado é armazenado em outra variável temporária e invisível.

tempC = (double)result3;

  • O compilador avalia essa nova expressão. Ele descobre que um duplo deve ser salvo dentro de um duplo. Isso não é um problema, portanto, não são necessárias conversões implícitas. “result3” é armazenado em tempC.

Quando você faz 5/9, 5 e 9 são ambos inteiros e a divisão inteira acontece. O resultado da divisão de inteiros é um número inteiro e é o quociente dos dois operandos. Portanto, o quociente no caso de 5/9 é 0 e, como você multiplica por 0, tempC é 0. Para não ter divisão inteira, pelo menos um dos dois operandos deve ser float .

Por exemplo, se você usar 5.0 / 9 ou 5 / 9.0 ou 5.0 / 9.0, ele funcionará como esperado.

5/9 é uma divisão inteira e não uma divisão de ponto flutuante. É por isso que você está obtendo resultado errado.

Faça 5 ou 9 variables ​​de ponto flutuante e você receberá a resposta correta.

Como 5.0 / 9 OU 5 / 9.0

5/9 é uma expressão de inteiro, como tal, fica truncado para 0. seu compilador deve avisá-lo sobre isso, senão você deve olhar para ativar os avisos.

Se você colocar 5/9 entre parênteses, isso será calculado primeiro, e como esses são dois inteiros, isso será feito por divisão inteira e o resultado será 0, antes que o resto da expressão seja avaliado.

Você pode reorganizar sua expressão para que a conversão para float ocorra primeiro:

tempC=((5/9)*(tempF-32)); ? tempC=(5*(tempF-32))/9;

ou, claro, como os outros dizem, use constantes de ponto flutuante.