如何将IEEE-11073 16位SFLOAT转换为Java中的简单浮点数?

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]


epx*_*epx 6

这个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)


Pet*_*rey 2

您可以使用位移位。提取符号、指数和尾数并对它们进行移位,使它们成为浮点格式。您可能需要纠正 Infinity 和 NaN。

正如 @PretiP 的回答指出的,指数以 10 为底,因此您需要乘以或除以 10 的幂才能得到最终值。