[PYTHON] 파이썬에서 float의 이진 표현 (16 진수가 아닌 비트)
PYTHON파이썬에서 float의 이진 표현 (16 진수가 아닌 비트)
문자열을 32 비트 부동 소수점의 이진 IEEE 754 표현으로 가져 오는 방법은 무엇입니까?
예
1.00 -> '00111111100000000000000000000000'
해결법
-
==============================
1.구조체 패키지를 사용하면 다음과 같이 할 수 있습니다.
구조체 패키지를 사용하면 다음과 같이 할 수 있습니다.
import struct def binary(num): return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))
이것은 네트워크 byte-ordered 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'
-
==============================
2.못 생겼어 ...
못 생겼어 ...
>>> import struct >>> bin(struct.unpack('!i',struct.pack('!f',1.0))[0]) '0b111111100000000000000000000000'
기본적으로, 나는 struct 모듈을 사용하여 float를 int로 변환했다.
다음은 ctypes를 사용하여 약간 더 나은 방법입니다.
>>> import ctypes >>> bin(ctypes.c_uint.from_buffer(ctypes.c_float(1.0)).value) '0b111111100000000000000000000000'
기본적으로, 나는 플로트를 만들고 동일한 메모리 위치를 사용하지만, 나는 c_uint로 태그를 붙인다. c_uint의 값은 내장 빈 함수를 사용할 수있는 파이썬 정수입니다.
-
==============================
3.bitstring 모듈을 사용하는 다른 솔루션을 찾았습니다.
bitstring 모듈을 사용하는 다른 솔루션을 찾았습니다.
import bitstring f1 = bitstring.BitArray(float=1.0, length=32) print f1.bin
산출:
00111111100000000000000000000000
-
==============================
4.이 문제는 두 부분으로 나누어보다 명확하게 처리됩니다.
이 문제는 두 부분으로 나누어보다 명확하게 처리됩니다.
첫 번째는 해당 비트 패턴을 사용하여 float를 int로 변환하는 것입니다.
def float32_bit_pattern(value): return sum(ord(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'
-
==============================
5.완전을 기하기 위해 다음을 사용하여 numpy로이 작업을 수행 할 수 있습니다.
완전을 기하기 위해 다음을 사용하여 numpy로이 작업을 수행 할 수 있습니다.
f = 1.00 int32bits = np.asarray(f, dtype=np.float32).view(np.int32).item() # item() optional
그런 다음 b 형식 지정자를 사용하여 패딩을 사용하여이를 인쇄 할 수 있습니다
print('{:032b}'.format(int32bits))
-
==============================
6.비슷한 질문을 많이 읽은 후 필자가 원했던 것을 무언가 적어 보았습니다.
비슷한 질문을 많이 읽은 후 필자가 원했던 것을 무언가 적어 보았습니다.
f = 1.00 negative = False if f < 0: f = f*-1 negative = True s = struct.pack('>f', f) p = struct.unpack('>l', s)[0] hex_data = hex(p) scale = 16 num_of_bits = 32 binrep = bin(int(hex_data, scale))[2:].zfill(num_of_bits) if negative: binrep = '1' + binrep[1:]
binrep이 결과입니다. 각 부분에 대해 설명합니다.
f = 1.00 negative = False if f < 0: f = f*-1 negative = True
음수 일 경우 숫자를 양수로 변환하고 음수를 음수로 설정합니다. 그 이유는 양수 및 음수 바이너리 표현의 차이가 첫 번째 비트에 불과하기 때문에 음수로 전체 프로세스를 수행 할 때 잘못된 점을 파악하는 것보다 더 간단한 방법이었습니다.
s = struct.pack('>f', f) #'?\x80\x00\x00' p = struct.unpack('>l', s)[0] #1065353216 hex_data = hex(p) #'0x3f800000'
s는 2 진수 f의 16 진수 표현입니다. 그러나 그것은 내가 필요한 예쁜 형태가 아닙니다. Th가 p가 들어오는 곳입니다. 헥스의 int 표현입니다. 그리고 예쁜 헥스를 얻기위한 다른 변환.
scale = 16 num_of_bits = 32 binrep = bin(int(hex_data, scale))[2:].zfill(num_of_bits) if negative: binrep = '1' + binrep[1:]
scale은 16 진수의 기본 16입니다. num_of_bits는 32이고, float는 32 비트이므로 나중에 0으로 추가 자리를 채우기 위해 사용됩니다.이 질문에서 binrep 코드를 얻습니다. 숫자가 음수이면 첫 번째 비트 만 변경하십시오.
나는 이것이 추한 것을 알고 있지만, 나는 좋은 방법을 찾지 못했고 나는 그것을 빨리 필요로했다. 의견 환영합니다.
-
==============================
7.내 생각에 .format을 비트의 가장 쉬운 표현으로 사용할 수 있습니다.
내 생각에 .format을 비트의 가장 쉬운 표현으로 사용할 수 있습니다.
내 코드는 다음과 같습니다.
def fto32b(flt): # is given a 32 bit float value and converts it to a binary string if isinstance(flt,float): # THE FOLLOWING IS AN EXPANDED REPRESENTATION OF THE ONE LINE RETURN # packed = struct.pack('!f',flt) <- get the hex representation in (!)Big Endian format of a (f) Float # integers = [] # for c in packed: # integers.append(ord(c)) <- change each entry into an int # binaries = [] # for i in integers: # binaries.append("{0:08b}".format(i)) <- get the 8bit binary representation of each int (00100101) # binarystring = ''.join(binaries) <- join all the bytes together # return binarystring return ''.join(["{0:08b}".format(i) for i in [ord(c) for c in struct.pack('!f',flt)]]) return None
산출:
>>> a = 5.0 '01000000101000000000000000000000' >>> b = 1.0 '00111111100000000000000000000000'
-
==============================
8.이러한 답변 중 일부는 Python 3로 작성된 것처럼 작동하지 않거나 음의 부동 소수점 숫자를 올바르게 나타내지 않았습니다. 나는 나를 위해 일할 다음을 발견했다. (이것은 내가 필요로하는 64 비트 표현을 제공하지만)
이러한 답변 중 일부는 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) )
-
==============================
9.이것은 묻는 것보다 조금 더 많았지 만,이 항목을 발견했을 때 필요한 것이 었습니다. 이 코드는 IEEE 754 32 비트 부동 소수점의 가수, 기준 및 부호를 제공합니다.
이것은 묻는 것보다 조금 더 많았지 만,이 항목을 발견했을 때 필요한 것이 었습니다. 이 코드는 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
from https://stackoverflow.com/questions/16444726/binary-representation-of-float-in-python-bits-not-hex by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Subprocess.Popen에서 "source"명령 호출 (0) | 2018.10.04 |
---|---|
[PYTHON] 파이썬 2 개체를 파이썬 3으로 풀어주기 (0) | 2018.10.04 |
[PYTHON] 파이썬 : 바인딩 소켓 : "이미 사용중인 주소" (0) | 2018.10.04 |
[PYTHON] __str__ 및 __repr__의 목적은 무엇입니까? (0) | 2018.10.04 |
[PYTHON] 파이썬에서 개인 및 보호 된 메소드의 상속 (0) | 2018.10.04 |