Select Page

# Python Numbers, Formatting Number, and built-in Functions: A Complete Guide

In this tutorial, you’ll learn 7 different very important concepts of Python:

1. Python Numbers, their types, operations, and many more
2. All the Arithmetic Operations supported in Python
3. All the Augmented Assignment Operations supported in Python
4. How Python handles the resultant object when you apply arithmetic operations on two different types of numbers at once
5. Type Casting and Type Conversion
6. Number formatting with string
7. Built-in mathematical functions or methods

This tutorial is a complete guide to Python numbers. Topics are discussed in detail and some are very rare to find online as of today (because Python 3.8 introduced many new scopes).

It is recommended that you get the basic idea of Python numbers from the previous tutorial 15 Data Types in Python – All in One. Although I’ll try to cover everything from scratch.

This tutorial is going to be a huge one. So grab a cup of coffee, turn on soft music in headphones, keep patience, and get started!

## Python Numbers – A Numerical Data Type

Python numbers consist of 3 different data types. They are:

1. int – Integers
2. float – Floating point numbers
3. complex – Complex numbers

All of these are immutable data types. That means, once they are created, they cannot be changed or modified. If you try to modify them, a new instance will be created.

int, float, and complex are 3 classes in Python. An instance of them is created when you assign one of these types of data to a variable.

### Integers in Python

Integers or ints are whole numbers. They can be positive, negative, or zero. But cannot contain a fraction value, scientific notation, or imaginary number. Integer numbers in Python can be of any length, you don’t need to declare any long type variable. An integer number cannot start with zero (0).

Here are a few examples of Python integers. Use the type( ) function to check their data type, and the id( ) function to check their allocated memory location.

This code of block written in a Bash consists of 3 different examples.

1. The first part shows 3 instances of Python integers. Their data type has been displayed using the type() function.
2. The second part shows that a decimal integer cannot start with a zero. To understand the error message properly, read the next section.
3. The last part shows that integers are immutable. That’s why when changing the value of the variable num3, the memory location has been changed, hence a new instance has been created instead of overriding the old one.

Python int includes all of the number systems. The decimal number system (base 10) is what we’re used to. But Binary, Octal, Hexadecimal are also supported. You can represent these number systems by placing appropriate prefixes before a number. The prefixes are:

Notice that each prefix starts with a zero followed by a lowercase or uppercase character that represents the number system. That’s why you can’t add a zero before decimal integer.

Binary, Octal, Decimal, Hexadecimal, all of the integers work the same way and support the same set of functionalities. But when you try to print any of them, by default the value is printed in decimal integer.

Now, a few questions may rise in your mind.

### How to convert any integer number to binary in Python?

The most general way to convert an integer number, i.e. binary, octal, decimal, or hexadecimal to binary, is to use the built-in function bin( ). Pass it a number in any base, and it will return the binary form of the number. Remember that the returned number is a binary string. So to apply any mathematical operation on it, you may convert it into a decimal integer. Read below to know how to do it.

### How to convert any integer number to octal in Python?

Use the built-in function oct( ), it’s the most general way.
It can convert any base number.
But again, the returned value is an octal string.

### How to convert any integer number to hexadecimal in Python?

Use the built-in hex() function.
The returned value is a hexadecimal string.
Remember that in hexadecimal, A=10, B=11, C=12, D=13, E=14, F=15.
The letters are not case sensitive. But Python returns in lowercase.

### How to convert binary, octal, or hexadecimal to decimal in Python?

Use the built-in function int(). The function takes 2 arguments, the first one is any number, but must be in a string format! The second one is the base of that number, but must be in decimal integer format! 2 for binary, 8 for octal, 10 for decimal, 16 for hexadecimal. The returned number is a decimal integer, not in string format like other functions. One extra feature of the int() function is that it’s not limited to only binary, octal, decimal, or hexadecimal. You can use any custom number system, just pass the base of it in the second argument. See the examples to understand it properly. If you’re familiar with number system theory, try justifying the outputs yourself!

### How to convert a float to binary, octal, or hexadecimal in Python?

There is no built-in function in Python to do it at a glance. But some third party modules can do it. However, there are 2 different methods of converting decimal to binary. One is the subtraction method, and the other one is the successive division method. Unfortunately, the successive division method does not work for float to binary conversion. And the subtraction method has some limitations. To get the proper answer to this question, follow the Floating Point Arithmetic: Issues and Limitations section.

### Float in Python

A float or floating-point number is the same as an integer, but it includes a decimal point. A float can be positive, negative, or zero. The number 5 is an integer, where 5.0 is a float, although both of them are equal. Python floats also include scientific notations, infinity, and Nan.

Python floats has been discussed in detail earlier here in Data Types in Python.

When working with Python numbers, you’ll use floats a lot. Here’s a few examples, notice carefully.

Floats are accurate up to 15 decimal points. Above that, either the decimal part gets truncated or the precision drops.

Two things to notice here:

1. A semicolon in Python helps to write multiple commands in one line. Python considers them to be written in different lines.
2. The len( ) function returns the length of an iterable, e.g. a string. So 19 in the last example starts counting from 0 up to 4 including the decimal point.

However, the precision can be increased and controlled using different modules like the decimal and the numpy modules.

In Scientific notation, a very big or very small number is represented as a power of 10. In Python, the letter e or E is used to represent it. Here’s some examples.

### NaN and infinity in Python

1. NaN – Stands for Not a Number. The term Undefined in mathematics is represented by this term. NaN is a numeric term, but it’s not a number. One example of NaN is float inf – inf. Although 0/0 is also undefined in mathematics, Python returns ZeroDivisionError instead of NaN.
2. inf or infinity – Stands for infinity in mathematics.

The use of these two can be a little bit confusing in Python. Note that both of them are case insensitive and can be represented in many different ways. To manually use Nan or inf, use the float( ) function and pass the value in string format.

There are 4 different ways of declaring infinity in Python:

1. Using the float() function and passing it a string format of inf, infinity (case insensitive)
2. Using Python’s math module
3. Using Python’s decimal module
4. using Python’s third-party numpy module

