タイトルはそれ自体を物語っています: Java で IEEE-11073 16 ビット SFLOAT を単純な浮動小数点数に変換する方法は?
7 に答える
IEEE-11073 はパブリック ドメインではありませんが、Bluetooth 個人の健康プロファイルで十分な情報を見つけることができます。完全な仕様番号 11073-2060 で Google を検索してください。以下は、Bluetooth 個人の健康に関するトランスコーディング ペーパーからのコピー ペーストです。
次の情報は、ISO/IEEE Std. 11073-2060™1-2008 [1]。SFLOAT-Type データ型は、整数型ではない数値を表すために定義されています。SFLOAT-Type は、仮数が 12 ビット、指数が 4 ビットの 16 ビット値として定義されます。SFLOAT-Type の完全な定義については、[1] の Annex F.8 を参照してください。このデータ型は次のように定義されます。 指数 仮数 サイズ 4 ビット 12 ビット
16 ビット浮動小数点型。整数型はプレースホルダーのみです
SFLOAT-Type ::= INT-U16 16 ビット値には、10 を底とする 4 ビットの指数と、それに続く 12 ビットの仮数が含まれます。それぞれが 2 の補数形式です。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]
ビットシフトを使用できます。符号、指数、仮数を抽出し、これらをシフトして float 形式にします。Infinity と NaN を補正する必要がある場合があります。
@PretiPの回答が指摘しているように、指数は基数10であるため、最終値を取得するには10の累乗で乗算または除算する必要があります。
「Personal Health Devices Transcoding_WP_V11」を検索してみると、Bluetooth Special Interest Group からのドキュメントが表示されます。ドキュメントの 2011 年 10 月 25 日 / V11r00 バージョンでは、セクション 2.2「BLUETOOTH CHARACTERISTICS を 11073 ATTRIBUTES に変換する」で、11073-20601 FLOAT (32 ビット) および SFLOAT (16 ビット) 番号を処理する方法の詳細な説明と例が示されています。
このドキュメントの現在の URL は https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961です。
これは、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));
}
}
IEEE 11073 に関連する float 仕様が見つかりません。おそらく、Half precision float (Minifloat とも呼ばれます) を意味します。
このフォーマットはウィキペディアで十分に説明されており、通常のフロートに簡単に変換できます。基本的に、3 つのフィールド (符号、指数、仮数) に分割します。符号を変換する必要はありません。正しい位置にシフトするだけで済みます。次に、指数の MIN または MAX 値をチェックし、特殊なケース (Inf、NaN、サブノーマル/非正規化) を処理します。それ以外の場合は、指数のバイアスを修正し、正しい位置にシフトします。仮数については、必要なだけ右側にゼロを追加します。最後にすべてを int にまとめ、Float.intBitsToFloat(bits) を使用してビットを通常の Java float に変換します。
float からの変換はほぼ同じように機能しますが、丸め、オーバーフロー、およびアンダーフローの追加の落とし穴があるだけです。