84

文字列を 32 ビット浮動小数点数のバイナリ IEEE 754 表現として取得するには?

1.00 -> '0011111110000000000000000000000'

4

13 に答える 13

81

structパッケージでそれを行うことができます:

import struct
def binary(num):
    return ''.join('{:0>8b}'.format(c) for c in struct.pack('!f', num))

それをネットワーク バイト順の float としてパックし、結果の各バイトを 8 ビットのバイナリ表現に変換して連結します。

>>> binary(1)
'00111111100000000000000000000000'

編集:説明を拡大するリクエストがありました。中間変数を使用してこれを展開し、各ステップにコメントを付けます。

def binary(num):
    # Struct can provide us with the float packed into bytes. The '!' ensures that
    # it's in network byte order (big-endian) and the 'f' says that it should be
    # packed as a float. Alternatively, for double-precision, you could use 'd'.
    packed = struct.pack('!f', num)
    print 'Packed: %s' % repr(packed)

    # For each character in the returned string, we'll turn it into its corresponding
    # integer code point
    # 
    # [62, 163, 215, 10] = [ord(c) for c in '>\xa3\xd7\n']
    integers = [ord(c) for c in packed]
    print 'Integers: %s' % integers

    # For each integer, we'll convert it to its binary representation.
    binaries = [bin(i) for i in integers]
    print 'Binaries: %s' % binaries

    # Now strip off the '0b' from each of these
    stripped_binaries = [s.replace('0b', '') for s in binaries]
    print 'Stripped: %s' % stripped_binaries

    # Pad each byte's binary representation's with 0's to make sure it has all 8 bits:
    #
    # ['00111110', '10100011', '11010111', '00001010']
    padded = [s.rjust(8, '0') for s in stripped_binaries]
    print 'Padded: %s' % padded

    # At this point, we have each of the bytes for the network byte ordered float
    # in an array as binary strings. Now we just concatenate them to get the total
    # representation of the float:
    return ''.join(padded)

そして、いくつかの例の結果:

>>> binary(1)
Packed: '?\x80\x00\x00'
Integers: [63, 128, 0, 0]
Binaries: ['0b111111', '0b10000000', '0b0', '0b0']
Stripped: ['111111', '10000000', '0', '0']
Padded: ['00111111', '10000000', '00000000', '00000000']
'00111111100000000000000000000000'

>>> binary(0.32)
Packed: '>\xa3\xd7\n'
Integers: [62, 163, 215, 10]
Binaries: ['0b111110', '0b10100011', '0b11010111', '0b1010']
Stripped: ['111110', '10100011', '11010111', '1010']
Padded: ['00111110', '10100011', '11010111', '00001010']
'00111110101000111101011100001010'
于 2013-05-08T15:40:01.217 に答える
40

ここに醜いものがあります...

>>> import struct
>>> bin(struct.unpack('!i',struct.pack('!f',1.0))[0])
'0b111111100000000000000000000000'

基本的に、構造体モジュールを使用して float を int に変換しました...


を使用したわずかに優れたものを次に示しctypesます。

>>> import ctypes
>>> bin(ctypes.c_uint.from_buffer(ctypes.c_float(1.0)).value)
'0b111111100000000000000000000000'

基本的に、 を構築しfloatて同じメモリ位置を使用しますが、 としてタグ付けしc_uintます。のc_uint値は、組み込み関数を使用できる python 整数ですbin

于 2013-05-08T15:40:24.340 に答える
12

完全を期すために、次を使用して numpy でこれを実現できます。

f = 1.00
int32bits = np.asarray(f, dtype=np.float32).view(np.int32).item()  # item() optional

b次に、フォーマット指定子を使用して、パディングを付けてこれを印刷できます

print('{:032b}'.format(int32bits))
于 2016-10-25T21:17:20.037 に答える
10

この問題は、2 つの部分に分割することで、より明確に処理されます。

1 つ目は、float を同等のビット パターンを持つ int に変換することです。

