在做上位機開發過程中,經常會碰到字節數組與浮點數,整數等數據之間的轉換,有時為了驗證數據是否解析正確,得借助於IEEE浮點數工具,本文把基於c#實現的浮點數與字節數組(或16進制的字符串)轉換的實現方法分享如下:
/// <summary> /// 將二進制值轉ASCII格式十六進制字符串 /// </summary> /// <paramname="data">二進制值</param> /// <paramname="length">定長度的二進制</param> /// <returns>ASCII格式十六進制字符串</returns> public static string toHexString(int data, int length) { string result = ""; if (data > 0) result = Convert.ToString(data, 16).ToUpper(); if (result.Length < length) { // 位數不夠補0 StringBuilder msg = new StringBuilder(0); msg.Length = 0; msg.Append(result); for (; msg.Length < length; msg.Insert(0, "0")) ; result = msg.ToString(); } return result; } ///<summary> /// 將浮點數轉ASCII格式十六進制字符串(符合IEEE-754標准(32)) /// </summary> /// <paramname="data">浮點數值</param> /// <returns>十六進制字符串</returns> public static string FloatToIntString(float data) { byte[] intBuffer = BitConverter.GetBytes(data); StringBuilder stringBuffer = new StringBuilder(0); for (int i = 0; i < intBuffer.Length; i++) { stringBuffer.Insert(0, toHexString(intBuffer[i] & 0xff, 2)); } return stringBuffer.ToString(); } /// <summary> /// 將ASCII格式十六進制字符串轉浮點數(符合IEEE-754標准(32)) /// </summary> /// <param name="data">16進制字符串</param> /// <returns></returns> public static float StringToFloat(String data) { if (data.Length < 8 || data.Length > 8) { //throw new NotEnoughDataInBufferException(data.length(), 8); return 0; } else { byte[] intBuffer = new byte[4]; // 將16進制串按字節逆序化(一個字節2個ASCII碼) for (int i = 0; i < 4; i++) { intBuffer[i] = Convert.ToByte(data.Substring((3 - i) * 2, 2), 16); } return BitConverter.ToSingle(intBuffer, 0); } } /// <summary> /// 將byte數組轉為浮點數 /// </summary> /// <param name="bResponse">byte數組</param> /// <returns></returns> public static float ByteToFloat(byte[] bResponse) { if (bResponse.Length < 4 || bResponse.Length > 4) { //throw new NotEnoughDataInBufferException(data.length(), 8); return 0; } else { byte[] intBuffer = new byte[4]; //將byte數組的前后兩個字節的高低位換過來 intBuffer[0] = bResponse[1]; intBuffer[1] = bResponse[0]; intBuffer[2] = bResponse[3]; intBuffer[3] = bResponse[2]; return BitConverter.ToSingle(intBuffer, 0); } } /// <summary> /// 用指針方式強制將byte數組轉為浮點數 /// </summary> /// <param name="bResponse"></param> /// <returns></returns> public static float BytetoFloatByPoint(byte[] bResponse) { //uint nRest = ((uint)response[startByte]) * 256 + ((uint)response[startByte + 1]) + 65536 * ((uint)response[startByte + 2]) * 256 + ((uint)response[startByte + 3]); float fValue = 0f; uint nRest = ((uint)bResponse[0]) * 256 + ((uint)bResponse[1]) + 65536 * (((uint)bResponse[2]) * 256 + ((uint)bResponse[3])); //用指針將整形強制轉換成float unsafe { float* ptemp; ptemp = (float*)(&nRest); fValue = *ptemp; } return fValue; }
注意:有時從串口(或其它設備讀到的字節有高低位之分,在作為參數傳遞前把他們的順序調整過來即可)