Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Bestin
- 애플
- 공모주
- ConnectedHomeIP
- esp32
- 월패드
- cluster
- matter
- SK텔레콤
- MQTT
- Python
- 배당
- 티스토리챌린지
- Apple
- homebridge
- 힐스테이트 광교산
- 파이썬
- 코스피
- RS-485
- 매터
- 홈네트워크
- Espressif
- 해외주식
- 국내주식
- 현대통신
- 오블완
- 미국주식
- Home Assistant
- 나스닥
- raspberry pi
Archives
- Today
- Total
YOGYUI
Python - 음의 정수를 16진수로 표현하기 (negative int to hex) 본문
반응형
Python 내장함수인 hex는 정수값을 16진수로 표현된 문자열(str)을 반환해준다
help(hex)
>>
Help on built-in function hex in module builtins:
hex(number, /)
Return the hexadecimal representation of an integer.
hex(12648430)
'0xc0ffee'
In [1]: hex(25)
Out[1]: '0x19'
In [2]: hex(1234)
Out[2]: '0x4d2'
그런데, 함수의 인자로 음의 정수 (negative integer)를 입력하면 다른 프로그래밍 언어에서와는 다른 결과가 출력된다
In [3]: hex(-1)
Out[3]: '-0x1'
In [4]: hex(-128)
Out[4]: '-0x80'
C/C++과 같이 자료형의 크기를 사전에 설정하는 언어에서는 위의 예에서
- 1바이트(8bit)의 경우 -1 = 0xFF, -128 = 0x80
- 4바이트(32bit)의 경우 -1 = 0xFFFFFFFF, -128 = 0xFFFFFF80
이 되어야 한데, hex 함수는 정수형을 몇 바이트 자료형으로 처리할 지에 대한 개념이 없으니 그냥 속편하게 절대값을 취한 뒤 - 기호를 붙여서 반환해버린다
음수가 왜 위와 같이 표현되어야 하는지는 '2의 보수 (2's complement)'와 관련있는데, 프로그래머라면 반드시 알아야 하는 개념이니 remind하도록 하자
https://ko.wikipedia.org/wiki/2%EC%9D%98_%EB%B3%B4%EC%88%98
구글링해보니 2가지 방식이 흔히 쓰이는데, 편한 방식을 골라서 사용하면 된다
(핵심은 정수값을 몇 바이트로 처리해야하는지를 함께 기입)
1. Bit Shifting
def tohex1(value: int, nbit: int):
conv = (value + (1 << nbit)) % (1 << nbit)
return hex(conv)
In [5]: tohex1(-1, 8)
Out[5]: '0xff'
In [6]: tohex1(-128, 8)
Out[6]: '0x80'
In [7]: tohex1(127, 8)
Out[7]: '0x7f'
2. Bit Masking
def tohex2(value: int, nbit: int):
conv = (value & (2 ** nbit - 1))
return hex(conv)
In [8]: tohex2(-1, 8)
Out[8]: '0xff'
In [9]: tohex2(-128, 8)
Out[9]: '0x80'
In [10]: tohex2(127, 8)
Out[10]: '0x7f'
Bit Shifting이 Bit Masking보다 수행속도가 약간 빠르니 1번을 추천한다
import time
tm = time.perf_counter()
for _ in range(100000):
tohex1(-1, 8)
elapsed1 = time.perf_counter() - tm
tm = time.perf_counter()
for _ in range(100000):
tohex2(-1, 8)
elapsed2 = time.perf_counter() - tm
In [11]: elapsed1
Out[11]: 0.05493220000062138
In [12]: elapsed2
Out[12]: 0.08496230000309879
3. Etc
위 2개의 구현 모두 범위를 벗어나는 경우에 대한 예외처리가 없다
In [13]: tohex1(-128, 8)
Out[13]: '0x80'
In [14]: tohex1(128, 8)
Out[14]: '0x80'
8비트 signed 정수형이 표현할 수 있는 값의 범위는 -128 ~ +127 까지이므로 (128, 8)에 대해서는 예외처리를 해주는 게 바람직하다
def tohex1(value: int, nbit: int):
if -2 ** (nbit - 1) <= value <= 2 ** (nbit - 1) - 1:
conv = (value + (1 << nbit)) % (1 << nbit)
return hex(conv)
else:
raise ValueError
str의 format 으로도 위와 유사하게 구현할 수 있다
def tohex3(value: int, nbit: int):
if -2 ** (nbit - 1) <= value <= 2 ** (nbit - 1) - 1:
conv = (value + (1 << nbit)) % (1 << nbit)
return '{:X}'.format(conv)
else:
raise ValueError
어떤 형식으로 포매팅할 지는 구현하는 사람 마음대로~
끝~!
[참고]
반응형
'Software > Python' 카테고리의 다른 글
PyQt5 - QtWebEngine::웹브라우저 만들기 (1) (8) | 2021.09.03 |
---|---|
Python - str format 중괄호 (brace) 출력하기 (0) | 2021.08.25 |
Python - list 요소 뒤집기 (reverse list elements) (0) | 2021.08.20 |
Python - 윈도OS 환경 변수 변경하기 (Modify Environment Variables) (1) | 2021.08.17 |
PyQt5 - Connect pyqtSignal in For loop (lambda problem) (0) | 2021.07.20 |