Функция дополнения до двух выводит неверный результат для -1

Я генерирую ввод для программы FPGA, чтобы использовать метод трапециевидной интеграции. По сути, здесь интерес представляют функции invert() и twos_comp(); остальное просто тестирование (создание сигнала прямоугольной формы, а затем повторение и преобразование его в дополнение до двух).

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)

Проблема здесь в том, что это выводит дополнение до двух для 1 как 01111111, а не 1111111. Вывод invert() кажется правильным, вывод для twos_comp() для положительных чисел кажется правильным, и генерация сигнала также кажется правильной. , поэтому я думаю, что это должно быть что-то с линией

return format(int(invert(bin_val),2) + int('1', 2), '08b')

но оглядываясь на SO и google, вот как другие люди обрабатывали добавление в двоичном формате.

Обратите внимание, что все входы в twos_comp() будут 8-битными. Любая помощь будет оценена по поводу того, почему это не работает. Прямых ошибок нет, только неверный вывод.

Вы можете запустить код здесь.


person karatechop    schedule 07.08.2018    source источник


Ответы (1)


Пройдитесь по значениям, когда val равно -1:

>>> format(-1, '08b')
'-0000001'

Возможно, вы уже заметили ошибку — 08b означает ширину 8 символов, а не 8 цифр. Для отрицательного числа - занимает 1 символ, поэтому вы получаете только 8 цифр. Но если непонятно, почему это проблема, продолжим:

>>> 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

Если вам нужно хакерское решение (а я подозреваю, что вам это нужно, так как вы уже постоянно переключаетесь между строками и числами), просто сделайте это:

bin_val = format(val, '09b')[-8:]

Это будет работать как для положительных, так и для отрицательных чисел.

person abarnert    schedule 07.08.2018
comment
Ах... было бы так. И да, это довольно хакерски, я пытаюсь быстро собрать его вместе, чтобы протестировать какой-нибудь другой код. Спасибо! - person karatechop; 07.08.2018