Sha*_*yLV 6 java floating-point types
标题不言自明:如何将IEEE-11073 16位SFLOAT转换为Java中的简单浮点数?
小智 7
IEEE-11073不属于公共领域,但您可以在蓝牙个人健康档案中找到足够的信息.谷歌完整规格#11073-2060.以下是来自蓝牙个人健康转码纸的复制粘贴:
以下信息在ISO/IEEE标准中定义.11073-2060™1-2008 [1].SFLOAT类型数据类型定义为表示类型中不是整数的数值.SFLOAT类型定义为具有12位尾数和4位指数的16位值.有关SFLOAT类型的详尽定义,请参见[1]的附录F.8.该数据类型定义如下:指数尾数大小4位12位
16位浮点型; 整数类型只是一个占位符
SFLOAT-Type :: = INT-U16 16位值包含一个4位指数到10位,后跟12位尾数.每个都是二进制形式.分配特殊值来表示以下内容:NaN [指数0,尾数+(2 ^ 11 -1)→0x07FF] NRes [指数0,尾数 - (2 ^ 11)→0x0800] + INFINITY [指数0,尾数+( 2 ^ 11 -2)→0x07FE] - INFINITY [指数0,尾数 - (2 ^ 11 -2)→0x0802]保留供将来使用[指数0,尾数 - (2 ^ 11 -1)→0x0801]
这个11073库有C代码可以做到:
https://github.com/signove/antidote/blob/master/src/util/bytelib.c
应该不难转换为Java.
double read_sfloat(ByteStreamReader *stream, int *error)
{
intu16 int_data = read_intu16(stream, error);
if (*error)
return 0;
intu16 mantissa = int_data & 0x0FFF;
int8 expoent = int_data >> 12;
if (expoent >= 0x0008) {
expoent = -((0x000F + 1) - expoent);
}
float output = 0;
if (mantissa >= FIRST_S_RESERVED_VALUE && mantissa
<= MDER_S_NEGATIVE_INFINITY) {
output = reserved_float_values[mantissa
- FIRST_S_RESERVED_VALUE];
} else {
if (mantissa >= 0x0800) {
mantissa = -((0x0FFF + 1) - mantissa);
}
double magnitude = pow(10.0f, expoent);
output = (mantissa * magnitude);
}
return output;
}
Run Code Online (Sandbox Code Playgroud)
样板代码:
typedef enum {
MDER_S_POSITIVE_INFINITY = 0x07FE,
MDER_S_NaN = 0x07FF,
MDER_S_NRes = 0x0800,
MDER_S_RESERVED_VALUE = 0x0801,
MDER_S_NEGATIVE_INFINITY = 0x0802
} ReservedSFloatValues;
static const intu32 FIRST_S_RESERVED_VALUE = MDER_S_POSITIVE_INFINITY;
intu16 read_intu16(ByteStreamReader *stream, int *error)
{
intu16 ret = 0;
if (stream && stream->unread_bytes > 1) {
ret = ntohs(*((uint16_t *) stream->buffer_cur));
stream->buffer_cur += 2;
stream->unread_bytes -= 2;
} else {
if (error) {
*error = 1;
}
ERROR("read_intu16");
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用位移位。提取符号、指数和尾数并对它们进行移位,使它们成为浮点格式。您可能需要纠正 Infinity 和 NaN。
正如 @PretiP 的回答指出的,指数以 10 为底,因此您需要乘以或除以 10 的幂才能得到最终值。