resueltos que punto numeros numericos normalizada norma metodos mantisa informatica flotante fijo ejercicios ejemplos coma aritmetica c++ fixed-point

c++ - que - Conversión de punto flotante a punto fijo



punto flotante metodos numericos (6)

En C ++, ¿cuál es la forma genérica de convertir cualquier valor de coma flotante (flotante) a punto fijo (int, 16:16 o 24: 8)?

EDITAR: para aclarar, los valores de punto fijo tienen dos partes: una parte entera y una parte fraccionaria. La parte entera se puede representar mediante un tipo de datos entero con signo o sin signo. La parte fraccionaria se representa mediante un tipo de datos entero de datos sin signo.

Hagamos una analogía con el dinero en aras de la claridad. La parte fraccionaria puede representar centavos, una parte fraccionaria de un dólar. El rango del tipo de datos ''centavos'' sería de 0 a 99. Si se utilizara un entero sin signo de 8 bits para matemática de punto fijo, entonces la parte fraccionaria se dividiría en 256 partes divisibles uniformemente.

Espero que eso aclare las cosas.


**** Edit **: Mi primer comentario se aplica a antes de la edición de Kevin, pero lo dejaré aquí para la posteridad. ¡Las respuestas cambian tan rápido aquí a veces!

El problema con el enfoque de Kevin es que con Fixed Point normalmente se empaqueta en un tamaño de palabra garantizado (normalmente, 32bits). Declarar las dos partes por separado te deja al capricho del empaque de la estructura de tu compilador. Sí, podría forzarlo, pero no sirve para nada más que la representación de 16:16.

KPexEA está más cerca de la marca al incluir todo en int, aunque usaría "signed long" para tratar de ser explícito en 32bits. Luego puede usar su enfoque para generar el valor del punto fijo, y el corte de bits extrae las partes componentes nuevamente. Su sugerencia también cubre el caso 24: 8.

(Y todos los demás que sugirieron solo static_cast ..... ¿qué estabas pensando?;))


Esto está bien para convertir de coma flotante a entero, pero el OP también quería un punto fijo .

Ahora cómo lo harías en C ++, no sé (C ++ no es algo en lo que pueda pensar fácilmente). Tal vez intente un enfoque de entero escalado, es decir, utilice un entero de 32 o 64 bits y asigne de manera programática los últimos, digamos, 6 dígitos a lo que está en el lado derecho del punto decimal.


No hay ningún soporte integrado en C ++ para números de punto fijo. Su mejor opción sería escribir una clase contenedora ''FixedInt'' que tome dobles y los convierta.

En cuanto a un método genérico para convertir ... la parte int es bastante fácil, solo toma la parte entera del valor y almacénala en los bits superiores ... la parte decimal sería algo como:

for (int i = 1; i <= precision; i++) { if (decimal_part > 1.f/(float)(i + 1) { decimal_part -= 1.f/(float)(i + 1); fixint_value |= (1 << precision - i); } }

aunque es probable que esto contenga errores


Un lanzamiento de flotante a entero arrojará la porción fraccionaria, por lo tanto, si desea mantener esa fracción como punto fijo, simplemente multiplique el flotador antes de lanzarlo. El siguiente código no verificará si hay desbordamiento.

Si quieres 16:16

double f = 1.2345; int n; n=(int)(f*65536);

si quieres 24: 8

double f = 1.2345; int n; n=(int)(f*256);


Le di la respuesta al tipo que escribió la mejor respuesta, pero realmente usé un código de preguntas relacionadas que apunta aquí .

Utilizaba plantillas y era fácil eliminar las dependencias de la libración de impulso.


Aqui tienes:

// A signed fixed-point 16:16 class class FixedPoint_16_16 { short intPart; unsigned short fracPart; public: FixedPoint_16_16(double d) { *this = d; // calls operator= } FixedPoint_16_16& operator=(double d) { intPart = static_cast<short>(d); fracPart = static_cast<unsigned short> (numeric_limits<unsigned short> + 1.0)*d); return *this; } // Other operators can be defined here };

EDITAR: Aquí hay una clase más general basada en otra forma común de tratar con números de punto fijo (y que KPexEA señaló):

template <class BaseType, size_t FracDigits> class fixed_point { const static BaseType factor = 1 << FracDigits; BaseType data; public: fixed_point(double d) { *this = d; // calls operator= } fixed_point& operator=(double d) { data = static_cast<BaseType>(d*factor); return *this; } BaseType raw_data() const { return data; } // Other operators can be defined here }; fixed_point<int, 8> fp1; // Will be signed 24:8 (if int is 32-bits) fixed_point<unsigned int, 16> fp1; // Will be unsigned 16:16 (if int is 32-bits)