Беззнаковые целые произвольной длины в Python - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь смоделировать реализацию фильтра с фиксированной запятой.Я хочу использовать низкоуровневые аппаратные функции, такие как переполнение / переполнение в 2 с и фиксированная ширина регистров.Некоторые ширины регистров устанавливаются аппаратными функциями на необычные и длинные ширины (например, 72b).

Я добился определенного прогресса, используя встроенные целые числа.Бесконечная ширина невероятно полезна ... но я часто сражаюсь с Python, потому что иногда он хочет интерпретировать двоичный файл как положительное целое число, а иногда он хочет интерпретировать очень похожий двоичный файл как дополнение отрицательного числа 2.Например:

>> a = 0b11111                          # sign-extended -1
>> b = 0b0011
>> print("{0:b}".format(a*b))
5f
>> print("{0:b}".format((a*b)&a))       # Truncate to correct product length
11101                                   # == -3 in 2s complement. Great!
>> print("{0:b}".format(~((a*b)&a)+1))  # Actually perform the 2's complement
-11101                                  # Arrrrggggghhh
>> print("{0:b}".format((~((a*b)&a)&a)+1))  # Truncate with extreme prejudice
11                                          # OK. Fine.

Полагаю, если я буду достаточно усердно думать, я смогу понять, почему все это работает так, как работает, но если бы я мог просто делать все это в неподписанном пространстве, не беспокоясь о добавлении битами знака в pythonэто сделает вещи проще и менее подвержены ошибкам.Кто-нибудь знает, есть ли относительно простой способ сделать это?Я рассматривал битовые строки, но в этом приложении мне приходится много добавлять и умножать, и встроенная целочисленная арифметика действительно полезна для этого.

1 Ответ

0 голосов
/ 05 декабря 2018

~x буквально определяется на целых числах произвольной точности как -(x+1).Он не выполняет битовую арифметику: ~0 равен 255 в однобайтовых целых числах, 65535 в двухбайтовых целых числах, 1023 для 10-битных целых чисел и т. Д .;поэтому определение ~ с помощью инверсии битов для растягиваемых целых чисел бесполезно.

Если a определяет фиксированную ширину ваших целых чисел (с 0b11111, говорящим, что вы работаете с пятибитными числами), инверсия битовтак же просто, как a^x.

print("{0:b}".format(a ^ b)
# => 11100

В то же время два дополнения проще всего сделать как a+1-b, или эквивалентно a^b+1:

print("{0:b}".format((a + 1) - b))
# => 11101
print("{0:b}".format((a ^ b) + 1))
# => 11101

tl; dr: не использовать~ если вы хотите остаться без подписи.

...