import struct
def float32_bit_pattern(value):
    return sum(ord(b) << 8*i for i,b in enumerate(struct.pack('f', value)))

Python 3 ではordバイトを整数に変換する必要がないため、上記を少し単純化する必要があります。

def float32_bit_pattern(value):
    return sum(b << 8*i for i,b in enumerate(struct.pack('f', value)))

次に、int を文字列に変換します。

def int_to_binary(value, bits):
    return bin(value).replace('0b', '').rjust(bits, '0')

それらを組み合わせます:

>>> int_to_binary(float32_bit_pattern(1.0), 32)
'00111111100000000000000000000000'
于 2013-05-08T16:18:47.267 に答える
9

これら 2 つの単純な関数 ( Python >=3.6 ) を使用すると、IEEE 754 binary64 の場合、浮動小数点数を 2 進数に、またはその逆に簡単に変換できます。

import struct

def bin2float(b):
    ''' Convert binary string to a float.

    Attributes:
        :b: Binary string to transform.
    '''
    h = int(b, 2).to_bytes(8, byteorder="big")
    return struct.unpack('>d', h)[0]


def float2bin(f):
    ''' Convert float to 64-bit binary string.

    Attributes:
        :f: Float number to transform.
    '''
    [d] = struct.unpack(">Q", struct.pack(">d", f))
    return f'{d:064b}'

例えば:

print(float2bin(1.618033988749894))
print(float2bin(3.14159265359))
print(float2bin(5.125))
print(float2bin(13.80))

print(bin2float('0011111111111001111000110111011110011011100101111111010010100100'))
print(bin2float('0100000000001001001000011111101101010100010001000010111011101010'))
print(bin2float('0100000000010100100000000000000000000000000000000000000000000000'))
print(bin2float('0100000000101011100110011001100110011001100110011001100110011010'))

出力は次のとおりです。

0011111111111001111000110111011110011011100101111111010010100100
0100000000001001001000011111101101010100010001000010111011101010
0100000000010100100000000000000000000000000000000000000000000000
0100000000101011100110011001100110011001100110011001100110011010
1.618033988749894
3.14159265359
5.125
13.8

気に入っていただければ幸いです。私にとっては完璧に機能します。

于 2020-01-04T21:12:53.993 に答える
2

これは要求されたものよりも少し多いですが、このエントリを見つけたときに必要なものでした. このコードは、IEEE 754 32 ビット浮動小数点数の仮数、基数、および符号を提供します。

import ctypes
def binRep(num):
    binNum = bin(ctypes.c_uint.from_buffer(ctypes.c_float(num)).value)[2:]
    print("bits: " + binNum.rjust(32,"0"))
    mantissa = "1" + binNum[-23:]
    print("sig (bin): " + mantissa.rjust(24))
    mantInt = int(mantissa,2)/2**23
    print("sig (float): " + str(mantInt))
    base = int(binNum[-31:-23],2)-127
    print("base:" + str(base))
    sign = 1-2*("1"==binNum[-32:-31].rjust(1,"0"))
    print("sign:" + str(sign))
    print("recreate:" + str(sign*mantInt*(2**base)))

binRep(-0.75)

出力:

bits: 10111111010000000000000000000000
sig (bin): 110000000000000000000000
sig (float): 1.5
base:-1
sign:-1
recreate:-0.75
于 2016-11-11T13:04:14.603 に答える
0

これらの回答のいくつかは、Python 3 で書かれたとおりに機能しなかったか、負の浮動小数点数を正しく表現できませんでした。私は次のことがうまくいくことを発見しました(ただし、これは私が必要としていた64ビット表現を提供します)

def float_to_binary_string(f):
    def int_to_8bit_binary_string(n):
        stg=bin(n).replace('0b','')
        fillstg = '0'*(8-len(stg))
        return fillstg+stg
    return ''.join( int_to_8bit_binary_string(int(b)) for b in struct.pack('>d',f) )
于 2016-09-23T19:01:08.657 に答える