Assuming:

  1. You have 2's-complement representations in mind; and,
  2. By (unsigned long) you mean unsigned 32-bit integer,

then you just need to add 2**32 (or 1 << 32) to the negative value.

For example, apply this to -1:

>>> -1
-1
>>> _ + 2**32
4294967295L
>>> bin(_)
'0b11111111111111111111111111111111'

Assumption #1 means you want -1 to be viewed as a solid string of 1 bits, and assumption #2 means you want 32 of them.

Nobody but you can say what your hidden assumptions are, though. If, for example, you have 1's-complement representations in mind, then you need to apply the ~ prefix operator instead. Python integers work hard to give the illusion of using an infinitely wide 2's complement representation (like regular 2's complement, but with an infinite number of "sign bits").

And to duplicate what the platform C compiler does, you can use the ctypes module:

>>> import ctypes
>>> ctypes.c_ulong(-1)  # stuff Python's -1 into a C unsigned long
c_ulong(4294967295L)
>>> _.value
4294967295L

C's unsigned long happens to be 4 bytes on the box that ran this sample.

Answer from Tim Peters on Stack Overflow
Top answer
1 of 7
146

Assuming:

  1. You have 2's-complement representations in mind; and,
  2. By (unsigned long) you mean unsigned 32-bit integer,

then you just need to add 2**32 (or 1 << 32) to the negative value.

For example, apply this to -1:

>>> -1
-1
>>> _ + 2**32
4294967295L
>>> bin(_)
'0b11111111111111111111111111111111'

Assumption #1 means you want -1 to be viewed as a solid string of 1 bits, and assumption #2 means you want 32 of them.

Nobody but you can say what your hidden assumptions are, though. If, for example, you have 1's-complement representations in mind, then you need to apply the ~ prefix operator instead. Python integers work hard to give the illusion of using an infinitely wide 2's complement representation (like regular 2's complement, but with an infinite number of "sign bits").

And to duplicate what the platform C compiler does, you can use the ctypes module:

>>> import ctypes
>>> ctypes.c_ulong(-1)  # stuff Python's -1 into a C unsigned long
c_ulong(4294967295L)
>>> _.value
4294967295L

C's unsigned long happens to be 4 bytes on the box that ran this sample.

2 of 7
95

To get the value equivalent to your C cast, just bitwise and with the appropriate mask. e.g. if unsigned long is 32 bit:

>>> i = -6884376
>>> i & 0xffffffff
4288082920

or if it is 64 bit:

>>> i & 0xffffffffffffffff
18446744073702667240

Do be aware though that although that gives you the value you would have in C, it is still a signed value, so any subsequent calculations may give a negative result and you'll have to continue to apply the mask to simulate a 32 or 64 bit calculation.

This works because although Python looks like it stores all numbers as sign and magnitude, the bitwise operations are defined as working on two's complement values. C stores integers in twos complement but with a fixed number of bits. Python bitwise operators act on twos complement values but as though they had an infinite number of bits: for positive numbers they extend leftwards to infinity with zeros, but negative numbers extend left with ones. The & operator will change that leftward string of ones into zeros and leave you with just the bits that would have fit into the C value.

Displaying the values in hex may make this clearer (and I rewrote to string of f's as an expression to show we are interested in either 32 or 64 bits):

>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'

For a 32 bit value in C, positive numbers go up to 2147483647 (0x7fffffff), and negative numbers have the top bit set going from -1 (0xffffffff) down to -2147483648 (0x80000000). For values that fit entirely in the mask, we can reverse the process in Python by using a smaller mask to remove the sign bit and then subtracting the sign bit:

>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376

Or for the 64 bit version:

>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376

This inverse process will leave the value unchanged if the sign bit is 0, but obviously it isn't a true inverse because if you started with a value that wouldn't fit within the mask size then those bits are gone.

๐ŸŒ
Python Data Science Handbook
jakevdp.github.io โ€บ PythonDataScienceHandbook โ€บ 02.01-understanding-data-types.html
Understanding Data Types in Python | Python Data Science Handbook
Again, the advantage of the list is flexibility: because each list element is a full structure containing both data and type information, the list can be filled with data of any desired type. Fixed-type NumPy-style arrays lack this flexibility, but are much more efficient for storing and manipulating data. Python offers several different options for storing data in efficient, fixed-type data buffers. The built-in array module (available since Python 3.3) can be used to create dense arrays of a uniform type: ... Here 'i' is a type code indicating the contents are integers.
๐ŸŒ
Sololearn
sololearn.com โ€บ en โ€บ Discuss โ€บ 3320064 โ€บ python-and-unsigned-int
Python and unsigned int | Sololearn: Learn to code for FREE!
March 12, 2025 - Thanks Brian I was also only concerned about non negative values only. I just assigned as below: a = 0 And expected it to work , but it did not. type(a) is int and as python does not have strong type for unsigned int may be the reason. This made me think about what would happen if I have two api as below in C++. void display(int a); void display(unsigned int); Will above work with swig for python ?
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ how to maintain an unsignedness of number in python?
r/learnpython on Reddit: How to maintain an unsignedness of number in python?
June 26, 2024 -

How to maintain an unsignedness of number in python?

I have a function that takes an array of octets like so, swaps the bytes, and creates a number out of the array. The solution was seemingly easy with just:

def make_int(octets):
    OCTET_SIZE = 8
    num = 0
    for i in range(len(octets)):
        shift = OCTET_SIZE * i
        num |= octets[i] << shift
    return num

def main():
    octets = [0x00, 0x10, 0xAB, 0xCE]
    four_byte_value = make_int(octets)

But this will occasionally fail and I don't know why. I'll randomly get 0xffffxx and that, to me, is indicative of a twos complement integer. What are potential pitfalls of function that I'm missing that's inducing this strange behavior?

๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ how-to-convert-signed-to-unsigned-integer-in-python
How to convert signed to unsigned integer in Python ? - GeeksforGeeks
April 5, 2021 - Compared to C programming, Python does not have signed and unsigned integers as data types. There is no need to specify the data types for variables in python as the interpreter itself predicts the variable data ...
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ declaring an unsigned integer 16 in python for bit shift operation
r/learnpython on Reddit: Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
October 29, 2023 -

SOLVED: 3 Solutions:

  1. using Numpy : np.uint16()

  2. Using CTypes : ctypes.c_uint16()

  3. Using Bitwise : & 0xFFFF


Hi, I'm trying to convert this code to Python from Go / C. It involves declaring a UInt16 variable and run a bit shift operation. However cant seem to create a variable with this specific type. Need some advise here.

Go Code:

package main

import "fmt"

func main() {

var dx uint16 = 38629

var dy uint16 = dx << 8

fmt.Println(dy) //58624 -> Correct value

}

Python Code:

dx = 38629

dy = (dx << 8)

print(dy) # 9889024 -> not the expected value

print(type(dx)) # <class 'int'>

print(type(dy)) # <class 'int'>

I cant seem to figure out a way to cast or similar function to get this into an Unsigned Int 16.\

Please help.

๐ŸŒ
TechBeamers
techbeamers.com โ€บ unsigned-integers-in-python
Enforcing Unsigned Integers in Python: A Complete Guide
November 30, 2025 - Python does not have built-in unsigned integers, unlike C, C++, or Java.
๐ŸŒ
DaniWeb
daniweb.com โ€บ programming โ€บ software-development โ€บ threads โ€บ 359675 โ€บ signed-and-unsigned-int-in-python
Signed and Unsigned int in python [SOLVED] | DaniWeb
A signed integer just uses one of the bits as a sign, so an 8 bit unsigned can store 0-->255, and an 8 bit signed -127-->127 because one bit is used as a sign. There is bitstring, bitbuffer and bitarray, Also, check PyPi for existing packages whenever you run into a problem like this . ... In Python integers have a size only limited by your computer's memory.
Find elsewhere
๐ŸŒ
Kristrev
kristrev.github.io โ€บ programming โ€บ 2013 โ€บ 06 โ€บ 28 โ€บ unsigned-integeres-and-python
Unsigned integers and Python
June 28, 2013 - The easiest (and portable!) way to get unsigned integers in Python is to import the required types from the ctypes module. However, sometimes you need to convert Pythons โ€˜normalโ€™ integers to unsigned values.
๐ŸŒ
IncludeHelp
includehelp.com โ€บ python โ€บ signed-and-unsigned-integer-arrays-in-python.aspx
Signed and Unsigned Integer Arrays in Python
May 3, 2025 - To declare an "array" in Python, ... alphabet "i") and it contains negative and posited integers. Unsigned Integer is defined by using type_code "I" (Capital alphabet "I") and it contains only positive integers....
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ c-api โ€บ long.html
Integer Objects โ€” Python 3.14.3 documentation
February 24, 2026 - CPython implementation detail: CPython keeps an array of integer objects for all integers between -5 and 256. When you create an int in that range you actually just get back a reference to the existing object. PyObject *PyLong_FromUnsignedLong(unsigned long v)ยถ
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ unsigned string to signed integer?
r/learnpython on Reddit: Unsigned String to Signed Integer?
November 14, 2023 -

I have a string (list member) that's being received as 65520, for instance. However this value is being received from a register that's a regular INT 2's complement representation. So really it's -16 in disguise. Obviously that's a problem on the sending side, when it does the INT to ASCII it should just encode it as -16, but it doesn't/can't.

When I read this value into an INT it of course reads the INT as 65520 since it has no way of knowing the original representation. Is there a way to force the ASCII to INT conversion to interpret the string value as a signed INT? So that input string = 65520 outputs INT = -16?

๐ŸŒ
Readthedocs
mypyc.readthedocs.io โ€บ en โ€บ latest โ€บ int_operations.html
Native integer operations - mypyc 1.20.0+dev.1abbafd4d0edb4ba116995b8aafd3d1556ee3ece documentation
Signed native integer types should only be used if all possible values are small enough for the type. For this reason, the arbitrary-precision int type is recommended for signed values unless the performance of integer operations is critical. Operations on unsigned integers (u8) wrap around ...
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ stable โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v2.4 Manual
There are 5 basic numerical types representing booleans (bool), integers (int), unsigned integers (uint) floating point (float) and complex. A basic numerical type name combined with a numeric bitsize defines a concrete type. The bitsize is the number of bits that are needed to represent a single value in memory.
๐ŸŒ
Python
mail.python.org โ€บ pipermail โ€บ tutor โ€บ 2004-January โ€บ 027693.html
[Tutor] difference between signed integers and unsigned integers
September 5, 2013 - Thus a 16 bit signed integer only has 15 bits for data whereas a 16 bit unsigned integer has all 16 bits available. This means unsigned integers can have a value twice as high as signed integers (but only positive values). On 16 bit computers this was significant, since it translates to the difference between a maximum value of ~32,000 or ~65,000.