valor siguiente separadores punto precisión literal flotante ejemplos doble cuál calculadora binario c++ binary floating-point ieee-754

siguiente - Punto flotante a valor binario(C++)



separadores en c++ (11)

Quiero tomar un número de punto flotante en C ++, como 2.25125, y una matriz int llena con el valor binario que se utiliza para almacenar el flotante en la memoria (IEEE 754).

Así que podría tomar un número, y terminar con una matriz int num [16] con el valor binario de la flotación: num [0] sería 1 num [1] sería 1 num [2] sería 0 num [3 ] sería 1 y así sucesivamente ...

Poner un int en una matriz no es difícil, solo el proceso de obtener el valor binario de una flotación es donde estoy atascado. ¿Puedes leer el binario en la memoria de la variable flotante? Si no, ¿cómo podría hacer esto en C ++?

EDITAR: La razón para hacer la comparación de esta manera es que estoy queriendo aprender a hacer operaciones bit a bit en C ++.


Crea una unión de float yy unsigned long. establezca el valor del miembro flotante e itere sobre los bits del valor largo sin signo como ya se describió en otras respuestas.

Esto eliminará a los operadores de elenco.


Puede usar un carácter sin signo para leer el byte flotante por byte en la matriz de enteros:

unsigned int bits[sizeof (float) * CHAR_BIT]; unsigned char const *c = static_cast<unsigned char const*>( static_cast<void const*>(&my_float) ); for(size_t i = 0; i < sizeof(float) * CHAR_BIT; i++) { int bitnr = i % CHAR_BIT; bits[i] = (*c >> bitnr) & 1; if(bitnr == CHAR_BIT-1) c++; } // the bits are now stored in "bits". one bit in one integer.

Por cierto, si solo quieres comparar los bits (al comentar en otra respuesta) utiliza memcmp :

memcmp(&float1, &float2, sizeof (float));


Si necesita una representación en coma flotante particular, tendrá que construirla semánticamente desde el flotador en sí, no copiando bits.

estándar c0x: http://c0x.coding-guidelines.com/5.2.4.2.2.html no define el formato de los números de coma flotante.


Transmite el puntero int a un puntero flotante, y listo.

(Aunque no lo declararía como una matriz int. Usaría void * para dejar en claro que la memoria se está utilizando como vertedero para otros valores).

Por cierto, ¿por qué no utilizas una serie de carrozas?


Use union y bitset:

#include <iostream> #include <bitset> int main() { union { float input; // assumes sizeof(float) == sizeof(int) int output; } data; data.input = 2.25125; std::bitset<sizeof(float) * CHAR_BIT> bits(data.output); std::cout << bits << std::endl; // or std::cout << "BIT 4: " << bits[4] << std::endl; std::cout << "BIT 7: " << bits[7] << std::endl; }

Puede que no sea una matriz, pero puede acceder a los bits con el operador [] como si estuviera usando una matriz.

Salida

$ ./bits 01000000000100000001010001111011 BIT 4: 1 BIT 7: 0


int fl = *(int*)&floatVar; //assuming sizeof(int) = sizeof(float) int binaryRepresentation[sizeof(float) * 8]; for (int i = 0; i < sizeof(float) * 8; ++i) binaryRepresentation[i] = ((1 << i) & fl) != 0 ? 1 : 0;

Explicación

(1 << i) desplaza el valor 1 , i bits hacia la izquierda. El operador & calcula el bit a bit y los operandos.

El bucle for ejecuta una vez para cada uno de los 32 bits en el flotante. Cada vez, seré el número del bit del que desee extraer el valor. Calculamos el bit a bit y el número y 1 << i :

Suponga que el número es: 1001011 e i = 2

1<<i voy a ser igual a 0000100

10001011 & 00000100 ========== 00000000

si i = 3 entonces:

10001011 & 00001000 ========== 00001000

