Numbers are an integral part of programming. Hence, programming languages support various datatypes to represent different kinds of numbers and provide various methods to work with them.
Each of these datatypes comes with certain limitations on the range of numbers they can represent; while some can represent a small range of numbers, others support a very large range of numbers. Depending on our use case, we can choose from one of them.
But none of them have a way to represent infinity.
We often encounter and have to deal with infinity in many real-world scenarios, and so we need a way to represent them in programming languages.
In this tutorial, we’ll learn how to represent and work with infinity in Python.
What is Infinity?
Before diving into the programming know-how of working with infinity, let us first understand what infinity is, by formally defining it
There are dozens of definitions of infinity depending on its usage in different contexts and domains. We’ll focus on the ones that are used in mathematics and computing.
Infinity is defined as a large, ‘undefined’ number that is bigger than any real number.
It exists on both ends of the number line, and hence we have both positive and negative infinities.
Infinity is denoted using the symbol ∞.
In Computer Science, it is also defined as a result of an ‘undefined operation’ such as division by zero. In programming, infinity is used to define an absolute max/min value in algorithms defined for optimizations.
For eg. in algorithms for finding the shortest path between two nodes of a graph, the initial value for shortest_path_distance can be set to infinity.
Declaring Infinity
There exist a number of different ways to represent infinity in Python. Let us look at a few of them.
We can declare infinity as a floating-point number, by passing the string value ‘inf’ or ‘infinity’ to the method float
.
a = float("inf") print(f"value of a = {a}") print(f"type of a = {type(a)}")
Output:
As we discussed, there also exists ‘negative infinity’. We can declare the same by passing ‘-inf’, or by creating positive infinity, and prefixing it with ‘-‘ sign.
b = float("-inf") print(f"value of b = {b}") print(f"value of -float('inf') = {-float('inf')}")
Output:
Note that the string that we pass to the float
method is case-independent. So passing “INF” or “inFINIty” would also be correctly evaluated to inf
.
We can also use Python’s math
module to represent infinity.
The module has predefined value math.inf
that can be assigned to variables to represent infinity.
import math c = math.inf d = -math.inf #negative inf print(f"value of c is {c}") print(f"value of d is {d}") print(f"type of c = {type(c)}")
Output:
It turns out the math module also defines infinity as a floating-point number and apparently, the infinities declared by the two methods are equivalent.
Let’s check it out.
float_inf = float("inf") math_inf = math.inf print(f"float_inf == math.inf is {float_inf == math.inf}")
Output:
So these were just two different ways of representing the same value i.e inf
.
Why the infinity is float type?
You must be wondering why the infinity is not int
type, and if it’s an undefined number how does its datatype matter?
The answer lies in the way the numbers are represented in Python.
An integer number is represented using its binary representation, for eg. 5 is represented as 0101.
The floating-point numbers, on the other hand, are represented using 3 components – sign, mantissa, and exponent. This is as per the IEEE 754 standard for storing floating-point numbers.
The IEEE 754 standard reserves some values to represent special numbers. One of these special numbers is infinity.
According to this standard, a floating-point number represents an infinity when all the bits in the exponent part are 1, and all the bits in the mantissa part are 0.
Additionally, if the sign bit is 0, it is positive infinity, while a 1 in the sign bit denotes a negative infinity.
So, since infinity is a special value that cannot be represented using simple binary representation, hence its datatype is float in Python.
Arithmetic Operations on infinity
Since infinity is a floating-point number, we can perform various arithmetic operations on it, and the results of such operations are also defined by the IEEE standard.
Addition
If we add any finite real number to infinity, the result will be infinity.
If we add infinity to infinity, the result will again be an infinity.
However, if we add a negative infinity to positive infinity, the result will be undefined or NaN
(Not a Number). NaN
is another special number like infinity that is represented in Python using float
datatype, as per IEEE 754 standard.
inf = float("infinity") print(f"inf + 100 = {inf + 100}") print(f"inf + 0.52 = {inf + 0.52}") print(f"inf + inf = {inf + inf}") print(f"-inf + inf = {-inf + inf}")
Output:
Subtraction
Subtracting a positive, real number from infinity yields infinity.
Subtracting infinity from any positive, real number returns negative infinity.
Subtracting infinity from infinity results in an undefined result i.e NaN
(as was observed in the previous section).
Subtracting infinity from negative infinity gives negative infinity.
print(f"inf - 50 = {inf - 50}") print(f"299.9 - inf = {299.9 - inf}") print(f"inf - inf = {inf - inf}") print(f"-inf - inf = {-inf - inf}")
Output:
Multiplication
The multiplication of any positive number with infinity gives infinity as the result.
Multiplying infinity by another infinity also results in infinity.
Multiplying infinity by zero is undefined, it returns NaN
.
Multiplying infinity by negative infinity, or any negative number, yields negative infinity.
print(f"inf * 1000 = {inf * 1000}") print(f"inf * inf = {inf * inf}") print(f"inf * (-inf) = {inf * (-inf)}") print(f"inf * 0 = {inf * 0}") print(f"inf * 0.5 = {inf * 0.5}")
Output:
Division
Dividing infinity by any positive or negative number returns positive or negative infinity, respectively.
Dividing infinity by itself, or by negative infinity returns a NaN
.
Dividing any finite number by infinity results in 0 or −0.
Finally, dividing infinity by 0 results in ‘ZeroDivisonError’
print(f"inf / 20 = {inf / 20}") print(f"-inf / 34 = {-inf / 34}") print(f"inf / inf = {inf / inf}") print(f"inf / -inf = {inf / -inf}") print(f"99 / -inf = {99 / -inf}") print(f"0 / inf = {0 / inf}")
Output:
Note that while doing the decimal division of infinity by any number results in infinity; doing floor division, however, results in NaN
.
print(f"inf // 20 = {inf // 20}")
Output:
Modulo operation
The modulo operation on two numbers returns the remainder when integer division is performed between the two.
The behavior of modulo operation on infinity is a bit weird.
While modulo of infinity(both positive & negative) with any number (positive, negative, infinity) yields NaN
, modulo of a real number with +infinity, however, returns that number.
Modulo of real number with -infinity, on the other hand, gives -infinity as the result.
print(f" 67 % 5 = {67 % 5}") print(f"inf % 20 = {inf % 20}") print(f"-inf % 34 = {-inf % 34}") print(f"inf % inf = {inf % inf}") print(f"inf % -inf = {inf % -inf}") print(f"99 % inf = {99 % inf}") print(f"99 % -inf = {99 % -inf}") print(f"0 % inf = {0 % inf}")
Output:
NumPy infinity
In addition to the math
module, and the float
method, an infinity can also be assigned using NumPy‘s np.inf
constant.
NumPy also follows IEEE 754 standard for storing floating-point numbers, and so the value of np.inf
is equal to float("inf")
and math.inf
. The datatype of np.inf
is also float.
NumPy’s infinity constant can also be accessed using several aliases such as np.Infinity
, np.Inf
, and np.infty
.
NumPy also defines separate constants for positive and negative infinities. Positive infinity can be accessed using np.PINF
(alias for np.inf), and the negative infinity can be accessed using the constant np.NINF
.
import numpy as np import math a = np.inf print(f"value of a = {a}") print(f"np.inf == float('Infinity') evaluates to {np.inf == float('Infinity')}") print(f"np.inf == math.inf evaluates to {np.inf == math.inf}") print(f"dataype of np.inf is {type(np.inf)}") print(f"np.PINF evaluates to {np.PINF}") print(f"np.NINF evaluates to {np.NINF}") print(f"np.PINF is np.inf evaluates to {np.PINF is np.inf}") #alias check
Output:
NumPy also has methods to find out whether a value is an infinity or not. It also has separate methods to check if the value is positive or negative infinity.
b = np.inf print(f"b = {b}") print(f"np.isinf(b): {np.isinf(b)}") print(f"np.isposinf(b): {np.isposinf(b)}") print(f"np.isneginf(b): {np.isneginf(b)}") c = np.NINF print(f"\nc = {c}") print(f"np.isneginf(c): {np.isneginf(c)}")
Output:
Note that we can also pass NumPy arrays to these methods; it will return an array of boolean values, denoting positions in the array where the value is infinity.
x = np.array([1,8, float("inf"), 10, 99, -math.inf]).reshape((2,3)) print(f"x:\n {x}\n") print(f"np.isinf(x):\n{np.isinf(x)}\n") print(f"np.isneginf(x):\n{np.isneginf(x)}\n") print(f"np.isposinf(x):\n{np.isposinf(x)}\n")
Output:
The math
module also has an isinf
method, though it doesn’t have methods to check positive or negative infinity like np.isposinf
and np.isneginf
.
Conversely, NumPy also has a method called np.isfinite
to check if the value is finite or not.
Maximum value for infinity
We have discussed that infinity is a ‘large, undefined number’ that is larger than any finite number.
But there are limitations in a computer on the maximum value a variable can store. We cannot declare any large value, and compare it with infinity.
In Python, there is a value between 1e+308 and 1e+309 that is the maximum value that a float variable can store. The exact value can be found using the attribute sys.float_info
.
This displays the various properties of the floating-point datatype on that computer, including the maximum value a float variable can store in Python.
Any value greater than this value is interpreted as infinity.
Similarly, on the negative end, any value below a certain minimum value is interpreted as negative infinity.
print(f"value of 1e+308 is {1e+308}") print(f"value of 1e+309 is {1e+309}") import sys print(f"\nfloat info: {sys.float_info}\n") print(f"value of 1.7976931348623157e+308 = {1.7976931348623157e+308}") print(f"value of 1.79769313486231585e+308 = {1.79769313486231585e+308}")
Output:
While we are at it, let us also discuss the behavior of the exponentiation (power) operator on infinity.
If we try to find any power(except 0) of infinity, or if we calculate the value of any number(except 1) raised to the power infinity, the result will be infinity.
However, if we perform an exponentiation operation using two finite numbers, and if the result exceeds the maximum allowed value, instead of returning infinity as the result, we get an ‘OverflowError’ with the message ‘Numerical result out of range’.
inf = np.inf print(f"10^inf = {10**inf}") print(f"inf^2 = {inf**2}\n") print(f"inf^0 = {inf**0}") print(f"inf^0.001 = {inf**0.001}\n") print(f"1^inf = {1**inf}") print(f"1.001^inf = {1.001**inf}\n") print(f"10.0^308 = {10.0**308}") print(f"10.0^309 = {10.0**309}")
Output:
Comparing Infinity
In this section, we will discuss the various comparison operations in Python involving infinity.
Any number is smaller than +inf
. Any number is greater than -inf
.
inf
is neither smaller nor greater than inf
>. It is equal to inf
, and not equal to -inf
.
inf = float("Inf") print(f"1000 < inf is {1000 < inf}") print(f"1000 > inf is {1000 > inf}") print(f"1000 > -inf is {1000 > -inf}") print(f"-1000 > -inf is {-1000 > -inf}") print(f"inf > inf is {inf > inf}") print(f"inf < inf is {inf < inf}") print(f"inf >= inf is {inf >= inf}") print(f"inf == inf is {inf == inf}") print(f"inf == -inf is {inf == -inf}") print(f"1e+309 < inf is {1e+309 < inf}") print(f"1e+309 == inf is {1e+309 == inf}")
Output:
Pass infinity as a command-line argument
When we run a python file from the command line, we can additionally pass any number of arguments we want.
These arguments can be accessed using sys.argv
.
sys.argv
contains a list of command-line arguments passed to the Python program. The first element in the list is the Python filename, and the remaining elements are the additional values passed (separated by a space) following the filename.
All the values in this list are stored as Python strings.
#cmd_args.py import sys print(f"arguments received from command line are: {sys.argv}\n") datatypes = [type(x) for x in sys.argv] print(f"type of each command line argument: {datatypes}")
Output:
Since all the command-line arguments are received as strings by default, if we want the arguments to be of a certain datatype (eg. float, int, etc.), we need to convert the string arguments into our desired datatype.
In this way, if the user needs to pass ‘infinity’ as one of the arguments, we can convert the same using the float
method, and store it in a variable.
Let us take an example where we expect 3 numeric command-line arguments, the first of which is an integer and the remaining ones are float.
#cmd_arg_inf.py import sys arguments = sys.argv[1:] x1 = int(arguments[0]) x2 = float(arguments[1]) max_val = float(arguments[2]) print(f"arguments received: x1={x1}, x2={x2}, max_val={max_val}")
Output:
Conclusion
In this tutorial, we understood what infinity is, how it is represented in memory using IEEE standard, and how to represent it and work with it in Python.
We began by defining infinity from mathematical and computing perspectives.
Then, we then discussed various ways of declaring infinity (and their equivalence) in Python.
We reasoned the need for defining infinity using float datatype by discussing the IEEE 754 standard for floating-point numbers.
We looked at various arithmetic operations that we can perform on infinity. While doing this, we discovered another special value called NaN
which is also stored as a float value in Python.
We looked at NumPy’s way of declaring infinity and worked with various methods in NumPy to check whether a value (or several values in a NumPy array) are infinity, -infinity, +infinity, etc.
We discussed the maximum value for a float variable that we can store in Python, beyond which everything is considered as infinity.
Then, we discussed the behavior of various comparison operators on infinity.
Finally, we learned how we can pass infinity as a command-line argument in Python.
The post A Foolproof Guide to Infinity In Python appeared first on Like Geeks.