数字是自然界计数活动的抽象,更是数学运算和推理表示的基础。计算机对数字的识别和处理有两个基本要求:确定性和高效性。
表示数字或数值的数据类型称为数字类型,Python语言提供3种数字类型:整数、浮点数和复数,分别对应数学中的整数、实数和复数。1010表示一个整数,"1010"表示一个字符串。
整数类型与数学中整数的概念一致,下面是整数类型的例子:
1010,99,-217,0x9a,-0x89
整数类型共有4种进制表示:十进制、二进制、八进制和十六进制。默认情况,整数采用十进制,其他进制需要增加引导符号,如下表所示。二进制数以0b引导,八进制数以0o引导,十六进制数以0x引导,大小写字母均可使用。
进制种类 | 引导符号 | 描述 |
---|---|---|
十进制 | 无 | 默认情况,例如,1010,-425 |
二进制 | 0b或0B | 由字符0和1组成,例如,0b101,0B101 |
八进制 | 0o或0O | 由字符0到7组成,例如,0o711,0O711 |
十六进制 | 0x或0X | 由字符0到9、a到f、A到F组成,例如,0xABC |
整数类型理论上的取值范围是[-∞,+∞],实际上的取值范围受限于运行Python程序的计算机内存大小。除极大数的运算外,一般认为整数类型没有取值范围限制。
我们已经知道了常见的整数类型,那么整数之间如何进行转换呢?其他进制转为十进制使用int函数,其他进制转为二进制使用bin函数,其他进制转为八进制使用oct函数,其他进制转为十六进制转为hex函数,并且是借助于10进制作为中间的桥梁进行转换,也就是使用到int()函数。例如:把一个二进制的数转换为八进制的数,需要先把二进制转换为十进制,再转换为八进制。
函数 | 描述 |
---|---|
int() | 其他进制转换为十进制 |
bin() | 其他进制转换为二进制 |
oct() | 其他进制转换为八进制 |
hex | 其他进制转换为十六进制 |
浮点数类型与数学中实数的概念一致,表示带有小数的数值。Python语言要求所有浮点数必须带有小数部分,小数部分可以是0,这种设计可以区分浮点数和整数类型。浮点数有两种表示方法:十进制表示和科学计数法表示。下面是浮点数类型的例子:
0.0,-77.,-2.17,3.1416,,96e4, 4.3e-3,9.6E5
科学计数法使用字母e或E作为幂的符号,以10为基数,含义如下:
e = a*10**b
上例中4.3e-3值为0.004.3;9.6E5也可以表示为9.6E+5,其值为960 000.0。浮点数类型与整数类型由计算机的不同硬件单元执行,处理方法不同,需要注意的是,尽管浮点数0.0与整数0值相同,但它们在计算机内部表示不同。
Python浮点数的数值范围和小数精度受不同计算机系统的限制,sys.float_info详细列出了Python解释器所运行系统的浮点数各项参数,例如:
import sys
print(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)
上述输出给出浮点数类型所能表示的最大值(max)、最小值(min),科学计数法表示下最大值的幂(max_10_exp)、最小值的幂(min_10_exp),基数 (radix)为2时最大值的幂(max_exp)、最小值的幂(min_exp),科学计数法表示中系数()的最大精度(mant_dig),计算机所能分辨的两个相邻浮点数的最小差值(epsilon),能准确计算的浮点数最大个数(dig)。
浮点数类型直接表示或科学计数法表示中的系数()最长可输出16个数字,浮点数运算结果中最长可输出17个数字,然而,根据sys.float_info结果,计算机只能够提供15个数字(dig)的准确性,最后一位由计算机根据二进制计算结果确定,存在误差,例如:
print(3.1415926535897924)
print(987654321123456.789)
输出结果为:
3.1415926535897922
987654321123456.8
浮点数在超过15位数字计算中产生的误差与计算机内部采用二进制运算有关,使用浮点数无法进行极高精度的数学运算,由于Python语言能够支持无限制且准确的整数计算,因此,如果希望获得精度更高的计算结果,往往采用整数而不直接采用浮点数。例如,计算如下两个数的乘法值,它们的长度只有10个数字,其中:
a=3.141592653,b=1.234567898
可以直接采用浮点数运算,也可以同时把它们的小数点去掉,当作整数运算,结果如下:
3.1415926531.234567898
3.8785094379864535
31415926531234567898
3878509437986453394
其中,浮点数运算输出17个数字长度的结果,然而,只有前15个数字是确定正确的。整数运算能够输出完全准确的运算结果。使用整数表达浮点数的方法是高精确度运算的基本方法之一。
拓展:高精度浮点运算类型
Python通过标准库decimal提供了一个更精确的数字类型Decimal,这个类型利用上文所介绍的整数运算方法提供高精度浮点数运算,并可以使用getcontext().prec参数自定义浮点数精度的位数,例如:
import decimal
a = decimal.Decimal('3.141592653')
b = decimal.Decimal('1.234567898')
decimal.getcontext().prec = 20
print(a * b)
输出结果为:
3.878509437986453394
需要注意的是,在使用decimal库时,Decimal('数字')
是高精确度数字的基本表示形式,需要使用单引号,例如, decimal.Decimal('3.141592653')
。
简单地说,浮点数类型的取值范围在[2-1023,21023],即 [-2.225x10308,1.797x10308] 之间,运算精度为2.220x10-16,即浮点数运算误差仅为0.000 000 000 000 0002。对于高精度科学计算外的绝大部分运算来说,浮点数类型足够“可靠”,一般认为浮点数类型没有范围限制,运算结果准确。
复数可以看作是二元有序实数对(a,b),表示为a+bj,其中,a是实数部分,简称实部,b是虚数部分,简称虚部。Python语言中,复数的虚数部分通过后缀“J”或“j”来表示,例如:
12.3+4j 、-5.6+7j 、1.23e-4+5.67e+89j
复数类型中实数部分和虚数部分的数伉都是浮点类型。对于复数z,可以用 z.real和z.imag分别获得它的实数部分和虚数部分,例如:
z = 1.23e-4 + 5.67e+89j
print(z.real)
print(z.imag)
输出结果为:
0.000123
5.67e+89
复数类型在科学计算中十分常见,基于复数的运算属于数学的复变函数分支,该分支有效支撑了众多科学和工程问题的数学表示和求解。Python直接支持复数类型,为这类运算求解提供了便利。
Python提供了9个基本的数值运算操作符,如下表所示。这些操作符由Python解释器直接提供,不需要引用标准或第三方函数库,也叫做内置操作符。
操作符 | 描述 |
---|---|
x+y | x与y之和 |
x+=y | 将x与y之和赋值为x |
x-y | x与y之差 |
x-=y | 将x与y之差赋值为x |
x*y | x与y之积 |
x*=y | 将x与y之积赋值为x |
x/y | x与y之商 |
x/=y | 将x与y之商赋值为x |
x//y | x与y之整除商,即不大于x与y之商的最大整数 |
x//=y | 将x与y之整除商赋值为x |
x%y | x与y之商的余数,也称为模运算 |
x%=y | 将x与y之商的余数赋值为x |
-x | x的负值,即x*(-1) |
+x | x本身 |
x**y | x的y次幂,即xy |
x**=y | 将x的y次幂赋值为x |
这几个操作符与数学习惯一致,运算结果也符合数学意义。操作符运算的结果可能改变数字类型,3种数字类型之间存在一种逐渐扩展的关系,具体如下:
整数>浮点数>复数
这是因为整数可以看成是浮点数没有小数的情况,浮点数可以看成是复数虚部为0的情况。基于上述扩展关系,数字类型之间相互运算所生成的结果是“更宽”的类型,基本规则如下。
(1)整数之间运算,如果数学意义上的结果是小数,结果是浮点数。
(2)整数之间运算,如果数学意义上的结果是整数,结果是整数。
(3)整数和浮点数混合运算,输出结果是浮点数。
(4)整数或浮点数与复数运算,输出结果是复数。
在Python的内置函数中,有6个与数值运算相关。
函数 | 描述 |
---|---|
abs(x) | x的绝对值 |
divmod(x,y) | (x//y,x%y)。输出为二元组形式(也称为元组类型) |
pow(x,y[,z]) | (x**y)%z,[…]表示该参数可以省略,即 pow(x,y)。它与x**y相同 |
round(x[,ndigits]) | 对x四舍五入,保留 ndigits 位小数。round(x)返回四舍五入的整数值 |
max(x) | 返回x中的最大值 |
min(x) | 返回x中的最小值 |
abs()可以计算复数的绝对值,复数的绝对值是二维坐标系中复数位置到坐标原点的长度。例如:
print(abs(-3 + 4j))
输出结果为:5.0
pow()函数第三个参数z是可选的,使用该参数时,模运算与幂运算同时进行,速度很快。例如,求3的3999次幂结果的最后4位。从Python语法角度,pow(3,pow(3,999))%10000(请不要在计算机中尝试该语句)和pow(3,pow(3,999),10000)都能完成计算需求。但是,前者是先求幂运算结果再进行模运算,由于幂运算结果数值巨大,上述计算在一般计算机上无法完成;而第二条语句则在
幂运算同时进行模运算,可以很快计算出结果。例如:
print(pow(3, pow(3,999),10000)) #幂运算和模运算同时进行,速度快
# 4587
pow()函数第三个参数z的这个特点在运算加解密算法和科学计算中十分重要。
拓展:模运算
模运算(%)在编程中十分常用,主要应用于具有周期规律的场景。例如,一个星期7天,用day 代表日期,则day%7可以表示星期;对于一个整数n,n%2的取值是0或者1,可以判断整数n的奇偶。本质上,整数的模运算n%m能够将整数n映射到[0,m-1]的区间中。
数值运算操作符可以隐式地转换输出结果的数字类型,例如,两个整数采用运算符“/”的除法将可能输出浮点数结果。此外,通过内置的数字类型转换函数可以显式地在数字类型之间进行转换,如表所示。
函数 | 描述 |
---|---|
int(x) | 将x转换为整数,x可以是浮点数或字符串 |
float(x) | 将x转换为浮点数,x可以是整数或字符串 |
complex(re[,im]) | 生成一个复数。实部为re,虚部为im,re可以是整数、浮点数或字符串,im可以是整数或浮点数但不能为字符串 |
浮点数类型转换为整数类型时,小数部分会被舍弃(不使用四舍五入),复数不能直接转换为其他数字类型,可以通过.real 和.imag将复数的实部或虚部分别转换,例如:
print(int(10.99)) # 10
print(complex(10.99)) # (10.99+0j)
print(float((10 + 99j).imag)) # 99.0
(1)既然浮点数可以表示所有整数数值,Python语言为何要同时提供整数和浮点数两种数据类型?
答:尽管浮点数确实可以表示很多整数数值,但Python语言同时提供整数(int)和浮点数(float)两种数据类型,这主要是因为它们在计算效率、存储效率和精确性上存在差异,并适用于不同的场景和需求。
综上所述,尽管浮点数可以表示很多整数数值,但Python语言同时提供整数和浮点数两种数据类型是为了满足不同的计算需求、提高计算效率、节省存储空间以及保持计算的精确性。根据具体的应用场景和需求,开发者可以选择使用合适的数据类型。
(2)Python 语言中整数1010的二进制、八进制和十六进制表示分别是什么?
n = 1010
print("{}的二进制表示为{}".format(n,bin(n)))
print("{}的八进制表示为{}".format(n,oct(n)))
print("{}的十六进制表示为{}".format(n,hex(n)))
输出结果为:
1010的二进制表示为0b1111110010
1010的八进制表示为0o1762
1010的十六进制表示为0x3f2
(3)Python语言中-77.的科学计数法表示是什么?4.3e-3的十进制表示是什么?
-77.的科学计数法表示:-7.7e1、4.3e-3的十进制表示:0.0043
(4)复数2.3e+3-1.34e-3j的实部和虚部分别是什么?采用什么方法提取一个复数的实部和虚部?
实部为:2300.0,虚部为:-0.00134。使用z.real()和z.imag()函数进行提取。
(5) (0.1+0.2) == 0.3
的结果是什么?(True or False)
在标准的Python浮点数运算中,(0.1 + 0.2) == 0.3 的结果会是 False。这是因为浮点数在计算机中的表示存在精度问题,0.1 和 0.2 的二进制表示并不是精确的,所以它们的和也不会精确地等于 0.3。
如果想要得到True,可以采用以下方法:
参考文章:
python中常见进制之间的转换