Back to Blog
Python

Python Hexadecimal Integer: Conversion and Formatting

python hexadecimal integer: Learn to convert between Python integers and hexadecimal strings, format hex output, and handle bitwise operations with practical examples.

pythonhexadecimalinteger-conversionbitwise-operationsformat-specifiers
Diagram showing conversion between a Python integer and its hexadecimal string representation.

When you need to work with a python hexadecimal integer, the built-in int() and hex() functions cover most cases. But the details of formatting, parsing, and bitwise operations often cause confusion. This article walks through the practical patterns and the edge cases that matter in real code.

Using int() to Parse Hexadecimal Strings

The most direct way to convert a hexadecimal string to an integer is to pass base=16 to int(). The function accepts an optional prefix 0x or 0X when the base is 16.

value = int("0xFF", 16) # 255 value_no_prefix = int("FF", 16) # 255

The prefix is optional. If you include it, Python ignores it. If you omit it, the string must contain only valid hexadecimal digits and an optional sign. For example, int("0x1A", 16) works, but int("0x1A", 10) raises a ValueError because 0x is not a valid decimal prefix.

When the input comes from user data or an external system, you often need to strip whitespace or handle an empty string. int() raises ValueError for an empty string, so validate the input before conversion if it might be empty.

Using hex() to Convert Integers to Hexadecimal

The hex() built-in returns a string that starts with 0x. For positive integers, the string contains lowercase digits. For negative integers, it returns a string like -0x....

hex(255) # '0xff' hex(-255) # '-0xff'

If you need uppercase digits, use format() or an f-string instead of hex(). The hex() function does not accept formatting options.

Formatting Hexadecimal with format() and f-strings

For more control over the output, use the format() function or f-strings. The format specifier x produces lowercase hex, X produces uppercase, and # adds the 0x prefix.

SpecifierExampleOutput
xf"{255:x}"ff
Xf"{255:X}"FF
#xf"{255:#x}"0xff
#Xf"{255:#X}"0xFF
08xf"{255:08x}"000000ff

You can combine width and zero-padding. For example, f"{value:08x}" pads the output to eight characters with leading zeros. This is useful when you need a fixed-length representation, such as for color codes or memory addresses.

Hexadecimal Literals in Source Code

Python source code can contain hexadecimal integer literals using the 0x prefix. You can also use underscores to separate groups of digits for readability.

mask = 0xFF00 large_mask = 0xFFFF_0000

These literals are integers at runtime. They behave exactly like decimal literals; the base only affects how the value is written in source code. This is useful when you are working with bit masks, network protocols, or memory layouts.

Bitwise Operations on Hexadecimal Integers

Because hexadecimal literals are just integers, you can use bitwise operators directly. This is common when manipulating flags or extracting fields from binary data.

status = 0b1101_0010 high_nibble = (status >> 4) & 0xF low_nibble = status & 0xF

The &, |, ^, <<, and >> operators work on the integer value. The hexadecimal representation is only a convenience for reading the code; the operations are performed on the underlying binary representation.

Handling Negative Numbers and Two's Complement

hex() returns a string with a leading minus sign for negative integers. This is not the same as a two's complement representation. If you need a fixed-width two's complement string, you must mask the value to the desired bit width.

value = -1 width = 8 two_complement = value & (2**width - 1) hex_string = f"{two_complement:0{width//4}X}" # 'FF'

This is common when working with hardware registers or binary protocols that expect unsigned values. The mask operation converts the negative integer to its unsigned equivalent within the given bit width.

Performance and Maintainability Considerations

For typical conversions, int() and hex() are efficient and clear. Avoid reimplementing conversion logic with loops or string manipulation; the built-ins are optimized and less error-prone.

When you need to format many values, f-strings are more readable than repeated format() calls. For bulk parsing, consider using bytes.fromhex() if you are working with raw bytes, but int(..., 16) is the right choice for a single integer.

Maintainability matters when the code is read by others. Use hexadecimal literals for constants that represent bit patterns, and document the meaning of each mask. A well-named constant like READ_FLAG = 0x01 is clearer than a raw number.

Edge Cases: Large Numbers and Arbitrary Precision

Python integers have arbitrary precision, so you can convert very large hexadecimal strings without overflow. For example:

big = int("FFFFFFFFFFFFFFFF", 16) # 18446744073709551615

This is not limited to 32 or 64 bits. The conversion cost scales with the number of digits, but it remains linear and is acceptable for typical inputs. If you are parsing megabytes of hex data, consider streaming or chunking, but for ordinary use, the built-in functions are sufficient.

python hexadecimal integer: Practical Usage and Code Example | RYUSLOG DEV