Estoy reemplazando un código C++ que escribe un archivo binario con C# (net6.0), y noto una discrepancia entre los valores escritos en el archivo.
Si tengo un valor de doble precisión igual a 0.0, C++ escribe los bytes como:
00 00 00 00 00 00 00 00
Sin embargo, C# (usando BinaryWriter) está escribiendo el mismo valor que:
00 00 00 00 00 00 00 80
Si convierto 0.0 a bytes usando System.BitConverter.GetBytes(), obtengo todos los 0x00. Si convierto los bytes con 0x80 en un doble usando BitConverter, todavía me da 0.0.
byte[] zero = System.BitConverter.GetBytes(0.0); // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 bool equal = 0.0 == System.BitConverter.ToDouble(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}); // trueEsto no parece que vaya a causar ningún problema, pero me gustaría entender qué está pasando.
Como se menciona en los comentarios, ese byte final 0x80 es en realidad el byte alto del valor double . Entonces, el MSB que se establece es el bit de signo . Esto significa que el número que se almacena es en realidad -0.0 (que, en prácticamente todos los casos, se compara con 0.0 , por lo que no debería causar ningún problema).
De hecho, hay otros bits (en el exponente ) que pueden apostar a 1 pero aún así dejar el valor del double representado como (+/-) cero.
¿Cómo obtuvimos -0.0 ? No puedo decir sin ver el código que genera el valor pero, desde la misma página Wiki:
Se puede obtener un cero negativo como resultado de ciertos cálculos, por ejemplo, como resultado de un subdesbordamiento aritmético en un número negativo (también pueden ser posibles otros resultados), o −1,0 × 0,0, o simplemente como −0,0.