Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中将IEEE-11073 16位SFLOAT转换为简单浮点?_Java_Types_Floating Point - Fatal编程技术网

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

如何在Java中将IEEE-11073 16位SFLOAT转换为简单浮点?,java,types,floating-point,Java,Types,Floating Point,标题不言自明:如何在Java中将IEEE-11073 16位SFLOAT转换为简单浮点?您可以使用位移位。提取符号、指数和尾数,并将其移位,使其为浮点格式。您可能需要更正无穷大和NaN 正如@PretiP的回答所指出的,指数是以10为基数的,因此需要乘以或除以10的幂才能得到最终值。我找不到任何与IEEE 11073相关的浮点规范,您可能指的是a(有时也称为迷你浮点) Wikipedia对该格式进行了充分描述,可以轻松地将其转换为普通浮点。基本上,您将其分为3个字段(符号、指数、尾数)。 该标志

标题不言自明:如何在Java中将IEEE-11073 16位SFLOAT转换为简单浮点?

您可以使用位移位。提取符号、指数和尾数,并将其移位,使其为浮点格式。您可能需要更正无穷大和NaN


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

我找不到任何与IEEE 11073相关的浮点规范,您可能指的是a(有时也称为迷你浮点)

Wikipedia对该格式进行了充分描述,可以轻松地将其转换为普通浮点。基本上,您将其分为3个字段(符号、指数、尾数)。 该标志不需要转换,只需要移动到正确的位置。然后检查指数的最小值或最大值,处理特殊情况(Inf、NaN、低于正常值/非标准化)。否则,只需修正指数的偏差,然后移到正确的位置。 对于尾数,根据需要在右侧添加尽可能多的零。最后,将所有内容合并到一个int中,并使用Float.intBitsToFloat(bits)将这些位转换为普通的java浮点


从float转换的工作原理几乎相同,只是存在舍入、溢出和下溢的额外陷阱。

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]+无穷大[指数0,尾数+(2^11–2)→ 0x07FE]–无穷大[指数0,尾数–(2^11–2)→ 0x0802] 保留供将来使用[指数0,尾数–(2^11–1)→ 0x0801]


此11073库的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;
}
尝试搜索“Personal Health Devices Transcoding_WP_V11”,它将引导您找到Bluetooth特殊兴趣小组的文档。在2011年10月25日/V11r00版本的文档中,第2.2节“将蓝牙特性转换为11073属性”给出了如何处理11073-20601浮点(32位)和SFLOAT(16位)数字的详细说明和示例

此文档的当前URL为


请注意,这很可能是Petri p.在上面引用的同一个文档。

即使这篇文章有点旧,我也只想发布基于java文件的解决方案

public short getExponent(short value)
{
    if (value < 0)
    { // if exponent should be negative
        return (byte) (((value >> 12) & 0x0F) | 0xF0);
    }
    return (short) ((value >> 12) & 0x0F);
}

public short getMantissa(short value)
{
    if ((value & 0x0800) != 0)
    { // if mantissa should be negative
        return (short) ((value & 0x0FFF) | 0xF000);
    }
    return (short) (value & 0x0FFF);
}

public double parseSFLOATtoDouble(short value)
{
    // NaN
    if (value == 0x07FF)
    {
        return Double.NaN;
    }
    // NRes (not at this resolution)
    else if (value == 0x0800)
    {
        return Double.NaN;
    }
    // +INF
    else if (value == 0x07FE)
    {
        return Double.POSITIVE_INFINITY;
    }
    // -INF
    else if (value == 0x0802)
    {
        return Double.NEGATIVE_INFINITY;
    }
    // Reserved
    else if (value == 0x0801)
    {
        return Double.NaN;
    }
    else
    {
        return ((double) getMantissa(value)) * Math.pow(10, getExponent(value));
    }
}
public short getExponent(短值)
{
如果(值<0)
{//如果指数应该为负
返回(字节)((值>>12)和0x0F)| 0xF0);
}
返回(短)((值>>12)和0x0F);
}
公共短尾数(短值)
{
如果((值&0x0800)!=0)
{//如果尾数应该是负数
返回(短)((值&0x0FFF)| 0xF000);
}
返回(短)(值和0x0FFF);
}
公共双解析FloatToDouble(短值)
{
//楠
如果(值==0x07FF)
{
返回Double.NaN;
}
//NRE(不适用于本决议)
else if(值==0x0800)
{
返回Double.NaN;
}
//+INF
否则如果(值==0x07FE)
{
返回双正无穷大;
}
//-INF
else if(值==0x0802)
{
返回双负无穷大;
}
//含蓄的
else if(值==0x0801)
{
返回Double.NaN;
}
其他的
{
return((double)get尾数(value))*Math.pow(10,getExponent(value));
}
}

对于那些希望在使用Javascript时转换SFLOAT的人,这里有一个简洁的库,可以实现这一点,还有更多。

如果您想添加自己的特性,只需使用addMeta函数,
defs/charMeta.js有很多例子

你能提供这种格式的引文吗?我很难找到一个规范。对于仍在寻找此规范的任何人来说,它被称为“个人健康设备代码转换白皮书”,可以从Bluetooth SIG以PDF格式提供。这一特定类型在第9页。这是其中的大部分,假定无穷大和NaN转换得到正确处理(包括NaN的信令位)。但是,您还必须处理非规范化。当偏置指数为0时,有效位字段的解释不同:隐式位为0,而不是1。必须对其进行调整,因为32位浮点中调整后的指数将不为零,因此隐式位将为1。一种调整是从32位浮点中减去隐式位(0x1p-126)的值(如果是正的,则加上负的)。很好的一点,编辑它以提及非规范化数字。SNaN不应该引起麻烦,因为java禁止信令。根据,SFLOAT格式使用十进制,而这不是半精度浮点,因此仅仅调整二进制指数是行不通的。你有例子吗?比如说69,哪个是符号、指数和尾数?非常感谢@符号为正,指数为6表示2^6,manitssa为1.000101,每个引号中,指数为基数10。仅将其转换为Java的基本两位数格式无法工作。这是新的url:。谢谢你的邀请
public short getExponent(short value)
{
    if (value < 0)
    { // if exponent should be negative
        return (byte) (((value >> 12) & 0x0F) | 0xF0);
    }
    return (short) ((value >> 12) & 0x0F);
}

public short getMantissa(short value)
{
    if ((value & 0x0800) != 0)
    { // if mantissa should be negative
        return (short) ((value & 0x0FFF) | 0xF000);
    }
    return (short) (value & 0x0FFF);
}

public double parseSFLOATtoDouble(short value)
{
    // NaN
    if (value == 0x07FF)
    {
        return Double.NaN;
    }
    // NRes (not at this resolution)
    else if (value == 0x0800)
    {
        return Double.NaN;
    }
    // +INF
    else if (value == 0x07FE)
    {
        return Double.POSITIVE_INFINITY;
    }
    // -INF
    else if (value == 0x0802)
    {
        return Double.NEGATIVE_INFINITY;
    }
    // Reserved
    else if (value == 0x0801)
    {
        return Double.NaN;
    }
    else
    {
        return ((double) getMantissa(value)) * Math.pow(10, getExponent(value));
    }
}