Kotlin秤应用数值格式化错误:预期123.456却显示51323.457
问题分析与解决
你的代码存在两个核心错误,导致结果不符合预期:
1. 整数部分解析错误
整数部分是uint8类型(仅占1个字节),但你使用了FORMAT_UINT16读取。FORMAT_UINT16会读取偏移0开始的两个字节作为16位无符号整数,这就把整数部分和小数部分的第一个字节错误拼接成了一个大整数。比如你预期的整数123(0x7B),加上小数部分456的低字节0xC8,在小端序下会被解析为0xC87B,也就是十进制的51323——这正好是你得到的错误结果的整数部分。
2. 小数部分解析逻辑错误
小数部分是uint16类型(占两个字节),你却错误地拆分读取偏移1和偏移2的FORMAT_UINT16(每个FORMAT_UINT16占两个字节,会导致读取范围重叠或越界),再通过or和位移运算组合,完全违背了uint16的读取逻辑。
修正后的代码
情况1:BLE数据为小端序(多数场景默认)
直接用对应格式读取对应偏移的数值:
val integerPart = characteristic.getIntValue(FORMAT_UINT8, 0).toFloat() val decimalPart = characteristic.getIntValue(FORMAT_UINT16, 1).toFloat() / 1000f val strValue = integerPart + decimalPart
情况2:BLE数据为大端序(若小数部分字节顺序相反)
手动组合两个字节的数值:
val integerPart = characteristic.getIntValue(FORMAT_UINT8, 0).toFloat() // 读取小数部分的高字节和低字节 val decimalHighByte = characteristic.getIntValue(FORMAT_UINT8, 1) val decimalLowByte = characteristic.getIntValue(FORMAT_UINT8, 2) val decimalPart = (decimalHighByte.shl(8) + decimalLowByte).toFloat() / 1000f val strValue = integerPart + decimalPart
运行修正后的代码就能得到预期的123.456结果。
内容的提问来源于stack exchange,提问作者NIXIE_123
相关产品推荐
相关产品推荐

