Скажімо, у мене є цей номер i = -6884376
. Як я можу посилатися на неї як на непідписану змінну? Щось як (unsigned long)i
у C.
abs
функція не дає того, що (unsigned)
дає акторський склад , що є (uint32_t)a = (1LL << 32) - a
додатком 2
Скажімо, у мене є цей номер i = -6884376
. Як я можу посилатися на неї як на непідписану змінну? Щось як (unsigned long)i
у C.
abs
функція не дає того, що (unsigned)
дає акторський склад , що є (uint32_t)a = (1LL << 32) - a
додатком 2
Відповіді:
Припускаючи :
(unsigned long)
вам означає беззнаковое 32-розрядний ціле число,тоді вам просто потрібно додати 2**32 (or 1 << 32)
до від’ємного значення.
Наприклад, застосуйте це до -1:
>>> -1
-1
>>> _ + 2**32
4294967295L
>>> bin(_)
'0b11111111111111111111111111111111'
Припущення # 1 означає, що ви хочете, щоб -1 розглядався як суцільний рядок з 1 біта, а припущення # 2 означає, що ви хочете, щоб їх було 32.
Однак ніхто, крім вас, не може сказати, якими є ваші приховані припущення. Якщо, наприклад, ви маєте на увазі подання 1-доповнення, то вам потрібно ~
замість цього застосувати оператор префікса. Цілі числа Python наполегливо працюють, щоб створити ілюзію використання нескінченно широкого представлення доповнення 2 (як звичайне доповнення 2, але з нескінченною кількістю «знакових бітів»).
А щоб повторити те, що робить компілятор платформи C, ви можете використовувати ctypes
модуль:
>>> import ctypes
>>> ctypes.c_ulong(-1) # stuff Python's -1 into a C unsigned long
c_ulong(4294967295L)
>>> _.value
4294967295L
C unsigned long
буває 4 байтами в полі, в якому пройшов цей зразок.
_
посилання на результат попереднього рядка!
"_"
для отримання попереднього результату - це не особливість самої мови, а зручність, реалізована деякими (більшість? Усіх?) Інтерактивними оболонками Python. Вони повинні захопити найсвіжіший результат незалежно від того, щоб відобразити його. Сама мова такого не робить.
Щоб отримати значення, еквівалентне творому C, просто побітово та з відповідною маскою. наприклад, якщо unsigned long
32-бітний:
>>> i = -6884376
>>> i & 0xffffffff
4288082920
або якщо це 64 біт:
>>> i & 0xffffffffffffffff
18446744073702667240
Майте на увазі, хоча, хоча це дає вам значення, яке ви мали б у C, воно все ще є підписаним значенням, тому будь-які подальші обчислення можуть дати негативний результат, і вам доведеться продовжувати застосовувати маску для імітації 32 або 64 розрахунок бітів.
Це працює, тому що хоча Python виглядає так, ніби він зберігає всі числа як знак і величину, побітові операції визначаються як робота над значеннями доповнення двох. C зберігає цілі числа у двійки, доповнюючи їх, але з фіксованою кількістю бітів. Побітові оператори Python діють на двоє значень доповнення, але ніби вони мають нескінченну кількість бітів: для позитивних чисел вони розширюються вліво до нескінченності з нулями, але від'ємні числа продовжуються ліворуч з одиницями. &
Оператор змінить цю левонаправленную рядок одиниць в нулі і залишити вас з тільки битами , які будуть мати підгонку в значення C.
Відображення значень у шістнадцятковій формі може зробити це зрозумілішим (і я переписав на рядок f як вираз, щоб показати, що нас цікавлять або 32, або 64 біти):
>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'
Для 32-бітового значення в C додатні числа збільшуються до 2147483647 (0x7fffffff), а негативні числа мають верхній біт, що йде від -1 (0xffffffff) до -2147483648 (0x80000000). Для значень, які цілком вміщуються в масці, ми можемо змінити процес у Python, використовуючи меншу маску, щоб видалити знаковий біт, а потім віднявши знаковий біт:
>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376
Або для 64-розрядної версії:
>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376
Цей зворотний процес залишить значення незмінним, якщо знаковий біт дорівнює 0, але, очевидно, це не є справжнім оберненим, тому що якщо ви починали зі значення, яке не вписується в розмір маски, ці біти зникнуть.
Python не має вбудованих типів без підпису. Ви можете використовувати математичні операції для обчислення нового int, що представляє значення, яке ви отримали б в C, але немає "беззнакового значення" Python int. Int Python - це абстракція цілочисельного значення, а не прямий доступ до цілого числа фіксованого байту.
Ви можете використовувати struct
вбудовану бібліотеку Python:
Кодувати:
import struct
i = -6884376
print('{0:b}'.format(i))
packed = struct.pack('>l', i) # Packing a long number.
unpacked = struct.unpack('>L', packed)[0] # Unpacking a packed long number to unsigned long
print(unpacked)
print('{0:b}'.format(unpacked))
Вийшов:
-11010010000110000011000
4288082920
11111111100101101111001111101000
Розшифрувати:
dec_pack = struct.pack('>L', unpacked) # Packing an unsigned long number.
dec_unpack = struct.unpack('>l', dec_pack)[0] # Unpacking a packed unsigned long number to long (revert action).
print(dec_unpack)
Вийшов:
-6884376
[ ПРИМІТКА ]:
>
є операцією BigEndian.l
довгий.L
не підписано довго.amd64
архітектурі int
і long
є 32-бітовими, отже, ви можете використовувати i
і I
замість l
і, L
відповідно.python не має жодної вбудованої функції, щоб перетворити int на непідписаний int, а замість цього він має довгий діапазон.
>>> val = 9223372036854775807 (maximum value of int 64)
>>> type(val)
<type 'int'>
>>> val += 1
>>> type(val)
<type 'long'>
Збільшуючи значення val на 1, я перевищую межу підписаного 64-бітового цілого числа, і значення перетворюється на long. Якби Python використовував або перетворював на ціле число без знака, val все одно був би int. Або, недовго.
Підписані цілі числа представлені бітом, як правило, найбільш значущим бітом, для якого встановлено значення 0 для додатних чи 1 для негативних чисел. Те, що робить val & 0xff, насправді є val & 0x000000ff (на 32-бітній машині). Іншими словами, підписаний біт встановлюється на 0, а беззнакове значення емулюється.
Приклад:
>>> val = -1
>>> val & 0xff
255
просто використовуйте abs для перетворення непідписаного в підписаний python
a=-12
b=abs(a)
print(b)
Вихід: 12
abs()
Повертає абсолютне значення числа. Аргументом може бути звичайне або довге ціле число або число з плаваючою комою. Якщо аргумент є комплексним числом, повертається його величина. Це за визначенням не повертає unsigned
змінну весь час