converts signed decimal numbers to signed binary and vice versa

98 views Asked by At

Can't Write Decimal To Binary and vice versa converter that works with the positive and negative numbers.

This Decimal To Binary Converter works fine

# decimal to binary 
def to2sCompStr(num):
    bitWidth = 8
    num &= (2 << bitWidth-1)-1 
    formatStr = '{:0'+str(bitWidth)+'b}'
    ret =  formatStr.format(int(num))
    return ret


print(to2sCompStr(-100))
#output 10011100


# Binary To decimal
binary = 10011100 
print(int(binary, 2))
# output 156, not -100
    

Binary To Decimal Working only on positive number, not negative

1

There are 1 answers

0
Booboo On BEST ANSWER

The call to int function with the base argument set to 2 in order to convert binary strings does not recognize input in two's-complement notation. It cannot assume that the leftmost "bit" (actually a character '0' or '1') of the input string is a sign bit. It does, however, recognize a leading '-' character.

Therefore, your to2sCompStr needs to negate negative numbers before calling int() and then prefix the result with a '-':

# decimal to binary
def to2sCompStr(num):
    bitWidth = 8
    if num < 0:
        negative = True
        num = -num
    else:
        negative = False
    num &= (2 << bitWidth-1)-1
    formatStr = '-{:0'+str(bitWidth)+'b}' if negative else '{:0'+str(bitWidth)+'b}'
    return formatStr.format(int(num))


binary = to2sCompStr(-100)
print(binary)
#output -01100100


print(int(binary, 2))
# output -100

Prints:

-01100100
-100

The alternative is not to use the int builtin function:

BITWIDTH = 8
MAX_POSITIVE_NUM = 2 ** (BITWIDTH - 1) - 1
MIN_NEGATIVE_NUM = -(2 ** (BITWIDTH - 1))

# decimal to binary:

def to2sCompStr(num):
    if not (MIN_NEGATIVE_NUM <= num <= MAX_POSITIVE_NUM):
        raise ValueError(f'Invalid input: {num}')
    num &= (2 << BITWIDTH-1)-1
    formatStr = '{:0'+str(BITWIDTH)+'b}'
    return formatStr.format(int(num))

# binary to decimal:

def strTo2Int(num):
    n = int(num, 2)
    return n if num[0] == '0' else -(2**len(num) - n)

for n in (0, 1, -1, 100, -100):
    base2 = to2sCompStr(n)
    base10 = strTo2Int(base2)
    print(n, base2, base10)

Prints:

0 00000000 0
1 00000001 1
-1 11111111 -1
100 01100100 100
-100 10011100 -100