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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
"Collection of tools for displaying bit representation of numbers."""
from __future__ import print_function
def binary(n, width=None):
"""
Return a list of (0|1)'s for the binary representation of n where n >= 0.
If you specify a width, it must be > 0, otherwise it is ignored. The list
could be padded with 0 bits if width is specified.
"""
l = []
if width and width <= 0:
width = None
while n > 0:
l.append(1 if n & 1 else 0)
n = n >> 1
if width:
for i in range(width - len(l)):
l.append(0)
l.reverse()
return l
def twos_complement(n, width):
"""
Return a list of (0|1)'s for the binary representation of a width-bit two's
complement numeral system of an integer n which may be negative.
"""
val = 2**(width - 1)
if n >= 0:
if n > (val - 1):
return None
# It is safe to represent n with width-bits.
return binary(n, width)
if n < 0:
if abs(n) > val:
return None
# It is safe to represent n (a negative int) with width-bits.
return binary(val * 2 - abs(n))
# print binary(0xABCD)
# [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1]
# print binary(0x1F, 8)
# [0, 0, 0, 1, 1, 1, 1, 1]
# print twos_complement(-5, 4)
# [1, 0, 1, 1]
# print twos_complement(7, 4)
# [0, 1, 1, 1]
# print binary(7)
# [1, 1, 1]
# print twos_complement(-5, 64)
# [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
def positions(width):
"""Helper function returning a list describing the bit positions.
Bit positions greater than 99 are truncated to 2 digits, for example,
100 -> 00 and 127 -> 27."""
return ['{0:2}'.format(i)[-2:] for i in reversed(range(width))]
def utob(debugger, command_line, result, dict):
"""Convert the unsigned integer to print its binary representation.
args[0] (mandatory) is the unsigned integer to be converted
args[1] (optional) is the bit width of the binary representation
args[2] (optional) if specified, turns on verbose printing"""
args = command_line.split()
try:
n = int(args[0], 0)
width = None
if len(args) > 1:
width = int(args[1], 0)
if width < 0:
width = 0
except:
print(utob.__doc__)
return
if len(args) > 2:
verbose = True
else:
verbose = False
bits = binary(n, width)
if not bits:
print("insufficient width value: %d" % width)
return
if verbose and width > 0:
pos = positions(width)
print(' ' + ' '.join(pos))
print(' %s' % str(bits))
def itob(debugger, command_line, result, dict):
"""Convert the integer to print its two's complement representation.
args[0] (mandatory) is the integer to be converted
args[1] (mandatory) is the bit width of the two's complement representation
args[2] (optional) if specified, turns on verbose printing"""
args = command_line.split()
try:
n = int(args[0], 0)
width = int(args[1], 0)
if width < 0:
width = 0
except:
print(itob.__doc__)
return
if len(args) > 2:
verbose = True
else:
verbose = False
bits = twos_complement(n, width)
if not bits:
print("insufficient width value: %d" % width)
return
if verbose and width > 0:
pos = positions(width)
print(' ' + ' '.join(pos))
print(' %s' % str(bits))
|