Numeric Types ============= .. toctree:: :maxdepth: 1 Indices and tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` Definition ---------- Python provides 4 first-class types for dealing with numbers. .. _section_heading-Integer: Integer ------- **MUTABILITY:** Immutable In Python, the size of an integer is only limited by available memory. Negative integer values are represented in 2's complement. Python provides a rich set of methods to create integer values: Simple base-10 literals can be created as follows: >>> foo = 1234 >>> foo 1234 Binary, octal and hex literals can be created using the appropriate prefix (``0b``, ``0o`` and ``0x``): >>> foo = 0b11001 >>> foo 25 >>> foo = 0o173 >>> foo 123 >>> foo = 0x1F4 >>> foo 500 Negative literal values can be created just by appending a ``-``: >>> foo = -1234 >>> foo -1234 >>> foo = -0b11001 >>> foo -25 >>> foo = -0o173 >>> foo -123 >>> foo = -0x1F4 -500 .. note:: Python doesn't display in 2's complement for negative numbers. This is because integers have arbitrary precision and showing the sign bit of a 2's complement number would be an infinitely long string of 1s (well, until its memory was exhausted). Just to prove Python is actually using 2's complement for negative numbers, we can do a little test using the 1's complement (invert) operator ``~``: >>> foo = -0b11001 >>> foo -25 # 0b100111 in 2's complement notation >>> ~foo 24 # 0b011000 See, no one was lying to you :) Integer values can also be made using the :py:class:`int` constructor which has the following signature: .. py:function:: int(x, [baseN]) :param x: The value to convert (coerce) to an integer. Optional sign bit. Valid digits are 0-9, A-Z (digits must be valid for the radix chosen by baseN). :param base: The radix of 'x'. Can be from 2 to 36. Defaults to base-10. This is commonly used when creating an integer from a string or float (as a type conversion function), or when using a non-standard base. For example: >>> foo = int('23') >>> foo 23 >>> foo = int(141.5) >>> foo 141 >>> foo = int('-Z5', 36) >>> foo -1265 >>> foo = int('0b11', 2) >>> foo 3 >>> foo = int('0o174', 8) >>> foo 124 >>> foo = int('0xDEADBEAF', 16) >>> foo 3735928495 The :py:func:`bin`, :py:func:`oct` and :py:func:`hex` functions can be used to convert from an integer to a binary, octal and hexadecimal *string*, respectively. For example: >>> foo = bin(5025124513) >>> foo '0b100101011100001010101000010100001' >>> foo = bin(-5025124513) >>> foo >>> '-0b100101011100001010101000010100001' >>> foo = oct(5025124513) >>> foo '0o45341250241' >>> foo = oct(-5025124513) >>> foo '-0o45341250241' >>> foo = hex(5025124513) >>> foo '0x12b8550a1' >>> foo = hex(-5025124513) >>> foo '-0x12b8550a1' You can get the number of bits required to represent an integer value using :py:func:`bit_length`. For example: >>> foo = 0x5025124513 >>> foo.bit_length() 39 If required, you can convert integer objects to/from byte arrays using the :py:meth:`int.to_bytes` and :py:meth:`int.from_bytes` functions which have the following signatures: .. py:function:: int.to_bytes(length, byteorder, *, signed=False) :param length: The number of bytes to use to represent the integer. :param byteorder: The endianness. One of 'big' or 'little'. :param signed: If True, 2s-complement is used to represent the integer. .. py:classmethod:: int.from_bytes(bytes, byteorder, *, signed=False) :param bytes: The array of bytes to convert to an integer. :param byteorder: The endianness. One of 'big' or 'little'. :param signed: If True, 2s-complement is used to represent the integer. An example will help visualize their use: >>> foo = 255 >>> foo.to_bytes(4, 'big') b'\x00\x00\x00\xff' >>> foo.to_bytes(4, 'little') b'\xff\x00\x00\x00' >>> foo = b'\xff\x00\x00\x00' >>> int.from_bytes(foo, 'little') 4278190080 >>> int.from_bytes(foo, 'little', signed=True) -16777216 .. _section_heading-Boolean: Boolean ------- **MUTABILITY:** Immutable Python defines 2 objects, that can be used to indicate truthness, :py:obj:`True` and :py:obj:`False`. Like :py:obj:`None`, there is only one object that has each of these values. Anywhere you can use use :py:obj:`True` and :py:obj:`False`, you can also use 1 and 0 for, respectivly. However, you really should use the :py:obj:`True` and :py:obj:`False` objects when a boolean is required (for one, it's easier to read). Python lets you convert other values to booleans to test their truthness using the :py:func:`bool` function. Specifically, the following values are considered false: * :py:obj:`None` * :py:obj:`False` * zero for any numeric type (ints, floats, complex) * an empty sequence (strings, tuples, lists) * an empty mapping (dictionaries) * instance of user-defined classes that has :py:func:`__bool__` or :py:func:`__len__` defined and it returns 0 or :py:obj:`False`. That can be a handy way to test for an empty sequence or mapping. For example: >>> bool('') False >>> bool('Hello World') True >>> bool([]) False >>> bool([1]) True .. _section_heading-Float: Float ----- **MUTABILITY:** Immutable Python implements double-precision floating points numbers. There is no support for single-precision numbers because the speed-up in using single-precision is much less than the overhead of using objects so there is no advantage. The :py:mod:`sys` package contains a function for learning about float objects in the Python implementation you are using: >>> import sys >>> sys.float_info sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1) You can call ``help(sys.float_info)`` for details on the meaning of each attribute. One attribute of note is epsilon, which gives the smallest difference between 2 floating point numbers that can be represented. If you need even greater precision that what is afforded with floats, :py:class:`decimal.Decimal` provides even greater, user-selectable precision (defaulting to 28 decimal places) at the cost of being slower. However, this package will not be covered in this course. Float literals can be constructed from numbers using a decimal point and/or an exponent: >>> foo = 1.41 >>> foo 1.41 >>> foo = -294.1351 >>> foo -294.1351 >>> foo = 6.67408e-11 >>> foo 6.67408e-11 >>> foo = 3E20 >>> foo 3e20 .. note:: It is the decimal point that makes it a float. Otherwise, Python will treat it as an integer. Using the :py:class:`float` constructor, you can create floats from strings (as a type conversion function), numbers and the special values of infinity (``'inf'`` and ``'infinity'``) and not-a-number (``'nan'``): >>> foo = float(3.1415) >>> foo 3.1415 >>> foo = float('-1.7E40') >>> foo -1.7e+40 >>> foo = float('inf') >>> foo inf >>> foo = float('-inf') >>> foo -inf >>> foo = float('nan') >>> foo nan .. note:: The strings ``'inf'``, ``'infinity'`` and ``'nan'``, when fed to the :py:class:`float` constructor are not case sensitive. However, when printed they are always their short, lower-case versions. If you try and create a float value outside what can be represented, you will get a :py:exc:`OverflowError` exception. Like integers, floats have a few more tricks up their sleeves. You can convert a floating point number to a pair of integers where the ratio between the integers is exactly the same as the floating point value: >>> float.as_integer_ratio(234.5) (469, 2) >>> float.as_integer_ratio(141.13) (2485775888075981, 17592186044416) You can test whether a float is a finite integral value: >>> float.is_integer(4.0) True >>> float.is_integer(4.1) False Finally, you can move back and forth between hexadecimal *string* presentation and base-10 representation using the :py:meth:`float.hex` and :py:meth:`float.fromhex` functions: >>> float.hex(1.25) '0x1.4000000000000p+0' >>> float.fromhex('0xA.84p+0') .. note:: In hex notation, the exponent is specified using 'p', since 'e' is a valid hex character. .. _section_heading-Complex: Complex ------- **MUTABILITY:** Immutable Python implements complex numbers as a container that holds a pair of floats; one for the real part and the other for the imaginary part. The real and imaginary parts are separated by a +/-1j. Complex literals can be constructed from numbers in a couple of ways. For example: >>> foo = 100 + 10j >>> foo (100+10j) >>> foo = 1.4831 - 9.5213j >>> foo (1.4831-9.5213j) If you want to create a complex number with an imaginary value of 0, you can't exclude the imaginary component or you will accidentally create an integer or a float. There are 2 ways to solve this problem, the first being set the imaginary component 0j: >>> foo = 75 + 0j >>> foo (75+0j) Or, use the :py:class:`complex` constructor, which also acts like a type conversion function, and has the following syntax: .. py:function:: complex([real [, [imag]]) :param real: The real part of the complex number. Can be a numerical value or string. If a string, can also include the imaginary part. If not included, defaults to 0. :param image: The imaginary part of the number. Must be a numerical value. If not included, defaults to 0. For example: >>> foo = complex(75) >>> foo (75+0j) >>> foo = complex("23-88.3j") >>> foo (23-88.3j) .. warning:: The string format does not support whitespace around the sign. The real and imaginary parts of a complex number can be extracted using the :py:attr:`~complex.real` and :py:attr:`~complex.imag` attributes. For example: >>> foo = 3.1415-2.45j >>> foo.real 3.1415 >>> foo.imag -2.45 Finally, Python supports computing the conjugate or a complex number using the :py:meth:`~complex.conjugate` method. For example: >>> foo = 3.1415-2.45j >>> foo.conjugate() (3.1415+2.45j) .. _section_heading-Numerical_Operations: Numerical Operations -------------------- Python supports the typical range of numeric operators that you see in other programming languages. .. _table-Python_Numeric_Operators: .. table:: Table of Python Numeric Operators +--------+-----------------------------------------+ | Op | Description | +========+=========================================+ | x + y | Sum of x and y | +--------+-----------------------------------------+ | x - y | Difference of x and y | +--------+-----------------------------------------+ | x * y | Product of x and y | +--------+-----------------------------------------+ | x / y | Quotient of x and y | +--------+-----------------------------------------+ | x // y | Quotient of x and y, floored | +--------+-----------------------------------------+ | x % y | Remainder of x / y | +--------+-----------------------------------------+ | x ** y | x raised to the power y | +--------+-----------------------------------------+ | -x | Negation of x | +--------+-----------------------------------------+ .. note:: One difference between Python 3.x and other languages (including Python 2.x) is that the ``/`` operator does not clip the result and return an integer like it does in other languages. Rather, it returns a float. To obtain the clipped/floored result common to other languages, use the ``//`` operator instead. For example: >>> 151 / 2 75.5 >>> 151 // 2 75 The built-in's module contains functions to support some common math operations, namely, :py:func:`abs` (absolute value) and :py:func:`pow` (power). Refer to the :py:mod:`math` module (for ordinary numbers) and the :py:mod:`cmath` module (for complex numbers) for additional math functions (e.g. power, log, trig, angular, hyperbolic functions and related constants.) Similar to numeric operators, Python also supports the typical range of bitwise operators:. .. _table-Python_Bitwise_Operators: .. table:: Table of Python Bitwise Operators +--------+-----------------------------------------+ | Op | Description | +========+=========================================+ | x << y | Bitwise shift left x by y bits | +--------+-----------------------------------------+ | x >> y | Bitwise shift right x by y bits | +--------+-----------------------------------------+ | x & y | Bitwise AND x with y | +--------+-----------------------------------------+ | x \| y | Bitwise OR x with y | +--------+-----------------------------------------+ | x ^ y | Bitwise XOR x with y | +--------+-----------------------------------------+ | ~x | Bitwise invert x (1-s compliment) | +--------+-----------------------------------------+ The bitwise math operators are only valid for integer types. All math operators (numeric and bitwise) support augmented assignment (``x += y``, ``x >>= y`` etc). .. tip:: In Python, augmented assignment is faster then the non-augmented version as Python only reads the variables once. Finally, it should be no surprise that Python supports the typical range of comparison operators: .. _table-Python_Comparison_Operators: .. table:: Table of Python Comparison Operators +--------+-----------------------------------------+ | Op | Description | +========+=========================================+ | x < y | Less-than comparator. | +--------+-----------------------------------------+ | x > y | Greater-than comparator. | +--------+-----------------------------------------+ | x <= y | Less-than-or-equal comparator. | +--------+-----------------------------------------+ | x >= y | Greater-than-or-equal comparator. | +--------+-----------------------------------------+ | x == y | Equal comparator. | +--------+-----------------------------------------+ | x != y | Not-equal comparator. | +--------+-----------------------------------------+ When performing math operations with mixed numeric types, Python expands the narrow type to the wider type to make them compatible for the operation. For example: an integer being widened to a float: >>> 5 + 11.3 16.3 Or, an integer being widened to complex: >>> 5 + 15-7.3j (20-7.3j) You can probably deduce the progression from narrowest to widest as the following: | integer | float | complex .. admonition:: Try it! :class: TryIt Try the following: * Create an integer from the base-4 value of 12. * Convert the value 47.3 to an integer. * Create 52 as a floating point number * Convert 255 to a boolean. * Create a complex number to represent 3+4i and compute its conjugate. * Add 2 and 3. What type is the sum? * Add 12 and 5.5. What type is the sum? * Add 4 and True. What type is the sum? * Get the value of 15.875 as an integer ratio. * Use the modulus operator to determine if 35 is an even number. * Find the hypotenuse of a right angle triangle with sides 3 and 4. * Multiple the value of 0b00110 by 4 using bitwise operators. * Compare 0b1100 to the value of 24 to confirm equality.