在工作需要时,需要此功能,网上查了半天,基本都是正数浮点数可以的,但负数浮点数就报错了,通过查询资料和修改部分函数,完成完全转化功能,经测试OK
编写了一个三个函数来实现此功能。
转化思路:16进制的字符串>>>转化二进制的字符串>>>由二进制转化成带符号的浮点数(32位和64位都可通用).,分享给需要的朋友!
/** * 16进制字符串转化二进制字符中 * * @param hexString * @return */ public static String HexString2binaryString(String hexString) { if (hexString == null || hexString.length() % 2 != 0) return null; String bString = "", tmp; for (int i = 0; i < hexString.length(); i++) { tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16)); bString += tmp.substring(tmp.length() - 4); } return bString; }
/** * 这里只处理规格化数,非规格化数,NaN,finite等没有考虑 * 2进制字符串转Float数,包括(正数和负数) * @param binaryString * @return */ static float BinaryStringToFloat(final String binaryString) { // float是32位,将这个binaryString左边补0补足32位,如果是Double补足64位。 final String stringValue = LeftPad(binaryString, '0', 32); // 首位是符号部分,占1位。 // 如果符号位是0则代表正数,1代表负数 final int sign = stringValue.charAt(0) == '0' ? 1 : -1; // 第2到9位是指数部分,float占8位,double占11位。 final String exponentStr = stringValue.substring(1, 9); // 将这个二进制字符串转成整数,由于指数部分加了偏移量(float偏移量是127,double是1023) // 所以实际值要减去127 final int exponent = Integer.parseInt(exponentStr, 2) - 127; // 最后的23位是尾数部分,由于规格化数,小数点左边隐含一个1,现在加上 final String mantissaStr = "1".concat(stringValue.substring(9, 32)); // 这里用double,尽量保持精度,最好用BigDecimal,这里只是方便计算所以用double double mantissa = 0.0; for (int i = 0; i < mantissaStr.length(); i++) { final int intValue = Character.getNumericValue(mantissaStr.charAt(i)); // 计算小数部分,具体请查阅二进制小数转10进制数相关资料 mantissa += (intValue * Math.pow(2, -i)); } // 根据IEEE 754 标准计算:符号位 * 2的指数次方 * 尾数部分 return (float) (sign * Math.pow(2, exponent) * mantissa); }
</pre><pre code_snippet_id="1670380" snippet_file_name="blog_20160503_2_6769868" name="code" class="html"><pre name="code" class="html"> /** * // 一个简单的补齐方法,很简单,没考虑很周到。具体请参考common-long.jar/StringUtils.leftPad() * @param str * @param padChar * @param length * @return */ static String LeftPad(final String str, final char padChar, int length) { final int repeat = length - str.length(); if (repeat <= 0) { return str; } final char[] buf = new char[repeat]; for (int i = 0; i < buf.length; i++) { buf[i] = padChar; } return new String(buf).concat(str); }
正数和负数可测试成功!请放心使用(调用的方法)
<span style="background-color: rgb(240, 240, 240);"> </span><span style="background-color: rgb(240, 240, 240);">String sBinaryString = HexString2binaryString("BF9DF3B6");</span>
System.out.println("BF9DF3B6>" + sBinaryString); Float ff = BinaryStringToFloat(sBinaryString); System.out.println("BF9DF3B6>" + ff.toString(ff)); System.out.println("BF9DF3B6>" + ff.toString()); String sBinaryString2 = HexString2binaryString("3F9DF3B6"); System.out.println("3F9DF3B6>" + sBinaryString2); Float ff2 = BinaryStringToFloat(sBinaryString2); System.out.println("3F9DF3B6>" + ff2.toString(ff2)); System.out.println("3F9DF3B6>" + ff2.toString());
执行显示的结果
05-04 15:22:35.370: I/System.out(13329): 3f9d70a4 05-04 15:22:35.370: I/System.out(13329): 1.2299999 05-04 15:22:35.370: I/System.out(13329): K1311P99 05-04 15:22:35.370: I/System.out(13329): BF9DF3B6>10111111100111011111001110110110 05-04 15:22:35.370: I/System.out(13329): BF9DF3B6>-1.234 05-04 15:22:35.370: I/System.out(13329): BF9DF3B6>-1.234 05-04 15:22:35.370: I/System.out(13329): 3F9DF3B6>00111111100111011111001110110110 05-04 15:22:35.370: I/System.out(13329): 3F9DF3B6>1.234 05-04 15:22:35.370: I/System.out(13329): 3F9DF3B6>1.234