paulo1205
(usa Ubuntu)
Enviado em 06/08/2022 - 01:13h
Sempre que você tem uma operação aritmética em que um dos operandos tem precisão menor que a do outro, o de menor precisão é promovido para o tipo do de maior precisão.
Contudo, olhe a sua expressão.
(5/9)*(temp1-32)
Você tem três operações, a saber:
•
5/9, cujos dois operandos,
5 e
9 são inteiros, de modo que a divisão é completamente inteira, produzindo um quociente inteiro igual a
0, e gerando um valor temporário inteiro que eu vou chamar de
t1;
•
temp1-32, que tem um operando
float (
temp1) e outro
int (
32), implicando uma promoção do valor inteiro para
float antes de realizar a subtração, que gera um valor temporário de ponto flutuante que eu vou chamar de
t2;
•
t1*t2, na qual um dos operandos é inteiro e o outro é de ponto flutuante, implicando a conversão do primeiro para ponto flutuante, para então realizar a multiplicação, produzindo o valor final da expressão.
Note que:
•
5/9 é uma operação com dois operandos constantes, então o compilador normalmente vai calcular o valor dessa expressão em tempo de compilação, de modo que essa divisão provavelmente não será observável no código objeto, já compilado.
• Mais ainda, como o valor resultante da divisão é
0, nos nossos PCs com processadores Intel e AMD, em vez de guardar esse valor na memória e depois carregá-lo para algum registrador, é tipicamente mais vantajoso emitir diretamente código que zera o valor de um registrador (por exemplo, fazendo um XOR do registrador consigo mesmo). Além disso, como o compilador vai inferir que o valor constante vai ser convertido para ponto flutuante, pode já emitir código que produz o valor zero já em ponto flutuante, sem passar pelas etapas de produzir primeiro um zero inteiro, e depois o converter.
• De modo semelhante, a constante
32 nunca é usada como inteiro antes de precisar ser convertida para ponto flutuante, de modo que o compilador pode optar por armazená-la no código compilado já convertida para ponto flutuante, assim evitando a etapa de conversão de tipo de dado durante a execução.
• Você provavelmente só vai conseguir observar que existe uma subtração e uma multiplicação se compilar o programa sem nenhuma otimização. Se ligar otimizações, é possível que o compilador identifique uma multiplicação com um dos fatores iguais a zero, e já decida simplesmente substituir toda a expressão por um valor de ponto flutuante nulo.
• Você pode evitar todas as conversões de tipo — e, mais do que isso, um resultado nulo para uma fração própria quando expressa com numerador e denominador inteiros — se tomar o cuidado de já colocar suas constantes como ponto flutuante, tal como mostra o exemplo abaixo.
float temp_celsius, temp_farenheit;
/* ... */
temp_celsius=(5.0f/9.0f)*(temp_farenheit-32.0f);
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)