C# 通过 IEEE 754 从浮点数转换为十六进制字符串,然后再转换回浮点数
本文关键字:浮点数 转换 字符串 然后 十六进制 通过 IEEE | 更新日期: 2023-09-27 18:35:02
我需要将float
值转换为十六进制字符串并再次转换回来。在线IEEE 754转换器允许我这样做。这是我实现转换的尝试:
unsafe static void Main(string[] args)
{
float f = 0.0023984962F;
long l = *((long*)&f);
float r = *((float*)&l);
Console.WriteLine("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r);
Console.ReadLine();
}
我的问题:
使用浮点
0.0023984962
预期结果是0x3B1D3017
但我的代码打印0x22CB20C3B1D3017
.我做错了什么?如何将输出保存在变量中?
为了能够两种方式进行转换,您需要两个函数。您的代码中有一个错误,您将 32 位浮点数 ( float
( 转换为 64 位整数 (long
(。由于您的代码unsafe
因此编译器不会捕获此错误。
但是,使用unsafe
代码执行得很好,因此以下是有效的代码:
unsafe string ToHexString(float f) {
var i = *((int*) &f);
return "0x" + i.ToString("X8");
}
unsafe float FromHexString(string s) {
var i = Convert.ToInt32(s, 16);
return *((float*) &i);
}
为了避免unsafe
代码的问题,您还可以使用BitConverter
来检查中间字节缓冲区的大小。
string ToHexString(float f) {
var bytes = BitConverter.GetBytes(f);
var i = BitConverter.ToInt32(bytes, 0);
return "0x" + i.ToString("X8");
}
float FromHexString(string s) {
var i = Convert.ToInt32(s, 16);
var bytes = BitConverter.GetBytes(i);
return BitConverter.ToSingle(bytes, 0);
}
您现在可以双向转换:
var hexString = ToHexString(0.0023984962F);
var f = FromHexString(hexString);
转换
float
时,您应该使用 int
而不是long
,因为 float
(又名 Single
(是 32 位值(不像 double
是 64 位(:
unsafe static void Main(string[] args)
{
float f = 0.0023984962F;
int l = *((int*)&f); // int here: 32-bit float into 32-bit integer
float r = *((float*)&l);
// Let's save the result in the variable
String result = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r);
Console.WriteLine(result);
Console.ReadLine();
}
但是,更好的方法是使用专门为该角色设计的BitConverter
,并避免不安全的例程:
static void Main(string[] args) {
float f = 0.0023984962F;
uint l = BitConverter.ToUInt32(BitConverter.GetBytes(f), 0);
float r = BitConverter.ToSingle(BitConverter.GetBytes(l), 0);
// Let's save the result in the variable
String result = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r);
Console.WriteLine(result);
Console.ReadLine();
}
要回答第二个问题,您可以使用字符串变量来存储输出,例如:
String output = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r);