A module is an already written piece of code that either comes with your Python installation or you need to manually download it. To use the pre-made code of a module, import the module with the import command. Here’s a quick overview of modules.

Here’s a list of possible ways of declaring infinity in Python.

Notice that the numpy module or library is a third-party module. So you must download it manually. If you’ve installed Anaconda, then you already have it. Otherwise, for now, use the online compiler to execute the commands.

Here’s a list of possible ways of declaring NaN in Python:

There’re a few operations that can lead you to generate NaN values. Here’s a list.

### Floating Point Arithmetic: Issues and Limitations

What is the exact value of 1/3? Is it 0.3? Or 0.33? Or 0.33333333? The more 3’s you add, the more precise it gets. But it cannot be the exact answer. 1/3 + 1/3 + 1/3 = 1. But is 0.33 + 0.33 + 0.33 = 1? No! It’s 0.99! This is a limitation for floating point arithmetic. The same happens in binary floating points.

Computers or hardware store numbers as binary. If you’re familiar with conversion between number systems, remember that a number is represented as the sum of powers of the base. For example, to convert 42 decimal to binary:

42 = 0x27 + 0x26 + 1×25 + 0x24 + 1×23 + 0x22 + 1×21 + 0x20 = 00101010

And to convert a floating decimal to binary, the power of 2 will continue to decrease from left to right. For example, to convert 0.6875 from decimal float to binary float:

0.6875 = 1×2-1 + 0x2-2 + 1×2-3 + 1×2-4 = 0.1011

This is the best way of converting decimal to binary. But still, there are some numbers that you can’t convert accurately, just like the 1/3 example above. One such number is 1/10. Try this online converter to check its binary representation.

No matter how many 2-n you use, the number 1/10 cannot be represented accurately in binary. If you keep trying, this is what you’ll get:

``0.0001100110011001100110011001100110011001100110011...``

And if Python had to convert the true decimal value of what it stores as binary for 1/10, this is what you would get:

``````>>> 0.1
0.1000000000000000055511151231257827021181583404541015625``````

That’s why Python limits the number of digits it shows you and you get 0.1 as answer. But the problem occurs when you try to apply some arithmetic operations on them. For example, the line 0.1 + 0.2 == 0.3 should return True (‘==’ sign is used to check whether both sides are equal). But Python returns False!

``````>>> 0.1 + 0.2 == 0.3
False
>>> 0.1 + 0.2
0.30000000000000004``````

2 things to keep in mind for floating point arithmetic:

1. This limitation is not a bug for Python. This is the nature of Computers.
2. Most of the floating point numbers have this limitation.

If you’re still curious, read this official documentation by Python.

### Complex Numbers in Python

Complex numbers are written in the form x + yj, where x is the real part and y is the imaginary part. j is used to indicate the imaginary part. x and y both can be zero, but you must write the yj part as 0j. Both the real or imaginary parts can be either integers or floats. The presence of j indicates that a number is a complex number.

Python complex number supports 2 methods. One is .real which shows the real part of the complex number, other is .imag which shows the imaginary part.

Here are a few examples.

``````a = 3+5j
b = -2+10j
c = 3.14j
d = 2.97+0j
e = 1.68e-27 + 2.5j    # Space is allowed
f = 69 - 3.2e-10j
g = -10j

print(type(a), type(c), type(e), sep='\t')
print(b, d, g, sep='\t')  # Separate the values by a tab
print(f.real)    # Shows the real part of f
print(f.imag)   # Shows the imaginary part of f``````

Output:

``````<class 'complex'>   <class 'complex'>   <class 'complex'>
(-2+10j)    (2.97+0j)   (-0-10j)
69.0
-3.2e-10``````

Notice that Python treats both the real and imaginary part of a complex number as floats, even if you declare them as ints! Here’s the proof:

``````num = 6+7j
print(type(num.real))
print(type(num.imag))``````

Output:

``````<class 'float'>
<class 'float'>``````

Public Group

A group optimized for learning purposes. Track your progress by joining a unit

Public Space

Best place to ask questions! Join the built-in community to get help from others

## Arithmetic Operators in Python

Arithmetic operators help you to perform arithmetic calculations, commonly addition, subtraction, division, and multiplication. Python supports a few more arithmetic operations. Here’s a list of all the arithmetic operators in Python. Look below the table for individual explanations.

Addition (x + y): Adds two or more numbers. But the important thing to note here is that if at least one number is a float, then the resultant will be a float. And if at least one number is complex, then the resultant will be a complex number.

``````>>> 2+3
5
>>> 2+3.0
5.0
>>> 2 + (3-4j)
(5-4j)``````

Subtraction(x – y): Subtracts two or more numbers. If at least one of the numbers is a float, then the resultant will be a float. And if at least one number is complex, then the resultant will be a complex number.

``````>>> 2-3
-1
>>> 2.0-3
-1.0
>>> 2 - (3-4j)
(-1+4j)``````

Multiplication(x * y): Multiplies two or more numbers. If at least one of the numbers is a float, then the resultant will be a float. And if at least one number is a complex, then the resultant will be a complex number.

``````>>> 2*3
6
>>> 2*3.0
6.0
>>> 2 * (3-4j)
(6-8j)
>>> (3-4j) * (5+6j)
(39-2j)``````

Float Division(x / y): Divides two or more numbers. It is named as float division because it always returns a value in float data type. However, in the presence of a complex number, the resultant will be a complex number.

``````>>> 2/3
0.6666666666666666
>>> 10/2
5.0
>>> 1.8/3
0.6
>>> (3-4j)/2
(1.5-2j)``````