Básicamente, el resultado será un número con un bit i establecido en el i ésimo bit del número original y todos los demás bits son cero. El resultado será cero, lo que significa que el i ésimo bit en el número original fue cero o distinto de cero, lo que significa que el número real tuvo el i ésimo bit igual a 1 .


La manera más fácil:

float myfloat; file.read((char*)(&myfloat),sizeof(float));


Bueno, no creo que C ++ tenga una forma segura de almacenar carrozas sin algún tipo de problema. Cuando se trata de moverse entre máquinas, es eficiente y se almacena fácilmente sin utilizar una gran capacidad de almacenamiento.

Es muy preciso, pero no admite valores realmente insanos. Podrá tener hasta 7 dígitos en cualquier ubicación, pero no puede exceder los 7 dígitos en cada lado. Para la izquierda, recibirás resultados inexactos. A la derecha obtendrás un error durante el tiempo de lectura. Para resolver el error, puede lanzar un error durante la escritura o realizar "buffer [idx ++] & 0x7" en la lectura para evitar que salga fuera de los límites 0 y 7. Tenga en cuenta que "& 0x7" solo funciona porque es una potencia de 2 menos uno. Que es 2 ^ 3 - 1. Solo puede hacer eso con esos valores Ej. 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, etc ...

Depende de ti si quieres usar esto o no. Sentí que era una forma segura de obtener la mayoría de los valores que siempre necesitarás. El siguiente ejemplo muestra cómo se convierte en una matriz de 4 bytes, pero para C ++ esto sería un char *. Si no desea realizar una división, puede convertir la matriz POWERS_OF_TEN en una matriz secundaria con decimales y múltiples en su lugar.

const float CacheReader::POWERS_OF_TEN[] = { 1.0F, 10.0F, 100.0F, 1000.0F, 10000.0F, 100000.0F, 1000000.0F, 10000000.0F }; float CacheReader::readFloat(void) { int flags = readUnsignedByte(); int value = readUnsignedTriByte(); if (flags & 0x1) value = -value; return value / POWERS_OF_TEN[(flags >> 1) & 0x7]; } unsigned __int32 CacheReader::readUnsignedTriByte(void) { return (readUnsignedByte() << 16) | (readUnsignedByte() << 8) | (readUnsignedByte()); } unsigned __int8 CacheReader::readUnsignedByte(void) { return buffer[reader_position] & 0xFF; } void CacheReader::writeFloat(float data) { int exponent = -1; float ceiling = 0.0F; for ( ; ++exponent < 8; ) { ceiling = (POWERS_OF_TEN[exponent] * data); if (ceiling == (int)ceiling) break; } exponent = exponent << 0x1; int ceil = (int)ceiling; if (ceil < 0) { exponent |= 0x1; ceil = -ceil; } buffer[writer_position++] = (signed __int16)(exponent); buffer[writer_position++] = (signed __int16)(ceil >> 16); buffer[writer_position++] = (signed __int16)(ceil >> 8); buffer[writer_position++] = (signed __int16)(ceil); }


otro enfoque, usando stl

#include <iostream> #include <bitset> using namespace std; int main() { float f=4.5f; cout<<bitset<sizeof f*8>(*(long unsigned int*)(&f))<<endl; return 0; }


Mirando los comentarios en esta respuesta ( Punto flotante a Valor binario (C ++) ) la razón para hacer esto es realizar una comparación bit a bit de dos valores.

#include <iostream> int main() { union Flip { float input; // assumes sizeof(float) == sizeof(int) int output; }; Flip data1; Flip data2; Flip data3; data1.input = 2.25125; data2.input = 2.25126; data3.input = 2.25125; bool test12 = data1.output ^ data2.output; bool test13 = data1.output ^ data3.output; bool test23 = data2.output ^ data3.output; std::cout << "T1(" << test12 << ") T2(" << test13 << ") T3(" << test23 << ")/n"; }


¿Puedes leer el binario en la memoria de la variable flotante?

Sí. Static le lanza un puntero a un puntero int y lee los bits del resultado. Un tipo de float IEEE 754 en C ++ es de 32 bits.