C# 浮点到二进制字符串,反之亦然
C# floating point to binary string and vice versa
我正在将浮点值转换为二进制字符串表示形式:
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
}
现在我想将这个二进制字符串转换为浮点值。
我尝试了以下但它 returns 值“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”
为什么我得到了错误的值?我错过了什么吗?
你让这件事变得比需要的更难;错误似乎主要是在字符解析代码中,但是你不需要做所有这些。
您可以这样尝试:
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 特定的 - 它取决于字节顺序。
我正在将浮点值转换为二进制字符串表示形式:
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
}
现在我想将这个二进制字符串转换为浮点值。
我尝试了以下但它 returns 值“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”
为什么我得到了错误的值?我错过了什么吗?
你让这件事变得比需要的更难;错误似乎主要是在字符解析代码中,但是你不需要做所有这些。
您可以这样尝试:
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 特定的 - 它取决于字节顺序。