Integer Division(x // y): Divides two or more numbers. It is named as integer division because it always returns the integer part of the resultant. Even if the resultant has a fraction value, the integer division ignores that part. If at least one of the numbers is a float, then the resultant is a float, but the fraction part shows zero only. However, complex numbers do not support this operator.

``````>>> 10//3
3
>>> 10.0//3
3.0
>>> 10.0//2
5.0
>>> (3-4j)//2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't take floor of complex number.``````

Remainder (x % y): Returns the remainder in the division of (x // y). For example, 10//3=3 and remainder is one. So 10%3=1

``````>>> 10%3
1
>>> 10.0%3
1.0
>>> 10.5%3
1.5
>>> (3-4j)%2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't mod complex numbers.``````

Exponential(x ** y): Reads as x to the power y, or xy. That means, this operator raises y to be the power of x. Here, x and y can be integer, float, or complex. If at least one of the numbers is a float, then the resultant will be a float. And if at least one number is complex, then the resultant will be a complex number.

``````>>> 2**3
8
>>> 2.5**3
15.625
>>> 2**3.5
11.313708498984761
>>> (3-4j)**2
(-7-24j)
>>> 2**(3-4j)
(-7.461496614688569-2.885492725513448j)``````

## Augmented Assignment Operators in Python

Augmented assignment operators help to write shortcut assignment expressions. A single equal sign (=) is used to assign a value to a variable, hence, it’s an assignment operator. The arithmetic operators are used to perform some arithmetic operations. These are two different operations and sometimes may need two different lines of code. But you can combine them both and write in a single line, hence, it’s called the augmented assignment operator. For example, this is what you may usually do:

``````>>> count = 10
>>> count = count + 1  # increase the value by 1
>>> count
11``````

With the help of augmented assignment operator, you can shorten the second line.

``````>>> count = 10
>>> count += 1  # equals to count = count + 1
>>> count
11``````

In augmented assignment operators, the equal sign should always come after the arithmetic operator. For count+=1, it means, first increase the value of count by 1, and then assign it back to count. If you try the opposite, i.e. count=+1, then it means, first assign count to zero, then add 1 to it. Here’s an example:

``````>>> count = 10
>>> count =+ 1  # equals to count = 0; count += 1
>>> count
1``````

Here’s a list of all the augmented assignment operators in Python. Say, for each example, x=10

The augmented assignment operation performs a calculation on a variable and assigns the result to the same memory location, knows as in-place operation. Whereas, using assignment and arithmetic operation separately stores the result in a new memory location, even if the variable name stays the same. Although this in-place operation is valid only for most mutable objects like lists.

``````var1 = [1, 2]
print(id(var1))
var1 = var1 + [3]
print(id(var1), var1)

print()

var2 = [5, 6]
print(id(var2))
var2 += [7]
print(id(var2), var2)``````

Output:

``````139915272862912
139915272503232 [1, 2, 3]

139915272502528
139915272502528 [5, 6, 7]``````

When dealing with large data, for example in Data Science or Machine Learning, the in-place operation assigns the result to the same memory location as before. Thus your device doesn’t get out of memory for large data.

The augmented assignment operations are not always in-place. Read more to understand it properly.

## Type Casting and Type Conversion

Sometimes you may need to specify the type of a variable yourself, specially when you need a fixed type of data to complete your task. The process of specifying the type of a variable is called type casting.

Sometimes you may need to change the type of some data you’re working on. The process of changing one type of data to another is called type conversion.

Both of the topics are discussed separately, but they are actually the same. For each data type in Python, there is a constructor function with the same name of the data type, which helps in type casting and type conversion. Here are the ones for Python numbers.

• int( ): It can construct an integer data type from an integer, float, or a string that contains only a number. If it constructs from a float, then the fraction part is ignored. If it constructs from a string, then the string must contain only an integer value, a float is not supported. Additionally, a complex number is not supported in int( ).
``````>>> a = int(10)    # int from an int
>>> b = int(10.5)  # int from a float
>>> c = int('10')  # int from a string
>>> a;b;c
10
10
10
>>> d = int('10.5')  # the string must contain only an integer
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '10.5'
>>>
>>> d = int('10M')  # the string must contain only an integer
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '10M'
>>>
>>> d = int(3-4j)  # complex number is not supported
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert complex to int
``````
• float( ): It can construct a float data type from an integer, float, or a string. When converting from a string, it can be a string of either an integer value or a float value. However, converting from a complex is not allowed.
``````>>> float(10)      # from int to float
10.0
>>> float(10.5)    # from float to float
10.5
>>> float('10')    # from string that contains an integer value
10.0
>>> float('10.5')  # from string that contains a float value
10.5
>>>
>>> float('10.5M') # string cannot contain non-numeric value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '10.5M'
>>>
>>> float(3-4j)    # complex number is not supported
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float``````
• complex( ): It can construct a complex data type from an integer, float, string, or a complex value.
``````>>> complex(10)
(10+0j)
>>> complex(10.5)
(10.5+0j)
>>> complex(3-4j)
(3-4j)
>>> complex('3-4j')
(3-4j)``````

## Formatting Numbers with format() function and f-string

When storing numbers or displaying output, sometimes you might need to store or display it in a fixed format. For example, if a number is 12.3456789, then you might want to store or display it up to 2 decimal points, such as 12.34, hence, formatting it up to 2 decimal points.

There are a bunch of ways of formatting. Here I’ll discuss 2 different ways. One is the built-in format( ) function which is the most common. Another one is the f-string method, the most modern way of formatting (introduced in Python 3.6).

The concept of formatting in Python is known as string formatting. Because, no matter what process you follow to format a data, the output will always be a string. Let’s see a couple of examples. Don’t try to understand yet!

Using the format() method:

``````>>> money = 1234.56 * 1.5 * 0.05
>>> money
92.592
>>>
>>> print("Pay \$", format(money, "0.2f"), "to confirm your order")
Pay \$ 92.59 to confirm your order
>>> print("Pay \$"+ format(money, "0.2f"), "to confirm your order")
Pay \$92.59 to confirm your order
>>> type(format(92.592, "0.2f"))
<class 'str'>
>>> format(92.592, '0.1f')
'92.6'``````

To discuss the topic, I’ll follow the last example. You can then modify it depending on your use. Just remember, the returned value is always a string.

Using the f-string:

``````>>> money = 1234.56 * 1.5 * 0.05
>>> money
92.592
>>>
>>> print(f"Pay \${money:.2f} to confirm your order")
Pay \$92.59 to confirm your order
>>> f"{92.592: 0.2f}"  # Notice the space after the colon
' 92.59'
>>> f"{92.592:0.2f}"
'92.59'``````

How clean and easy it is! Notice that everything inside the curly braces has a special meaning, even if it’s a simple space after the colon.

### format() Function in Python

The format function takes 2 arguments. Its syntax is:

``format(value, format_specifier)``
• value: The number you want to format
• format_specifier: A string that specifies how the number should be formatted

According to the documentation on format( ) function, the format_specifier can be anything in this list:

``````[[fill]align][sign][#][0][width][,][.precision][type]
where, the options are
fill        ::=  any character
align       ::=  "<" | ">" | "=" | "^"
sign        ::=  "+" | "-" | " "
width       ::=  integer
precision   ::=  integer
type        ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" |
"g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
``````

If you don’t understand the list, skip it for now and get back to it after completing this section. Trust me, you’ll understand each and everything listed here!

### f-string in Python

A formatted string literal or f-string is a string literal that is prefixed with ‘f‘ or ‘F‘. Its syntax for numbers is as follows:

``````f"{value:format_specifier}"
F"{value:format_specifier}"``````

If you want the f-string to use as a replacement field, ignore the second part and use it like f”{value}”. More about it in string.

### Formatting Floating Point Numbers

The general format specifier for a floating point number:

``width.precision+f``
• width: Width of the number after formatting. It includes the entire number, even the decimal point.
• .precision: Precision of the floating part. That means, how many digits to include after the decimal point (.).
• f: Stands for float. It tells what type of number to show after formatting (although it’s still a string). This is known as type code.

A few things to notice when formatting floats.

• By default, all types of numbers are right-justified. That means, if the specified width is longer than the length of the value, then the output is right-justified with trailing whitespaces to fulfill the specified width.
• If the specified width is shorter than the length of the value, then formatting ignores the width and only follows the .precision value.

Example in format() function

``````>>> format(123.321, '10.2f')  # width 10, 2 digit precision, float data type
'    123.32'
>>> format(123.321, '8.2f')
'  123.32'
>>> format(123.321, '7.2f')  # Notice the length of the output
' 123.32'
>>> format(123.321, '6.2f')
'123.32'
>>> format(123.321, '5.2f')
'123.32'
>>> format(123.321, '4.2f')
'123.32'
>>> format(123.321, '.2f')   # Notice this one
'123.32'
>>> format(123.321, '-1.2f')
'123.32'
>>>
>>> print('Your account balance is:', format(123.321, '.2f')+'\$')

Example in f-string:

``````>>> f'{123.321:10.2f}'
'    123.32'
>>> f'{123.321:8.2f}'
'  123.32'
>>> f'{123.321:7.2f}'
' 123.32'
>>> f'{123.321:6.2f}'
'123.32'
>>> f'{123.321:3.2f}'
'123.32'
>>> f'{123.321:.2f}'
'123.32'
>>>
>>> print(f'Your account balance is {123.321:.2f}\$')

The width value is only used to neatly line up data in columns. Otherwise, just use .precision+f. Because, if the width is equal or less than the length of the value, then formatting will ignore width.

### Formatting Numbers in Scientific Notation

Scientific notation falls under the float data type. Just change the type code to E or e. Everything else works the same.

Example in format() function:

``````>>> format(663800000000, '8.2E')
'6.64E+11'
>>> format(663800000000, '9.2E')
' 6.64E+11'
>>> format(663800000000, '.2E')    # It returns in 'E'
'6.64E+11'
>>> format(663800000000, '.3e')    # It returns in 'e'
'6.638e+11'
>>> format(663800000000, 'e')
'6.638000e+11'
>>> format(0.000123, 'e')
'1.230000e-04'
>>> format(0.000123, '.2e')
'1.23e-04'``````

Example in f-string:

``````>>> f'{663800000000:8.2E}'
'6.64E+11'
>>> f'{663800000000:9.2E}'
' 6.64E+11'
>>> f'{663800000000:.2E}'
'6.64E+11'
>>> f'{663800000000:e}'
'6.638000e+11'
>>> f'{0.000123:e}'
'1.230000e-04'
>>> f'{0.000123:.2e}'
'1.23e-04'``````

Formatting in Scientific notation always puts the decimal point after one non-zero digit.

Now when you’re comfortable with formatting floating point numbers, check out this table:

Here are the examples:

``````>>> f'{123.456:e}'
'1.234560e+02'
>>> f'{123.456:E}'
'1.234560E+02'
>>> f'{123.456:f}'
'123.456000'
>>> f'{123.456:F}'
'123.456000'
>>>
>>> val1 = float('inf')
>>> val2 = float('nan')
>>> f'{val1:f}, {val2:f}'
'inf, nan'
>>> f'{val1:F}, {val2:F}'
'INF, NAN'``````

### Formatting Integers

Integers include decimal, binary, octal, and hexadecimal. Their corresponding type codes are:

Integers do not need any precision. So you can’t format like .2d.

Examples in format():

``````>>> format(12345, 'd')
'12345'
>>> format(12345, '10d')  # Here 10 is the width
'     12345'
>>> format(12345, 'b')
'11000000111001'
>>> format(12345, 'o')
'30071'
>>> format(999999999, 'x')
'3b9ac9ff'
>>> format(999999999, 'X')
'3B9AC9FF'
>>> format(1234, 'c')
'Ӓ'
>>> format(123, 'c')
'{'
>>> format(12345, 'c')
'〹'
>>> format(12345)  # No type means decimal by default
'12345'
>>> format(0xab12)  # No type means decimal by default
'43794'``````

Examples in f-string:

``````>>> f'{12345:d}'
'12345'
>>> f'{12345:10d}'  # Here 10 is the width
'     12345'
>>> f'{12345:b}'
'11000000111001'
>>> f'{12345:o}'
'30071'
>>> f'{9999999999:x}'
'2540be3ff'
>>> f'{9999999999:X}'
'2540BE3FF'
>>> f'{1234:c}'
'Ӓ'
>>> f'{321:c}'
'Ł'
>>> f'{420:c}'
'Ƥ'
>>> f'{12345}'  # No type means decimal by default
'12345'
>>> f'{0xab12}'  # No type means decimal by default
'43794'``````

Let’s see a few more examples in different bases other than 10.

``````>>> f'{0xabc:b}'  # Hex to binary
'101010111100'
>>> f'{0b11001011:c}'  # Binary to character
'Ë'
>>> f'{0o7264:d}'  # Octal to decimal
'3764'``````

### Inserting Commas

Reading large numbers can get easier if separated by commas. To include the comma separator in the format_specifier, type a comma before precision or after width.

Examples in format():

``````>>> format(123456789.12345, '20,.3f')  # width+comma+precision+type
'     123,456,789.123'
>>> format(123456789.12345, ',.3f')  # comma+precision+type
'123,456,789.123'
>>> format(123456789, ',d')  # comma+type
'123,456,789'
>>> format(123456789.1234, ',f')  # comma+type; default precision of f is 6
'123,456,789.123400'``````

Examples in f-string:

``````>>> f'{123456789.12345:20,.2f}'  # width+comma+precision+type
'      123,456,789.12'
>>> f'{123456789.12345:,.2f}'  # comma+precision+type
'123,456,789.12'
>>> f'{123456789:,d}'  # comma+type
'123,456,789'
>>> f'{123456789.1234:,f}'  # comma+type; default precision of f is 6
'123,456,789.123400'``````

### Formatting Numbers as Percentage

To format a number in percentage, use the % sign as format_specifier. Note that this formatting method falls under the floats section. AND when using % as a format specifier, you don’t need to use the type code f.

The percentage format specifier (%) multiplies the number by 100 and shows in float data type, followed by a percentage sign. By default, the precision is 6, but you can specify it too.

Example in format():

``````>>> format(0.542, '%')  # Default precision is 6
'54.200000%'
>>> format(100, '%')
'10000.000000%'
>>> format(0.36213, '.2%')    # Setting precision to 2
'36.21%'
>>> format(0.36213, '10.2%')  # Defining width to 10
'    36.21%'``````

Example in f-string:

``````>>> f'{0.542:%}'
'54.200000%'
>>> f'{42:%}'
'4200.000000%'
>>> f'{0.36213:.2%}'
'36.21%'
>>> f'{0.36213:10.2%}'
'    36.21%'``````

### Assigning Signs to Numbers

In case you want to show the sign of the number, here are a few available options.

• + : Indicates that a sign should be used for both positive and negative numbers
• : Indicates that a sign should be used only for a negative number (This is the default behavior)
• space : Indicates that a leading space should be used for positive numbers, and a minus sign for negative numbers

Example in format():

``````>>> format(123, '+')
'+123'
>>> format(-123.34, '+')
'-123.34'
>>> format(123, '-')
'123'
>>> format(-123.34, '-')
'-123.34'
>>> format(123, ' ')
' 123'
>>> format(-123.34, ' ')
'-123.34'``````

Example in f-string:

``````>>> f'{123:+}'
'+123'
>>> f'{-123.34:+}'
'-123.34'
>>> f'{123:-}'
'123'
>>> f'{-123.34:-}'
'-123.34'
>>> f'{123: }'
' 123'
>>> f'{-123.34: }'
'-123.34'``````

Notice the last 2 examples and understand why you shouldn’t use a space after the colon just to make your formatting look cleaner. Because it has a special meaning, right?

### Setting Alignment and fill

By default, formatting numbers and strings are printed right-justified. This alignment can be changed by the following options. Remember to use the alignment option before sign and width (is exists).

Example in format():

``````>>> format(123.456, '<10.2f')  # Alignment+width+precision+type
'123.46    '
>>> format(12345, '>10')  # Alignment+width
'     12345'
>>> format(12345, '^10')  # Alignment+width
'  12345   '
>>> format(12345, '+10')  # Without equal sign
'    +12345'
>>> format(12345, '=+10')  # With equal sign
'+    12345'
>>>
>>> format(12345, '*<10')  # Fill padding with *
'12345*****'
>>> format(12345, '0>10')  # Fill padding with 0
'0000012345'
>>> format(12345, '\$^10')  # Fill padding with \$
'\$\$12345\$\$\$'
>>> format(12345, '0=+10')  # Fill padding with 0
'+000012345'``````

Example in f-string:

``````>>> f'{123.456:<10.2f}'  # Alignment+width+precision+type
'123.46    '
>>> f'{12345:>10}'  # Alignment+width
'     12345'
>>> f'{12345:^10}'  # Alignment+width
'  12345   '
>>> f'{12345:+10}'  # Without equal sign
'    +12345'
>>> f'{12345:=+10}'  # With equal sign
'+    12345'
>>>
>>> f'{12345:*<10}'  # Fill padding with *
'12345*****'
>>> f'{12345:0>10}'  # Fill padding with 0
'0000012345'
>>> f'{12345:\$^10}'  # Fill padding with \$
'\$\$12345\$\$\$'
>>> f'{12345:0=+10}'  # Fill padding with 0
'+000012345'``````

### Grouping Numbers by Thousands using Underscores

When writing a large number, it becomes very tough to keep track of zeros. In mathematics, you use commas to separate thousands and hence can easily track the number. But in Python, you can only use commas by formatting the number into a string. To keep track of large numbers without changing its data type, Python 3.6 introduces underscores as the thousand separators. Here’s how it works.

``````>>> 10,000 - 10 # Can't use commas. Python treats it as 10-10; 0-10
(10, -10)
>>> 10_000 - 10 # Underscore helps here
9990
>>> 10_0_00_000 + 99 # You can add underscores anywhere you want
10000099
>>> 0b1011_1100_1011 + 0b101 # Any base is supported
3024``````

From Python 3.6, you can use underscores to format numbers as thousand separators, like commas as you’ve seen earlier. Any type of number and any base is supported.

For thousands separator in formatting:

Commas are placed after each 3 digits and only supported by ints and floats.

Underscores are placed after 3 digits for ints and floats, and after 4 digits for binary, octal, and hexadecimal.

Example in format():

``````>>> format(10000000, '_')
'10_000_000'
>>> format(0b10110011001, '_')
'1_433'
>>> format(1433 '_b')
'101_1001_1001'``````

Example in f-string:

``````>>> format(1433, '_b')
'101_1001_1001'
>>>
>>> f'{10000000:_}'
'10_000_000'
>>> f'{0b10110011001:_}'  # Output in decimal (default), and place '_' after each 3 digits
'1_433'
>>> f'{1433:_b}'  # Output in binary, and place '_' after each 4 digits
'101_1001_1001'``````

### “#” – Alternate form of Python numbers

The ‘#‘ option causes the alternate form to be used for conversion. Notice the examples above. When you want to use binary, octal, or hexadecimal, you use the prefix 0b, 0o, 0x respectively. But the formatted output does not include any prefix. In case you want to add the prefixes when converting decimals to other bases in formatting, use the ‘#‘ option.

Example in format():

``````>>> # Example without '#'
>>> format(54321, 'b')
'1101010000110001'
>>> format(54321, 'o')
'152061'
>>> format(54321, 'x')
'd431'
>>>
>>> # Example with '#'
>>> format(54321, '#b')
'0b1101010000110001'
>>> format(54321, '#o')
'0o152061'
>>> format(54321, '#x')
'0xd431'``````

Example in f-string:

``````>>> # Example without '#'
>>> f'{54321:b}'
'1101010000110001'
>>> f'{54321:o}'
'152061'
>>> f'{54321:x}'
'd431'
>>>
>>> # Example with '#'
>>> f'{54321:#b}'
'0b1101010000110001'
>>> f'{54321:#o}'
'0o152061'
>>> f'{54321:#x}'
'0xd431'``````

### Wrapping up Formatting Numbers

Remember the format_specifier option list? Now you understand it properly, don’t you? Here’s the list again for you.

The most important thing here is the first line. You must follow the sequence!

``````[[fill]align][sign][#][0][width][,][.precision][type]
where, the options are
fill        ::=  any character
align       ::=  "<" | ">" | "=" | "^"
sign        ::=  "+" | "-" | " "
width       ::=  integer
precision   ::=  integer
type        ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" |
"g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"``````

Last but not the least, let’s see a complete example following the sequence shown in the first line of the above list.

Example in format():

``````>>> format(123456.789, 'f')
'123456.789000'
>>> format(123456.789, '.2f')
'123456.79'
>>> format(123456.789, ',.2f')
'123,456.79'
>>> format(123456.789, '_.2f')
'123_456.79'
>>> format(123456.789, '10,.2f')
'123,456.79'
>>> format(123456.789, '20,.2f')
'          123,456.79'
>>> format(123456.789, '020,.2f')  # Fills the gap with zeros
'0,000,000,123,456.79'

>>> format(12345, '#20,b')  # Comma is only supported in decimal
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Cannot specify ',' with 'b'.

>>> format(12345, '#20_b')
' 0b11_0000_0011_1001'
>>> format(123456.789, '+#20,.2f')
'         +123,456.79'
>>> format(123456.789, '^+#20,.2f')
'    +123,456.79     '
>>> format(123456.789, '\$^+#20,.2f')
'\$\$\$\$+123,456.79\$\$\$\$\$'``````

Example in f-string:

``````>>> f'{123456.789:f}'
'123456.789000'
>>> f'{123456.789:.2f}'
'123456.79'
>>> f'{123456.789:,.2f}'
'123,456.79'
>>> f'{123456.789:_.2f}'
'123_456.79'
>>> f'{123456.789:10,.2f}'
'123,456.79'
>>> f'{123456.789:20,.2f}'
'          123,456.79'
>>> f'{123456.789:020,.2f}'
'0,000,000,123,456.79'

>>> f'{12345:#20,b}' # Comma is only supported in decimal
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Cannot specify ',' with 'b'.

>>> f'{12345:#20_b}'
' 0b11_0000_0011_1001'
>>> f'{123456.789:+#20,.2f}'
'         +123,456.79'
>>> f'{123456.789:^+#20,.2f}'
'    +123,456.79     '
>>> f'{123456.789:\$^+#20,.2f}'
'\$\$\$\$+123,456.79\$\$\$\$\$'``````

Public Group

A group optimized for learning purposes. Track your progress by joining a unit

Public Space

Best place to ask questions! Join the built-in community to get help from others

## Built-in Mathematical Functions in Python

There are a total of 69 built-in functions in Python as of version 3.8.5. A function is a reusable block of code that performs a specific task. You can create your own functions, but there are some functions that are very common in programming. So to make your life easy, Python developers have already written some most commonly used functions that you can use just by calling it and supplying appropriate arguments.

To use a function, call it by its name followed by parenthesis. A function needs some values to work on. These values are called arguments. To make your life even easier, Python developers set some common values as arguments, these are called default arguments. The ones you need to provide yourself are called keyword arguments. Here is an example:

``````print('Hello','World!')  # What you write
print('Hello', 'World!', sep=' ', end='\n', file=sys.stdout, flush=False)  # What it actually is``````

print( ) is a function that outputs values in the standard output. You usually give it the values to print, like ‘Hello’, and ‘World!’ in the example. These are keyword arguments. Python print( ) function needs a few more arguments to operate appropriately. sep contains the character to separate multiple objects (Here ‘Hello’ and ‘World!’). As almost every time you’ll use one whitespace, Python sets it by default for you. The same goes for all the other arguments. These are called default arguments. More about them in a future tutorial.

Python has a total of 15 built-in mathematical functions. They are:

Let’s discuss the one’s we haven’t discussed yet.

### abs() function – Absolute Value

The Python abs( ) function takes a number as an input and returns the absolute value of it. The argument or input can be an integer or float. But if it’s a complex number, then abs( ) returns the magnitude of it. In mathematics, the magnitude of a complex number a + bj is the square root of (a2 + b2). However, an absolute value means how big or small a number is compared to zero. Hence, absolute values are always positive.

``````>>> abs(5)
5
>>> abs(-5)
5
>>> abs(10.3)
10.3
>>> abs(-10.3)
10.3
>>> abs(2+3j)
3.605551275463989
>>> (2**2+3**2)**.5  # 2**2 means 2 to the power 2
3.605551275463989
>>> abs(2+3j) == (2**2+3**2)**.5
True``````

### max() function – Find The Maximum

The max( ) function in Python finds the maximum value from an iterable or from 2 or more arguments.

An iterable means any data type that can contain multiple values in one variable and can be indexed. For example, string(can contain multiple alphabets), list, dictionary, set, etc. Read the 15 Data Types in Python to get an overall idea of each of them.

When you supply an iterator to the max( ) function as an argument; or 2 or more values as multiple arguments, it returns the maximum value.

• If the values are numbers, then the biggest number is returned.
• If the value is a string, max( ) converts each character into Unicode and returns the biggest one.
• If the values are 2 or more different strings, max( ) compares the first character of each argument to detects the biggest argument.

Notice the example to understand it properly.

When iterators are used:

``````>>> ord('a')  # Checking the Unicode first
97
>>> ord('g')
103
>>> max({'a':10, 'b':9, 'c':8})  # In dictionary, keys are compared
'c'
>>> max([1,5,7,3,9,0,6])
9
>>> max('abcdgfe')  # Each character is compared
'g'
``````

When multiple arguments are used:

``````>>> max(1,9,2,0,3,8,5,6)
9
>>> max('abc', 'def', 'agh')  # First character of each are compared
'def'
>>> max('abc', 'def', 'dfg')  # If firsts are equal, then second characters are compared
'dfg'``````

Note that if there are multiple maximum values, then the first one encountered is returned.

### min() function – Find The Minimum

The min( ) function in Python finds the minimum value from an iterable or from 2 or more arguments. It works the opposite of the max( ) function.

When iterators are used:

``````>>> min({'a':10, 'b':9, 'c':8})  # In dictionary, keys are compared
'a'
>>> min([1,5,7,3,9,0,6])
0
>>> min('abcdgfe')  # Each character is compared
'a'``````

When multiple arguments are used:

``````>>> min(1,9,2,0,3,8,5,6)
0
>>> min('abc', 'def', 'agh')
'abc'
>>> min('abc', 'def', 'aabc')
'aabc'``````

### pow() function – Raise to the Power

The pow(base, exp[, mod]) takes up to 3 arguments. base and exp are required arguments, which means these are the must. And mod is an optional argument. Although it’s commonly used to find the exponential of a base, it can perform different mathematical operations depending on the arguments. Note that all three arguments must be numeric values.

• When base and exp are given, the pow() function returns baseexp. This is the same as base**exp. Both raises exp to the power of base.
• When all base, exp, and mod are given, the function returns baseexp % mod. This is the same as (base ** exp) % mod, but computed more efficiently. When all three arguments are used, all of them must be integers.
• When exp is negative and mod is also given, the function returns baseexp % mod but calculated in modular arithmetic process.

Example 1:

``````>>> pow(2, 3)
8
>>> 2**3
8
>>> pow(2+3j, 4)
(-119-120j)
>>> (2+3j) ** 4
(-119-120j)
>>> pow(3.5, 4, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() 3rd argument not allowed unless all arguments are integers
>>> pow(3.5, 4)
150.0625
>>> pow(3.5, 4.2)
192.79056951583615``````

Example 2:

``````>>> pow(2,3,4)
0
>>> 2**3 % 4
0
>>> pow(5,7,3)
2
>>> 5**7 % 3
2
>>> pow(4,11,13)
10
>>> pow(4,11,2.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() 3rd argument not allowed unless all arguments are integers``````

Example 3: If you’re not familiar with modular multiplicative inverses from the number theory, read this Stack Overflow answers to understand what’s going on under the hood of the following examples.

``````>>> pow(38, -1, mod=97)
23
>>> 23 * 38 % 97 == 1    # This is what it really does
True
>>> pow(3, -1, 8)
3
>>> pow(10, -3, 42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: base is not invertible for the given modulus``````

Why did the last one returned an error? Notice the first and second examples.

When the pow( ) function computes the modulo of an inverse number, here 38-1 % 97, it actually tries to find a value d such that d * base % mod = 1. Where d can be anything from 0 to mod-1, i.e. in the range(97).

For the third example, you can’t find any whole number d that satisfies the condition d * base % mod = 1. That’s why this operation becomes invalid.

To check out the value of d manually, run this code and find out where it returns 1.

``````for i in range(97):
s = f"{i} * 38 % 97"
print(s, "==", eval(s))``````

### range() function – Generate a sequence of numbers

The range( ) function generates a sequence of integer numbers as a range object. Later it can be converted into any sequence types like list, tuple, and set types like set, frozenset. A range( ) function can take up to 3 arguments. One is a required argument and the other two are optional.

range([start,] stop [, step]):

• start: Starting number of the range. It is optional, default value is zero.
• stop: Where to stop the range. It is the only required argument.
• step: The step size of going from start to stop. In other words, the difference between every 2 elements in the sequence. This is optional. Default value is 1 or +1. step can’t be zero!

Note that the second argument is stop, and not end. Why?

The range() function starts from the start and goes up to stop, but excluding it. That means, the sequence ends before the stop value.

A few things to note here:

• All three arguments must be integers only
• If only one argument value is passed, it goes to stop
• If two arguments are passed, the first one goes to start, and the second one to stop
• If all three arguments are passed, they go to start, stop, step serially.
``````>>> range(0, 10, 1)
range(0, 10)
>>> type(range(0, 10))
<class 'range'>
>>> range(10)  # start=0, stop=10, step=1
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))      # star=0,stop=0,step=1; this cannot be done
[]
>>> list(range(1, 0))   # star=1,stop=0,step=1; cannot be done
[]
>>> list(range(10,1))   # star=10,stop=1,step=1; cannot be done
[]
>>> list(range(10,1,-1))
[10, 9, 8, 7, 6, 5, 4, 3, 2]``````

Here’s some example only for negative numbers which might get a little bit confusing.

``````>>> list(range(-10))    # star=0,stop=-10,step=1; this cannot be done
[]
>>> list(range(-10, -1))
[-10, -9, -8, -7, -6, -5, -4, -3, -2]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(-10, -10, -1))
[]
>>> list(range(10, -10, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9]``````

The advantage of the range() function or type over a regular list, tuple, or set is that a range object will always take the same (and small) amount of memory, no matter the size of the range it represents. Because it only stores the start, stop, and step values instead of storing every single element, and calculates the elements and sub-ranges as needed.

Range objects provide features like containment test (whether a value exists in the range), element index lookup (finding the index of an element), slicing (creating sub-ranges), and positive/negative indexing (finding value with both positive and negative indexing). Here are some examples:

``````>>> r = range(0, 20, 2)
>>> r
range(0, 20, 2)
>>> list(r)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> 13 in r      # containment test
False
>>> 6 in r
True
>>> r.index(14)  # element index lookup
7
>>> r[5]         # indexing
10
>>> r[:5]        # slicing
range(0, 10, 2)
>>> list(r[:5])
[0, 2, 4, 6, 8]
>>> r[-1]        # negative indexing
18
>>> r[-3]
14``````

### round() function – rounding a number

The round(number [, ndigits]) has two arguments, where number is required and ndigits is optional. It returns number rounded to ndigits precision after the decimal point. If ndigits is not provided or is None, then it returns an integer closest to the input number.

``````>>> round(3.6542, 2)
3.65
>>> round(3.14159265, 3)
3.142
>>> round(3.1449, 2)
3.14
>>> round(3.1450, 2)
3.15
>>> round(3.4)
3
>>> round(3.5)
4``````

round( ) in Python does not work the same as you might have learned in school. You might have learned the simple always round 0.5 up method. But this process is not efficient. There are lots of ways of rounding numbers. Python 3’s way (Called round half to even or “banker’s rounding“) is considered the standard rounding method these days. In this method, every .5 number is rounded to the nearest even digit.

For example, 2.5 can be rounded to 2 or 3. But as 2 is an even, it rounds down to 2. On the other hand, 1.5 can be rounded to 1 or 2. But as 2 is an even, it rounds up to 2. The same happens for 3.25 and 3.35 when rounding with ndigits = 1.

``````>>> round(1.5)
2
>>> round(2.5)
2
>>> round(3.5)
4
>>> round(4.5)
4
>>> round(-1.5)
-2
>>> round(-2.5)
-2
>>> round(-.5)
0
>>> round(.5)
0

>>> round(3.25,1)
3.2
>>> round(3.35,1)
3.4``````

You’ll see some floating-point numbers not following this rule. Even they behave differently for different values. For example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug. It’s a result of the fact that most floating-point numbers cannot be represented exactly in the binary number system when storing in hardware. Read Floating Point Arithmetic: Issues and Limitations above if you don’t remember.

``````>>> round(2.675, 2)
2.67
>>> round(3.15,1)  # Expected 3.2
3.1
>>> round(3.25,1)
3.2
>>> round(3.35,1)
3.4
>>> round(3.45,1)  # Expected 3.4
3.5
>>> round(3.55,1)  # Expected 3.6
3.5``````

### sum() function – Sum up the numbers of an iterable

The sum(iterable, start=0) function sums up the numbers of an iterable from left to right. Here, start is an optional argument. Consider this as total. The function sums every number to it. You can define a different start value and the sum( ) function will add the numbers from this start value. But this operation is only supported from Python 3.8.

``````>>> sum([1,2,3,4,5])
15
>>> sum([1,2,3,4,5], start=100)
115
>>> sum(range(10))
45
>>> sum(range(10), start=5)
50
>>> sum([1.5, 2.3, 3.1416, 6.675])
13.616599999999998``````

To add floating point values with extended precision, see math.fsum().

### len() function – Finds the length

The len(object) function measures the length of an object. The argument can be a sequence (such as string, bytes, tuples, list, or range), or a collection (such as dictionary, set, or frozenset), but it cannot be a number (such as int, float, complex, or boolean).

``````>>> len('Machine Learning Wiki')
21
>>> len(bytes('MLwiki', encoding='utf-8'))
6
>>> len((1,2,3,4,5))
5
>>> len([1,2,3,4,5])
5
>>> len(range(5))
5
>>> len({'a':1, 'b':2, 'c': 0})
3
>>> len({'a', 'b', 'c'})
3
>>> len(frozenset(['a', 'b', 'c']))
3
>>> len(frozenset({'a', 'b', 'c'}))
3``````

### bool() function – True or False

The bool(x) function returns either True or False depending on the value x. The bool( ) function returns True for every single value of x, except these values:

• x is left empty
• x = None, False, 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
• Empty sequence and collections: ‘ ‘, ( ), [ ], { }, set(), range(0)

Note that True equals 1 and False equals 0 mathematically.

``````>>> bool()
False
>>> bool(1)
True
>>> bool(-1)
True
>>> bool('text')
True

>>> bool(None)
False
>>> bool(False)
False
>>> bool(0)
False
>>> import decimal
>>> bool(decimal.Decimal(0))
False

>>> bool([])
False
>>> bool(range(0))
False

>>> True + True
2
>>> False + False
0
>>> True + False
1``````

### What’s Next?

Now you have a very good understanding of Python numbers. There are a number of modules and libraries that are dedicated to Python numbers to extend its scope. Those will be discussed after covering all the basics of Python. Here is a list of things you you should try next:

• Bookmark this tutorial so that you can get back to it whenever it’s necessary
• Share it with others. This encourages me!
• Go to Stack Overflow, search for ‘Python’, or ‘Python Numbers’, and answer the questions as many as you can. I expect 3 questions.
• Read the next tutorial to know about all the operators supported in Python. That will be a complete guide to operators.
• Read the tutorials on the following modules and libraries when they are released: math, decimal, random, and numpy

And if you didn’t, read earlier tutorials:

Mind Sharing It?