I am generating the input for an FPGA program to use the trapezoidal integration method. Basically, the functions of interest here are the invert()
and twos_comp()
functions; the rest is just testing (creating a square wave signal, and then iterating through and converting it into two's complement).
signals = []
bit_signals = []
def invert(bit_val):
new_val = []
for i in bit_val:
new_val.append(str(int(not(int(i)))))
return ''.join(new_val)
def twos_comp(val):
if val < 0:
bin_val = format(val, '08b')[1:]
return format(int(invert(bin_val),2) + int('1', 2), '08b')
else:
bin_val = format(val, '08b')[1:]
return bin_val
x = 0
signal = 1
while x <= 25:
if x % 2 == 0:
signal*=-1
signals.append(signal)
x+=1
print(signals)
for i in signals:
bit_signals.append(twos_comp(i))
print(bit_signals)
The problem here is that this outputs the two's complement for 1 as 01111111, not 1111111. The output of invert()
seems to be correct, the output for twos_comp()
for positive numbers seems to be correct, and the generation of the signal also appears to be correct, so I think it must be something with the line
return format(int(invert(bin_val),2) + int('1', 2), '08b')
but looking around on SO and google this is how other people have handled adding in binary.
Please note that all inputs to twos_comp()
will be 8 bits. Any help would be appreciated as to why this is not working. There are no outright errors, just an incorrect output.
You can run the code here.
Step through the values when val
is -1
:
>>> format(-1, '08b')
'-0000001'
You may have already spotted the error—08b
means 8 characters wide, not 8 digits. For a negative number, the -
takes up 1 of the characters, so you only get 8 digits. But in case it isn't obvious why that's a problem, let's keep going:
>>> format(val, '08b')[1:]
'0000001'
>>> invert('0000001')
'1111110'
>>> int(invert('0000001'), 2)
126
>>> int('1', 2) # BTW, why do you need this instead of just 1, exactly?
1
>>> 126 + 1
127
>>> format(127, '08b')
01111111
If you want a hacky solution (and I suspect you do, since you're already going back and forth between strings and numbers all over the place), just do this:
bin_val = format(val, '09b')[-8:]
That will work for both positive and negative numbers.