python2:数字
python支持3种不同的数字类型:整型、浮点型和复数,布尔类型可以看作整型的子类型。python中的浮点型对应C语言中的double,可以通过sys.float_info来查看精度。
数字的基本操作
python中的数字都支持下面的操作:
1、x + y:x加y;
2、x - y:x减y;
3、x * y:x和y的积;
4、x / y:x和y的商;
5、x // y:x和y的商的下限,即取整;
6、x % y:x/y的余;
7、abs(x):x为整型和浮点型,返回x的绝对值;x为复数型,返回x的magnitude(注);
8、int(x):将x转换到整型;
9、float(x):将x转换到浮点型;
10、complex(re, im):得到实部为re,虚部为im的复数;
11、c.conjugate():返回复数c的共轭复数;
12、divmod(x, y):返回对(x // y, x % y);
13、pow(x, y):x的y次方;
14、x ** y:同pow(x, y),x的y次方。
对数字的操作也可以使用math和cmath模块(后面介绍)。
注:
magnitude的计算规则如下:
1)实数的magnitude就是该实数的正平方根。2的magnitude就是2,-3的magnitude就是3;
2)复数的magnitude是该复数与共轭复数的乘积的正平方根。比如z=3-2j,则magnitude为(3-2j)*(3+2j)的正平方根,也就是9+4=13的正平方根。
整型的位运算
位运算只能用于整型数据,下面是python中的位运算:
1、x | y:按位或;
2、x ^ y:按位异或;
3、x & y:按位与;
4、x << y:左移;
5、x >> y:右移;
6、~x:取反。
整型附加方法
整型实现了numbers.Integral抽象基础类,在此基础上,新增了下面的方法:
int.bit_length()
返回整数的二进制的bit位数,例如:
>>> a = 8
>>> bin(a)
‘0b1000‘
>>> a.bit_length()
4
int.to_bytes(length, byteorder, *, signed=False)
将整数转换为字节数组表示,参数说明如下;
length:数组的长度,如果整数转换出的字节数组长度超过了该长度,则产生OverflowError;
byteorder:字节序;值为"big"或者"little","big"表示最有意义的字节放在字节数组的开头,"little"表示最有意义的字节放在字节数组的结尾。sys.byteorder保存了主机系统的字节序;
signed:确定是否使用补码来表示整数,如果值为false,并且是负数,则产生OverflowError。默认值False。
例如
>>> (1024).to_bytes(2, byteorder=‘big‘)
b‘\x04\x00‘
>>> (1024).to_bytes(10, byteorder=‘big‘)
b‘\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00‘
>>> (-1024).to_bytes(10, byteorder=‘big‘, signed=True)
b‘\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00‘
>>> x = 1000
>>> x.to_bytes((x.bit_length() // 8) + 1, byteorder=‘little‘)
b‘\xe8\x03‘
classmethod int.from_bytes(bytes, byteorder, *, signed=False)
将字节数组转换为整数,参数如下:
bytes:字节数组或者是一个iterable;
byteorder:同上;
signed:同上。
例如:
>>> int.from_bytes(b‘\x00\x10‘, byteorder=‘big‘)
16
>>> int.from_bytes(b‘\x00\x10‘, byteorder=‘little‘)
4096
>>> int.from_bytes(b‘\xfc\x00‘, byteorder=‘big‘, signed=True)
-1024
>>> int.from_bytes(b‘\xfc\x00‘, byteorder=‘big‘, signed=False)
64512
>>> int.from_bytes([255, 0, 0], byteorder=‘big‘)
16711680
float附加方法
float实现了numbers.Real抽象基础类,并带有如下的额外方法:
float.as_integer_ratio()
将浮点数表示为两个整数的商。无限则抛出OverflowError,NaNs则抛出ValueError。
例如:
>>> a = 1.5
>>> a.as_integer_ratio()
(3, 2)
float.is_integer()
如果float可以转化为整数,则返回True,否则返回False。
例如:
>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False
float.hex()
返回浮点数的hexadecimal字符串(注)表示,该字符串始终以0x开头,p结尾,并带有一个指数。
例如
>>> a = 1.234
>>> a.hex()
‘0x1.3be76c8b43958p+0‘
classmethod float.fromhex(s)
将hexadecimal字符串s转换为float,s的开头和结尾允许存在空格。
注
一个hexadecimal字符串的格式为:
[sign] [‘0x‘] integer [‘.‘ fraction] [‘p‘ exponent]
sign:可选,+后者-;
integer,fraction:16进制数字的字符串;
exponent:十进制数,可带上一个sign作为开头,表示系数为2的exponent次方。
下面是一个例子:
0x3.a7p10表示浮点数:(3 + 10./16 + 7./16**2) * 2.0**10,计算结果为3740.0。
哈希
对于数字x和y,可能是不同的类型,但如果x==y,则要求hash(x) == hash(y)(__hash__()方法文档中有更详细的介绍)。python中提供了一个专门的函数为所有的数字类型计算哈希值。本质上,函数使用了一个固定的质数P,通过和P模运算来计算哈希值。P的值保存在sys.hash_info的modulus属性中。
CPython实现细节
当前,质数的值在32位的机器上是P = 2**32 - 1,在64位的机器上是P = 2**61 - 1。
下面是具体的规则:
1)如果x = m / n是一个非负的有理数,并且n不整除P,定义hash(x)作为m * invmod(n, P) % P,其中invmod(n, P)表示n mod P的逆;
2)如果x = m / n是一个非负的有理数,并且n整除P(但是m不),定义hash(x)为常量值sys.hash_info.inf;
3)如果x = m / n是一个负的有理数,定义hash(x)作为-hash(-x),如果结果为-1,则修改结果为-2;
4)特殊值sys.hash_info.inf、-sys.hash_info.inf被用于正无穷大和负无穷大的哈希值,sys.hash_info.nan被用于nan(not a number)的哈希值;
5)对于复数z,哈希值为hash(z.real) + sys.hash_info.imag * hash(z.imag),并模运算2**sys.hash_info.width确保值在range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width - 1))内。如果结果是-1,则修改为-1。
下面是用于阐述上面逻辑的python代码的例子:
import sys, math def hash_fraction(m, n): """Compute the hash of a rational number m / n. Assumes m and n are integers, with n positive. Equivalent to hash(fractions.Fraction(m, n)). """ P = sys.hash_info.modulus # Remove common factors of P. (Unnecessary if m and n already coprime.) while m % P == n % P == 0: m, n = m // P, n // P if n % P == 0: hash_ = sys.hash_info.inf else: # Fermat's Little Theorem: pow(n, P-1, P) is 1, so # pow(n, P-2, P) gives the inverse of n modulo P. hash_ = (abs(m) % P) * pow(n, P - 2, P) % P if m < 0: hash_ = -hash_ if hash_ == -1: hash_ = -2 return hash_ def hash_float(x): """Compute the hash of a float x.""" if math.isnan(x): return sys.hash_info.nan elif math.isinf(x): return sys.hash_info.inf if x > 0 else -sys.hash_info.inf else: return hash_fraction(*x.as_integer_ratio()) def hash_complex(z): """Compute the hash of a complex number z.""" hash_ = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag) # do a signed reduction modulo 2**sys.hash_info.width M = 2**(sys.hash_info.width - 1) hash_ = (hash_ & (M - 1)) - (hash & M) if hash_ == -1: hash_ == -2 return hash_
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。