[C#.NET] 浮點數 轉 Hexadecimal
由於設備商所定義的通訊協定裡會用到浮點數,所以我就利用下列方式將浮點數轉成16進制的字串格式
用 BitConverter 轉成 16 進制的字串
public void FloatToHexStringTest()
{
var expected = "4200CCCD";
float source = 32.2f;
byte[] sourceArray = BitConverter.GetBytes(source);
var number = BitConverter.ToUInt32(sourceArray, 0);
string actual = number.ToString("X");
Assert.AreEqual(expected, actual);
}
字串反轉成浮點數
public void HexStringToFloatTest()
{
var expected = 32.2f;
string source = "4200CCCD";
var number = int.Parse(source, System.Globalization.NumberStyles.AllowHexSpecifier);
byte[] numberArray = BitConverter.GetBytes(number);
float actual = BitConverter.ToSingle(numberArray, 0);
Assert.AreEqual(expected, actual);
}
或是使用 DoubleToInt64Bits 來轉成16進制的字串
public void FloatToHexStringTest1()
{
var expected = "40401999A0000000";
float source = 32.2f;
long number = BitConverter.DoubleToInt64Bits(source);
var actual = number.ToString("X");
Assert.AreEqual(expected, actual);
}
用 Int64BitsToDouble 反轉回浮點數
public void HexStringToFloatTest1()
{
float expected = 32.2f;
string hex = "40401999A0000000";
long dec = Convert.ToInt64(hex, 16);
var actual = BitConverter.Int64BitsToDouble(dec);
Assert.AreEqual(expected, actual);
}
但是設備商給我的格式只有兩個 byte ,上列的方式至少要有4個 byte,於是經我詢問的結果,設備商的做法是整數擺一個byte, 小數擺一個byte(小數只取後兩位),所以我又將程式碼改成以下:
這段程式碼的原理很簡單,只是把小數跟整數拆開放在不同的byte,這個測試方法裡有用到無條件捨去小數點後兩位,如果不想那麼那麼麻煩, 也可以利用double.ToString(“F2”)來處理,不過這樣的做法會進位, 可參考:http://stackoverflow.com/questions/4916240/format-double-in-c-sharp
public void DoubleToHexStringTest1()
{
double source = 32.22677921;
//無條件捨去小數點後兩位
double pow = Math.Pow(10, 2);
double sign = source >= 0 ? 1 : -1;
source = sign * Math.Floor(sign * source * pow) / pow;
var inputString = source.ToString();
var index = inputString.IndexOf(".");
var hi = "";
var lo = "";
if (index > 0)
{
//有小數
var split = inputString.Split('.');
hi = (byte.Parse(split[0])).ToString("X").PadLeft(2, '0');
lo = (byte.Parse(split[1])).ToString("X").PadLeft(2, '0');
}
else //沒有小數
{
hi = (byte.Parse(inputString)).ToString("X").PadLeft(2, '0');
lo = 0.ToString("X").PadLeft(2, '0');
}
var expected = "2016";
var actual = hi + lo;
Assert.AreEqual(expected, actual);
}
字串反轉成浮點數
public void HexStringToDoubleTest1()
{
double expected = 32.22;
var source = "2016";
var sourceArray = Enumerable.Range(0, source.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(source.Substring(x, 2), 16))
.ToArray();
var temp = sourceArray[0] + "." + sourceArray[1];
var actual = double.Parse(temp);
Assert.AreEqual(expected, actual);
}
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET