Hexadecimal, Octal, and Binary Notation

As described earlier in this chapter, Python integers can be coded in hexadecimal, octal, and binary notation, in addition to the normal base 10 decimal coding. The coding rules were laid out at the start of this chapter; let’s look at some live examples here.

Keep in mind that these literals are simply an alternative syntax for specifying the value of an integer object. For example, the following literals coded in Python 3.0 or 2.6 produce normal integers with the specified values in all three bases:

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

>>> 0o1, 0o20, 0o377           # Octal literals
(1, 16, 255)
>>> 0x01, 0x10, 0xFF           # Hex literals
(1, 16, 255)
>>> 0b1, 0b10000, 0b11111111   # Binary literals
(1, 16, 255)

Here, the octal value 0o377, the hex value 0xFF, and the binary value 0b11111111 are all decimal 255. Python prints in decimal (base 10) by default but provides built-in functions that allow you to convert integers to other bases’ digit strings:

>>> oct(64), hex(64), bin(64)
('0100', '0x40', '0b1000000')

The oct function converts decimal to octal, hex to hexadecimal, and bin to binary. To go the other way, the built-in int function converts a string of digits to an integer, and an optional second argument lets you specify the numeric base:

>>> int('64'), int('100', 8), int('40', 16), int('1000000', 2)
(64, 64, 64, 64)

>>> int('0x40', 16), int('0b1000000', 2)    # Literals okay too
(64, 64)

The eval function, which you’ll meet later in this book, treats strings as though they were Python code. Therefore, it has a similar effect (but usually runs more slowly—it actually compiles and runs the string as a piece of a program, and it assumes you can trust the source of the string being run; a clever user might be able to submit a string that deletes files on your machine!):

>>> eval('64'), eval('0o100'), eval('0x40'), eval('0b1000000')
(64, 64, 64, 64)

Finally, you can also convert integers to octal and hexadecimal strings with string formatting method calls and expressions:

>>> '{0:o}, {1:x}, {2:b}'.format(64, 64, 64)
'100, 40, 1000000'

>>> '%o, %x, %X' % (64, 255, 255)
'100, ff, FF'

String formatting is covered in more detail in Chapter 7.

Two notes before moving on. First, Python 2.6 users should remember that you can code octals with simply a leading zero, the original octal format in Python:

>>> 0o1, 0o20, 0o377     # New octal format in 2.6 (same as 3.0)
(1, 16, 255)
>>> 01, 020, 0377        # Old octal literals in 2.6 (and earlier)
(1, 16, 255)

In 3.0, the syntax in the second of these examples generates an error. Even though it’s not an error in 2.6, be careful not to begin a string of digits with a leading zero unless you really mean to code an octal value. Python 2.6 will treat it as base 8, which may not work as you’d expect—010 is always decimal 8 in 2.6, not decimal 10 (despite what you may or may not think!). This, along with symmetry with the hex and binary forms, is why the octal format was changed in 3.0—you must use 0o010 in 3.0, and probably should in 2.6.

Secondly, note that these literals can produce arbitrarily long integers. The following, for instance, creates an integer with hex notation and then displays it first in decimal and then in octal and binary with converters (run in 2.6 here to reveal the long precision):

>>> X = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF
>>> X
5192296858534827628530496329220095L
>>> oct(X)
'017777777777777777777777777777777777777L'
>>> bin(X)
'0b1111111111111111111111111111111111111111111111111111111111 ...and so on...

Speaking of binary digits, the next section shows tools for processing individual bits.