前言
最近用modbus tcp与plc设备进行通信时,获取到的二进制数需要转成浮点数。modubus中浮点数是按照IEEE754标准存储的,主要是单精度和双精度浮点型,对应着java里面的float和double。
存储方式

无论是单精度还是双精度都是三部分组成:符号位、指数位、尾数位,两者只是精度不同所以尾数位的位数不一样,下面按照单精度来说明各部分。
符号位(sign):
符号位,表示该浮点类型的正负,0为正,1为负
指数位(exponent):
指数位,表示该浮点类型数据的大小容量,8位,容量高达256种不同形态,通过阶计算而来,计算方式为(规格数) 阶 + 偏移量 = 指数,阶码取值范围为[-127,128],单精度偏移量为127,双精度偏移量为1023,偏移是为了是指保持指数的存储始终为正数,指数位格子越多可存储的浮点类型数据就越大
尾数位(fraction):
尾数位,也叫有效数字,表示该浮点类型数据的精度,通过浮点数的二进制规范化而来,会将第一位的1隐藏起来,格子越多存储的浮点类型数据精度就越高
实现方式
public class IEE754Demo {
public static void main(String[] args) {
// 验证网址: https://www.binaryconvert.com/convert_float.html
// 32位二进制 转成 单精度浮点数
String binString32 = "111111000000000000000000000000";
System.out.println(Float.intBitsToFloat(Integer.parseUnsignedInt(binString32, 2)));
// 单精度浮点数 转成 32位二进制
float floatVal = 0.5f;
System.out.println(Integer.toBinaryString(Float.floatToIntBits(floatVal)));
// 64位二进制 转成 双精度浮点数
String binString64 = "11111111100000000000000000000000000000000000000000000000000000";
System.out.println(Double.longBitsToDouble(Long.parseUnsignedLong(binString64, 2)));
// 双精度浮点数 转成 64位二进制
double doubleVal = 0.5d;
System.out.println(Long.toBinaryString(Double.doubleToLongBits(doubleVal)));
}
}
