2

Python のfloatデータ型は実際には倍精度(64 ビット) を使用します。ただし、私の特定の実装 ( OSCを介して型タグ付きの値を送信する) では、(32 ビット) 単精度浮動小数点数と (64 ビット) 倍精度浮動小数点数として表現できる値を区別したいと考えています。

より正確には、次のようなことをしたいと思います。

 if isdouble(value):
    binary=struct.pack('>d', value)
 else:
    binary=struct.pack('>f', value)

これを達成するための実行可能な方法はありますか?

4

4 に答える 4

4

少しの精度の損失を気にしない場合は、範囲をテストできます(Alfe's answerを参照):

def isdouble(value):
    return not (1.18e-38 <= abs(value) <= 3.4e38)

または反転して単精度をテストします。

def issingle(value):
    return 1.18e-38 <= abs(value) <= 3.4e38:

これらは例外の発生を防ぎOverflowErrorますが、別の方法はそれをキャッチすることです。

float('-0')float('+0')float('inf')float('-inf')およびfloat('nan')は、これらのテストで double としてテストされることに注意してください。これらを 8 バイトではなく 4 バイトで格納する場合は、明示的にテストしてください。

于 2013-11-14T13:21:10.087 に答える
1

float を使用して試してみることを提案します。それが失敗した場合 (範囲オーバーフローが原因で)、 double バージョンを使用します。

try:
  binary = struct.pack('>f', value)
except OverflowError:
  binary = struct.pack('>d', value)

範囲は、あなたの質問が完全に理にかなっている唯一の側面です。

精度に関して言えば、あなたが言うように、Pythonは常にdouble を内部で使用し、単純な3.3is でさえも float としてパックおよびアンパックされるため、質問は意味がありません3.299999952316284

struct.unpack('>f', struct.pack('>f', 3.3))
(3.299999952316284,)

したがって、事実上 double を float として表現することはできません。(通常、int でないか、元々 float から出てくるものはありません。)

ただし、数値のパック/アンパック バージョンが元の数値と等しいかどうかを確認し、等しい場合は float バージョンを使用できます。

try:
  binary = struct.pack('>f', value)
  if struct.unpack('>f', binary)[0] != value:
    binary = struct.pack('>d', value)
except OverflowError:
  binary = struct.pack('>d', value)
于 2013-11-14T13:34:17.860 に答える
0

float を double に変換し直し、結果​​を x と比較することで、double x が float として正確に表現できるかどうかを確認できます。

すべての float は double で正確に表現できるため、逆変換には丸めが含まれません。float が元の double と等しい場合にのみ、結果は元の double と等しくなります。

于 2013-11-15T02:59:27.503 に答える
-1

単精度

IEEE 単精度浮動小数点標準表現には、左から右に 0 から 31 までの番号が付けられた 32 ビット ワードが必要です。

最初のビットは符号ビット S、次の 8 ビットは指数ビット「E」、最後の 23 ビットは分数「F」です。


倍精度

IEEE 倍精度浮動小数点標準表現には 64 ビット ワードが必要であり、左から右に 0 から 63 までの番号で表すことができます。

最初のビットは符号ビット S、次の 11 ビットは指数ビット「E」、最後の 52 ビットは分数「F」です。

于 2013-11-14T13:26:07.227 に答える