tipos tipo puede implicitamente datos convertir conversion c# binary floating-point double

c# - tipo - ¿Cómo convierto una cadena binaria en flotante o doble?



convertir string a double c# (4)

En esta pregunta, Bill The Lizard pregunta cómo mostrar la representación binaria de un flotante o doble .

Lo que me gustaría saber es, dada una cadena binaria de la longitud adecuada, ¿cómo podría realizar la operación inversa (en C #)? En otras palabras, ¿cómo convierto una cadena binaria en flotante o doble?

Como nota al margen, ¿hay algunas cadenas de bits que no resulten en un float o double válido?

EDITAR: Por cadena binaria me refiero a una cadena de 0 y 1.

Por lo tanto, mi entrada será una cadena como esta:

01010101010101010101010101010101

y mi salida debería ser un número de punto flotante. (O, si había 64 bits en la cadena, un doble).


double d1 = 1234.5678; string ds = DoubleToBinaryString(d1); double d2 = BinaryStringToDouble(ds); float f1 = 654.321f; string fs = SingleToBinaryString(f1); float f2 = BinaryStringToSingle(fs); // ... public static string DoubleToBinaryString(double d) { return Convert.ToString(BitConverter.DoubleToInt64Bits(d), 2); } public static double BinaryStringToDouble(string s) { return BitConverter.Int64BitsToDouble(Convert.ToInt64(s, 2)); } public static string SingleToBinaryString(float f) { byte[] b = BitConverter.GetBytes(f); int i = BitConverter.ToInt32(b, 0); return Convert.ToString(i, 2); } public static float BinaryStringToSingle(string s) { int i = Convert.ToInt32(s, 2); byte[] b = BitConverter.GetBytes(i); return BitConverter.ToSingle(b, 0); }


string bstr = "01010101010101010101010101010101"; long v = 0; for (int i = bstr.Length - 1; i >= 0; i--) v = (v << 1) + (bstr[i] - ''0''); double d = BitConverter.ToDouble(BitConverter.GetBytes(v), 0); // d = 1.41466386031414E-314



Aquí hay una solución que no usa BitConverter y no está limitada por el rango de Int64 .

static double BinaryStringToDouble(string s) { if(string.IsNullOrEmpty(s)) throw new ArgumentNullException("s"); double sign = 1; int index = 1; if(s[0] == ''-'') sign = -1; else if(s[0] != ''+'') index = 0; double d = 0; for(int i = index; i < s.Length; i++) { char c = s[i]; d *= 2; if(c == ''1'') d += 1; else if(c != ''0'') throw new FormatException(); } return sign * d; }

Esta versión admite cadenas binarias que representan valores entre Double.MinValue y Double.MaxValue , o 1023 dígitos binarios significativos. Se desborda a Double.PositiveInfinity o Double.NegativeInfinity .

La respuesta de @LukeH solo admite cadenas binarias que representan valores entre Int64.MinValue e Int64.MaxValue , o 63 dígitos binarios significativos.

La cuestión de por qué necesita una cadena binaria de más de 63 dígitos es tema de debate.

Si no desea permitir un carácter de signo principal, puede utilizar esta versión más simple que solo devuelve valores positivos.

static double BinaryStringToDouble(string s) { if(string.IsNullOrEmpty(s)) throw new ArgumentNullException("s"); double d = 0; foreach(var c in s) { d *= 2; if(c == ''1'') d += 1; else if(c != ''0'') throw new FormatException(); } return d; }