[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