【问题标题】:C# floating point to binary string and vice versaC#浮点到二进制字符串,反之亦然
【发布时间】:2021-04-27 02:34:19
【问题描述】:

我正在将浮点值转换为二进制字符串表示:

float resulta = 31.0 / 15.0;    //2.0666666
var rawbitsa = ToBinaryString(resulta); //returns 01000000000001000100010001000100

其中 ToBinaryString 编码为:

static string ToBinaryString(float value)
{

        int bitCount = sizeof(float) * 8; // never rely on your knowledge of the size
        // better not use string, to avoid ineffective string concatenation repeated in a loop
        char[] result = new char[bitCount]; 

        // now, most important thing: (int)value would be "semantic" cast of the same
        // mathematical value (with possible rounding), something we don't want; so:
        int intValue = System.BitConverter.ToInt32(BitConverter.GetBytes(value), 0);

        for (int bit = 0; bit < bitCount; ++bit)
        {
            int maskedValue = intValue & (1 << bit); // this is how shift and mask is done.
            if (maskedValue > 0)
                maskedValue = 1;
            // at this point, masked value is either int 0 or 1
            result[bitCount - bit - 1] = maskedValue.ToString()[0];
        }

        return new string(result); // string from character array
}

现在我想将此二进制字符串转换为浮点值。

我尝试了以下方法,但它返回值“2.8293250329111622E-315”

string bstra = "01000000000001000100010001000100";
long w = 0;
for (int i = bstra.Length - 1; i >= 0; i--) w = (w << 1) + (bstra[i] - '0');
double da = BitConverter.ToDouble(BitConverter.GetBytes(w), 0); //returns 2.8293250329111622E-315

通过传入值“01000000000001000100010001000100”,我想要值“2.0666666”

为什么我得到一个错误的值?我错过了什么吗?

【问题讨论】:

  • 这能回答你的问题吗? Is floating point math broken?
  • 你可以看看这个thread
  • @SᴇM 这不是数学。这有效地序列化和反序列化值。
  • 在使用 long/double 而不是 int/float 的反转代码中有很多混淆 - 这真的很重要,但是:实际的位处理代码没有'不工作;您应该能够将 w 重新生成为与 intValue 最初的值相同的值。在 that 起作用之前,没有其他东西会起作用。检查您是否正在向后阅读这些位。
  • 如果您正在获取其他人的代码并在您的示例中使用该代码,请提供链接codeproject.com/Questions/484209/…

标签: c# floating-point data-conversion


【解决方案1】:

你让这件事变得比需要的困难得多;错误似乎大部分在字符解析代码中,但您不需要做所有这些

你可以这样尝试:

static string ToBinaryString(float value)
{
    const int bitCount = sizeof(float) * 8;
    int intValue = System.BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
    return Convert.ToString(intValue, 2).PadLeft(bitCount, '0');
}

static float FromBinaryString(string bstra)
{
    int intValue = Convert.ToInt32(bstra, 2);
    return BitConverter.ToSingle(BitConverter.GetBytes(intValue), 0);
}

例子:

float resulta = 31.0F / 15.0F; //2.0666666
var rawbitsa = ToBinaryString(resulta);
Console.WriteLine(rawbitsa); //01000000000001000100010001000100
var back = FromBinaryString(rawbitsa);
Console.WriteLine(back); //2.0666666

注意GetBytes 的使用效率有点低;如果你对unsafe 代码没问题,你可以删除所有这些。

另请注意,此代码是特定于 CPU 的 - 它取决于字节序。

【讨论】:

  • “但是你不需要写这个”?我觉得很混乱。
  • @CodingYoshi OP 正在编写大量代码来将整数转换为该值的二进制字符串,反之亦然。有内置的实用方法可以做到这一点,这使得代码 a: 更简单,b: 正确
  • 谢谢马克。我们如何处理双重价值?即静态字符串 ToBinaryString(double value) 和 static double FromBinaryString(string bstra)
  • 它应该大致相同,但int 变成longInt32 变成Int64Single 变成Doublefloat 变成double
猜你喜欢
  • 2011-07-29
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2011-05-18
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多