Pregunta

¿Qué tan costosa es la conversión de un float en un double ? ¿Es tan trivial como una conversión int a long ?

EDITAR: estoy asumiendo una plataforma donde el flotante es de 4 bytes y el doble es de 8 bytes

¿Fue útil?

Solución

Consideraciones de plataforma

Esto depende de la plataforma utilizada para el cálculo flotante. Con x87 FPU, la conversión es gratuita, ya que el contenido del registro es el mismo: el único precio que a veces puede pagar es el tráfico de memoria, pero en muchos casos incluso no hay tráfico, ya que simplemente puede usar el valor sin ninguna conversión. x87 es en realidad una bestia extraña a este respecto: es difícil distinguir adecuadamente entre flotadores y dobles, ya que las instrucciones y registros utilizados son los mismos, lo que es diferente son las instrucciones de carga / almacenamiento y la precisión de cálculo en sí misma se controla mediante bits de estado . El uso de cálculos mixtos flotantes / dobles puede dar lugar a resultados inesperados (y existen opciones de línea de comandos del compilador para controlar el comportamiento exacto y las estrategias de optimización debido a esto).

Cuando usa SSE (y a veces Visual Studio usa SSE por defecto), puede ser diferente, ya que puede necesitar transferir el valor en los registros de FPU o hacer algo explícito para realizar la conversión.

Rendimiento de ahorro de memoria

Como resumen, y respondiendo a su comentario en otro lugar: si desea almacenar los resultados de los cálculos flotantes en 32b de almacenamiento, el resultado será la misma velocidad o más rápido, porque:

  • Si hace esto en x87, la conversión es gratuita; la única diferencia será que se usará fstp dword [] en lugar de fstp qword [].
  • Si hace esto con SSE habilitado, incluso puede ver una ganancia de rendimiento, ya que algunos cálculos flotantes se pueden hacer con SSE una vez que la precisión del cálculo es solo flotante en lugar de doble predeterminado.
  • En todos los casos el tráfico de memoria es menor

Otros consejos

Las conversiones de flotación a doble suceden de forma gratuita en algunas plataformas (PPC, x86 si su compilador / tiempo de ejecución usa el "al diablo con qué tipo me dijo que usara, voy a evaluar todo en doble largo de todos modos, nyah nyah " modo de evaluación).

En un entorno x86 donde la evaluación de punto flotante se realiza realmente en el tipo especificado utilizando registros SSE, las conversiones entre flotante y doble son casi tan caras como una suma o multiplicación de punto flotante (es decir, es poco probable que sea una consideración de rendimiento a menos que estás haciendo muchas de ellas).

En un entorno integrado que carece de punto flotante de hardware, pueden ser algo costosos.

Esto es específico de la implementación de C ++ que está utilizando. En C ++, el tipo de punto flotante predeterminado es doble . Un compilador debe emitir una advertencia para el siguiente código:

float a = 3.45;

porque el valor doble 3.45 se está asignando a un flotante. Si necesita usar flotante específicamente, agregue el valor con f :

float a = 3.45f;

El punto es que todos los números de coma flotante son dobles por defecto. Es seguro mantener este valor predeterminado si no está seguro de los detalles de implementación de su compilador y no tiene una comprensión significativa del cálculo de coma flotante. Evita el yeso.

Consulte también la sección 4.5 de El lenguaje de programación C ++ .

No puedo imaginar que sea mucho más complejo. La gran diferencia entre convertir int a long y convertir float a double es que los tipos int tienen dos componentes (signo y valor) mientras que los números de coma flotante tienen tres componentes (signo, mantisa y exponente).

  

La precisión simple IEEE 754 está codificada   en 32 bits usando 1 bit para el signo, 8   bits para el exponente y 23 bits para   el significado Sin embargo, utiliza un   bit oculto, entonces el significado es 24   bits (p = 24), aunque sea   codificado utilizando solo 23 bits.

- David Goldberg, Lo que todo informático debe saber sobre el punto flotante Aritmética

Entonces, la conversión entre flotante y doble va a mantener el mismo bit de signo, establecer los últimos 23/24 bits de la mantisa del flotante en la mantisa del doble, y establecer los últimos 8 bits del exponente del flotante en el exponente del doble.

Este comportamiento incluso puede estar garantizado por IEEE 754 ... No lo he hecho lo comprobé, así que no estoy seguro.

probablemente un poco más lento que convertir int a long, ya que la memoria requerida es mayor y la manipulación es más compleja. Una buena referencia sobre problemas de alineación de memoria

Quizás esta ayuda:

#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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top