Как превратить двоичную строку в число с плавающей запятой или двойную? - PullRequest
3 голосов
/ 25 ноября 2011

В этом вопросе Bill The Lizard спрашивает , как отобразить двоичное представление числа с плавающей запятой или двойное .

Что я хотел бы знать, учитывая, что в двоичной строке соответствующей длины, как я могу выполнить обратную операцию (в C #)? Другими словами, как мне превратить двоичную строку в число с плавающей запятой или двойную?

В качестве примечания, есть ли битовые строки, которые не приводят к действительному плавающему или двойному числу?


РЕДАКТИРОВАТЬ: Под двоичной строкой я подразумеваю строку 0 и 1 с.

Итак, мой ввод будет такой строкой:

01010101010101010101010101010101

и мой вывод должен быть числом с плавающей запятой. (Или, если в строке было 64 бита, двойной.)

Ответы [ 4 ]

6 голосов
/ 25 ноября 2011
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);
}
2 голосов
/ 25 ноября 2011
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
1 голос
/ 25 ноября 2011
0 голосов
/ 04 октября 2014

Вот решение, которое не использует BitConverter и не ограничено диапазоном 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;
}

Эта версия поддерживает двоичные строки, которые представляют значения от Double.MinValue до Double.MaxValue или 1023 значащих двоичных цифр. Он переполняется до Double.PositiveInfinity или Double.NegativeInfinity .

@ LukeH ответ поддерживает только двоичные строки, представляющие значения от Int64.MinValue до Int64.MaxValue или 63 значащих двоичных цифр.

Почему вам нужна бинарная строка длиной более 63 цифр, обсуждается.

Если вы не хотите разрешить символ начального знака, вы можете использовать эту более простую версию, которая возвращает только положительные значения.

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;
}
...