数字是编程不可或缺的一部分。因此,编程语言支持各种数据类型来表示不同类型的数字,并提供各种使用它们的方法。
这些数据类型中的每一种都对其可以表示的数字范围有一定的限制;有些可以代表小范围的数字,而另一些则支持很大的数字范围。根据我们的用例,我们可以选择其中之一。
但他们都没有办法表示无穷大。
在许多现实场景中,我们经常遇到并且必须处理无穷大,因此我们需要一种用编程语言来表示它们的方法。
在本教程中,我们将学习如何在 Python 中表示和使用无穷大。
什么是无限?
在深入研究无穷大的编程技巧之前,让我们首先通过正式定义它来了解无穷大是什么
根据无穷大在不同上下文和领域中的用法,无穷大有数十种定义。我们将重点关注数学和计算中使用的那些。
无穷大被定义为一个比任何实数都大的“未定义”的大数。
它存在于数轴的两端,因此我们有正无穷和负无穷。
无穷大用符号 ₨ 表示。
在计算机科学中,它也被定义为“未定义运算”的结果,例如除以零。在编程中,无穷大用于定义优化算法中的绝对最大/最小值。
如何使用浮点数书写无穷大?
我们可以通过将字符串值“inf”或“infinity”传递给方法来将无穷大声明为浮点数float
.
a = float("inf")
print(f"value of a = {a}")
print(f"type of a = {type(a)}")
Output:
正如我们所讨论的,还存在“负无穷”。我们可以通过传递“-inf”或创建正无穷大并在其前面加上“-”符号来声明相同的内容。
b = float("-inf")
print(f"value of b = {b}")
print(f"value of -float('inf') = {-float('inf')}")
Output:
Note我们传递给的字符串float
方法是与大小写无关。因此传递“INF”或“inFINIty”也将被正确评估为inf
.
为什么无穷大是float类型?
你一定想知道为什么无穷大不是int
类型,如果它是一个未定义的数字,它的数据类型有何影响?
答案在于 Python 中数字的表示方式。
整数使用其二进制表示形式来表示,例如。 5表示为0101。
另一方面,浮点数由 3 个部分表示:符号、尾数和指数。这是根据IEEE 754 标准用于存储浮点数。
IEEE 754 标准保留了一些值来表示特殊数字。这些特殊数字之一是无穷大。
根据该标准,当浮点数的指数部分全部为1、尾数部分全部为0时,表示无穷大。
另外,如果符号位为0,则表示正无穷大,而符号位为1则表示负无穷大。
因此,由于无穷大是一个特殊的值,无法使用简单的二进制表示形式来表示,因此它的数据类型在Python中是float。
使用数学模块
我们也可以使用Python的math
模块来表示无穷大。
该模块有一个预定义值math.inf
可以分配给变量来表示无穷大。
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:
事实证明,数学模块还将无穷大定义为浮点数,显然,这两种方法声明的无穷大是等效的。
让我们来看看。
float_inf = float("inf")
math_inf = math.inf
print(f"float_inf == math.inf is {float_inf == math.inf}")
Output:
检查无穷大
您可以使用 math.isinf() 来检查无穷大,如下所示:
import math
positive_infinity = float('inf')
negative_infinity = float('-inf')
print(math.isinf(positive_infinity)) # returns True
print(math.isinf(negative_infinity)) # returns True
请注意,math.isinf
无论无穷大是正数还是负数,都返回 true。
使用十进制模块
蟒蛇的decimal
模块提供对快速正确舍入的十进制浮点运算的支持。
它还提供了一种使用以下方式表示无穷大的方法Decimal
class.
以下是如何使用 Python 表示正无穷大和负无穷大decimal
module:
from decimal import Decimal
positive_infinity = Decimal('Infinity')
negative_infinity = Decimal('-Infinity')
Output:
print(positive_infinity)
print(negative_infinity)
Infinity
-Infinity
在此示例中,“Infinity”和“-Infinity”是传递给Decimal
构造函数。蟒蛇的decimal
模块将这些字符串参数分别解释为正无穷大和负无穷大。
无穷大的算术运算
由于无穷大是一个浮点数,我们可以对其进行各种算术运算,并且此类运算的结果也是由 IEEE 标准定义的。
Addition
如果我们将任何有限实数与无穷大相加,结果将是无穷大。
如果我们将无穷大加上无穷大,结果将再次是无穷大。
但是,如果我们将负无穷大添加到正无穷大,结果将是未定义的或NaN
(不是数字)。NaN
是另一个特殊数字,如无穷大,在 Python 中使用float
数据类型,根据 IEEE 754 标准。
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:
减法
从无穷大中减去正实数会得到无穷大。
从任何正实数中减去无穷大都会返回负无穷大。
从无穷大减去无穷大会得到未定义的结果,即NaN
(正如上一节中所观察到的)。
从负无穷大减去无穷大得到负无穷大。
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:
乘法
任何正数与无穷大相乘都会得到无穷大的结果。
无穷大乘以另一个无穷大也会得到无穷大。
无穷大乘以零是未定义的,它返回NaN
.
无穷大乘以负无穷大或任何负数,都会得到负无穷大。
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
无穷大除以任何正数或负数分别返回正无穷大或负无穷大。
无穷大除以自身或除以负无穷大返回 aNaN
.
任何有限数除以无穷大都会得到 0 或 ∽0。
最后,无穷大除以 0 会产生“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:
请注意,无穷大除以任何数字的小数结果都是无穷大;然而,进行楼层划分会导致NaN
.
print(f"inf // 20 = {inf // 20}")
Output:
模运算
The 模运算两个数之间进行整数除法时,返回两个数的余数。
无穷大的模运算的行为有点奇怪。
无穷大(正数和负数)与任何数字(正数、负数、无穷大)的模会产生NaN
然而,以+无穷大实数取模会返回该数字。
另一方面,用 -无穷大对实数取模,结果是 -无穷大。
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 无穷大
除了math
模块,以及float
方法,也可以使用 NumPy 的分配无穷大np.inf
持续的。
NumPy 还遵循 IEEE 754 标准来存储浮点数,因此np.inf
等于float("inf")
and math.inf
。数据类型为np.inf
也是浮动的。
NumPy 的无穷常量也可以使用多个别名来访问,例如np.Infinity
, np.Inf
, and np.infty
.
NumPy 还为正无穷大和负无穷大定义了单独的常数。可以使用以下方式访问正无穷大np.PINF
(np.inf 的别名),并且可以使用常量访问负无穷大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 还具有判断某个值是否为无穷大的方法。它还具有单独的方法来检查该值是正无穷大还是负无穷大。
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:
请注意,我们还可以将 NumPy 数组传递给这些方法;它将返回一个布尔值数组,表示数组中值为无穷大的位置。
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:
检查正无穷大或负无穷大
在某些情况下,您可能需要具体检查某个值是正无穷大还是负无穷大。 NumPy 为此提供了两个方便的函数:np.isposinf()
and np.isneginf()
.
以下是如何使用这些函数的示例:
import numpy as np
positive_infinity = np.inf
negative_infinity = np.NINF
num = 100
print(np.isposinf(positive_infinity)) # True
print(np.isposinf(negative_infinity)) # False
print(np.isposinf(num)) # False
print(np.isneginf(positive_infinity)) # False
print(np.isneginf(negative_infinity)) # True
print(np.isneginf(num)) # False
相反,NumPy 也有一个方法称为np.isfinite
检查该值是否是有限的。
使用带有 Infinity 的 Pandas
假设我们有一个包含无限值的 DataFrame,并且我们想要对其执行操作。这是一个例子:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'A': [1, 2, np.inf],
'B': [4, -np.inf, 6],
'C': [7, 8, 9]
})
print(df)
Output:
A B C
0 1.0 4.0 7
1 2.0 -inf 8
2 inf 6.0 9
Pandas提供了这个功能DataFrame.isin()
检查无限值:
print(df.isin([np.inf, -np.inf]))
Output:
A B C
0 False False False
1 False True False
2 True False False
The isin([np.inf, -np.inf])
函数返回一个布尔值的 DataFrame,指示值是否为无限。
算法中的无穷大
无穷大广泛应用于计算机科学算法中,尤其是与图相关的算法,例如Dijkstra 算法用于寻找最短路径。
无穷大的概念用于初始化节点之间的距离,因为最初我们不知道距离,所以我们假设它们是无限的。
以下是如何在 Dijkstra 算法中使用无穷大的简化演示:
import math
# Suppose we have the following graph represented as an adjacency matrix
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
# Dijkstra's algorithm
def dijkstra(graph, start_node):
shortest_distances = {node: math.inf for node in graph}
shortest_distances[start_node] = 0 # The distance of the start node from itself is always 0
unvisited_nodes = list(graph)
while unvisited_nodes:
# Select the node with the smallest distance
current_node = min(unvisited_nodes, key=lambda node: shortest_distances[node])
unvisited_nodes.remove(current_node)
for neighbour, distance in graph[current_node].items():
new_distance = shortest_distances[current_node] + distance
if new_distance < shortest_distances[neighbour]:
shortest_distances[neighbour] = new_distance
return shortest_distances
# Find the shortest distances from node 'A'
shortest_distances = dijkstra(graph, 'A')
print(shortest_distances)
Output:
{'A': 0, 'B': 1, 'C': 3, 'D': 4}
在上面的示例中,Dijkstra 算法找到从起始节点到图中所有其他节点的最短路径。
最初,使用以下方法将到所有节点的距离设置为正无穷大math.inf
因为我们假设我们对图结构一无所知。
起始节点的距离设置为 0,因为任何节点到其自身的距离始终为 0。
无穷大的最大值
我们已经讨论过无穷大是一个比任何有限数都大的“大的、未定义的数”。
但计算机中变量可以存储的最大值是有限制的。我们不能声明任何大值,并将其与无穷大进行比较。
在Python中,1e+308和1e+309之间的一个值是浮点变量可以存储的最大值。
可以使用属性找到确切的值sys.float_info
.
这会显示该计算机上浮点数据类型的各种属性,包括浮点变量可以在 Python 中存储的最大值。
任何大于该值的值都被解释为无穷大。
同样,在负端,任何低于某个最小值的值都被解释为负无穷大。
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:
在我们讨论这个问题的同时,我们还可以讨论无穷大上的幂(幂)运算符的行为。
如果我们试图找到无穷大的任何幂(除了0),或者如果我们计算任何数字(除了1)的无穷大幂的值,结果将是无穷大。
但是,如果我们使用两个有限数字执行求幂运算,并且结果超出了最大允许值,则我们不会返回无穷大作为结果,而是会收到“溢出错误”,并显示消息“数值结果超出范围”。
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:
比较无穷大
任意数都小于+inf
。任意数都大于-inf
.
inf
既不小于也不大于inf
>。它等于inf
,并且不等于-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:
将无穷大作为命令行参数传递
当我们从命令行运行 Python 文件时,我们还可以传递任意数量的参数。
可以使用以下方式访问这些参数sys.argv
.
sys.argv
包含传递给 Python 程序的命令行参数列表。列表中的第一个元素是 Python 文件名,其余元素是在文件名后面传递的附加值(用空格分隔)。
该列表中的所有值都存储为 Python 字符串。
#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:
由于默认情况下所有命令行参数都以字符串形式接收,因此如果我们希望参数具有某种数据类型(例如 float、int 等),则需要将字符串参数转换为所需的数据类型。
这样,如果用户需要传递“无穷大”作为参数之一,我们可以使用float
方法,并将其存储在变量中。
让我们举一个例子,我们需要 3 个数字命令行参数,第一个是整数,其余的是浮点数。
#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: