Pergunta

Como caro é a conversão de um float a um double? É tão trivial como uma int à conversão long?

EDIT: Estou assumindo uma plataforma onde onde float é de 4 bytes e duplo é de 8 bytes

Foi útil?

Solução

considerações Plataforma

Isso depende da plataforma utilizada para o cálculo float. Com x87 FPU a conversão é livre, como o teor de registo é o mesmo - o único preço que você pode, por vezes pagar é o tráfego de memória, mas em muitos casos há ainda nenhum tráfego, como você pode simplesmente usar o valor sem qualquer conversão. x87 é realmente uma besta estranha a este respeito - é difícil distinguir adequadamente entre carros alegóricos e dobra sobre ele, como as instruções e registros utilizados são os mesmos, o que é diferente são de carga / instruções de loja e em si precisão computação é controlado usando bits de status . Usando float / cálculos duplas mistas pode resultar em resultados inesperados (e há compilador opções de linha de comando para controle exato comportamento e otimização de estratégias por causa disso).

Quando você usa SSE (e, por vezes, Visual Studio usa SSE por padrão), ele pode ser diferente, como você pode precisar de transferir o valor nos registradores FPU ou fazer alguma coisa explícita para realizar a conversão.

Memória desempenho economia

Como um resumo, e respondendo ao seu comentário em outro lugar: se você deseja armazenar resultados de cálculos flutuante no armazenamento 32b, o resultado será a mesma velocidade ou mais rápido, porque:

  • Se você fizer isso em x87, a conversão gratuita -. A única diferença será dword fstp [] será usado em vez de QWORD fstp []
  • Se você fizer isso com SSE habilitado, você pode até mesmo ver algum ganho de desempenho, como alguns cálculos flutuador pode ser feito com SSE uma vez que a precisão do cálculo é apenas flutuar insteead de padrão duplo.
  • Em todos os casos, o tráfego de memória é menor

Outras dicas

Float para conversões duplas acontecer gratuitamente em algumas plataformas (PPC, x86 se o seu compilador / runtime usa o "para o inferno com o que tipo você me disse para usar, eu vou avaliar tudo em long double de qualquer maneira, nyah nyah "modo de avaliação).

Em um ambiente x86 onde a avaliação de ponto flutuante é realmente feito no tipo especificado usando registradores SSE, conversões entre float e double são quase tão caro como um add-ponto flutuante ou multiplicar (ou seja, pouco provável que seja uma consideração desempenho, a menos você está fazendo muito deles).

Em um ambiente embutido que carece de hardware de ponto flutuante, que pode ser um pouco caro.

Esta é específico para a implementação do C ++ você está usando. Em C ++, o tipo de ponto flutuante padrão é duplo . Um compilador deve emitir um aviso para o seguinte código:

float a = 3.45;

porque o valor double 3.45 está sendo atribuído a uma bóia. Se você precisa usar flutuador especificamente, sufixo o valor com f :

float a = 3.45f;

O ponto é, todos os números de ponto flutuante são por padrão duplo . É seguro manter esse padrão, se você não tiver certeza dos detalhes de implementação de seu compilador e não têm compreensão significativa de flutuar computação ponto. Evite o elenco.

Veja também a seção 4.5 of O C ++ Linguagem de programação .

Eu não posso imaginar que seria muito mais complexa. A grande diferença entre converter int para longo e convertendo float para double é que os tipos int tem dois componentes (sinal e valor), enquanto números de ponto flutuante tem três componentes (sinal, mantissa e expoente).

IEEE 754 de precisão simples é codificada em 32 bits usando o 1 bit para o sinal, 8 bits para o expoente e 23 bits para do significando. No entanto, ele usa um escondida pouco, de modo que o significand é 24 bocados (p = 24), embora seja codificados utilizando apenas 23 bits.

- David Goldberg, O que cada cientista computador deve saber sobre Floating-Point aritmética

Assim, a conversão entre float e double vai manter o mesmo bit de sinal, defina os últimos 23/24 bits de mantissa do flutuador a mantissa do casal e definir os últimos 8 bits de expoente do flutuador para expoente da dupla.

Este comportamento pode até ser garantida por IEEE 754 ... Eu não tenho verifiquei isso, então eu não tenho certeza.

provavelmente um pouco mais lento do que converter int para longo, como memória necessária é maior e manipulação é mais complexa. Uma boa referência sobre problemas de alinhamento de memória

Talvez esta ajuda:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

double _ftod(float fValue)
{
  char czDummy[30];
  printf(czDummy,"%9.5f",fValue);
  double dValue = strtod(czDummy,NULL);
  return dValue;
}


int main(int argc, char* argv[])
{
  float fValue(250.84f);
  double dValue = _ftod(fValue);//good conversion
  double dValue2 = fValue;//wrong conversion
  printf("%f\n",dValue);//250.840000
  printf("%f\n",dValue2);//250.839996
  getch();
  return 0;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top