该模块定义了数字的层级结构抽象基类,逐级添加一些特性已适应各种数字对称操作的需要。
class Number
数字的顶层,是其它所有数字层次的基础,可Number()实例化,但这样的实例无用。本模块中它之下的所有类型都不能实例化。如果你只想确认参数x是不是数字而不关心其类型,则使用内置函数isinstance(x, Number)。
>>>from numbers import Number
>>>n = Number()
>>>n
<numbers.Number object at 0x000001357370BAE0>
>>>isinstance(1, Number)
True
第一层class Complex(复数类型)
这是Number的抽象子类,描述了复数抽象要求和功能,适用于内置 complex 类型的操作。这些操作有: 转换为complex 和 bool, real, imag, +, -, *, /, **, abs(), conjugate(), == 以及 !=。除取反(-)和不等于( != )之外所有操作都是抽象的。
Complex.real该复数的实数部分,抽象,只有复数对象才可以调用。
Complex.imag该复数的虚数部分,抽象。
abstractmethod Complex.conjugate(),抽象。返回共轭复数。例如 (1+3j).conjugate() == (1-3j)。
>>>from numbers import Complex
>>>n = Complex()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Complex with abstract methods __abs__, __add__, __complex__, __eq__, __mul__, __neg__, __pos__, __pow__, __radd__, __rmul__, __rpow__, __rtruediv__, __truediv__, conjugate, imag, real
>>>isinstance(1+1J, Complex)
True
>>>cmp=complex("1+1j")
>>>cmp
1+1j
>>>bool(cmp)
True
>>>cmp.real
1.0
>>>cmp.imag
1.0
>>>cmp.conjugate()
(1-1j)
>>>abs(cmp)
1.4142135623730951
第二层class Real(实数类型)
这是Complex的抽象子类,虚部为0,继承复数的所有属性和方法外,增加了只适合实数的操作,它们包括:float()、math.trunc()、 round()、 math.floor()、 math.ceil()、 divmod()、 //、 %、 <、 <=、 >、 和 >=。
>>>from numbers import Real
>>>real = Real()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Real with abstract methods __abs__, __add__, __ceil__, __eq__, __float__, __floor__, __floordiv__, __le__, __lt__, __mod__, __mul__, __neg__, __pos__, __pow__, __radd__, __rfloordiv__, __rmod__, __rmul__, __round__, __rpow__, __rtruediv__, __truediv__, __trunc__
>>>f=float("1.23e12")
>>>f
1230000000000.0
>>>from math import trunc,floor,ceil
>>>f=trunc(1.23e12)
>>>f
1230000000000
>>>round(2.3501,2)
2.35
>>>floor(1.995)
1
>>>ceil(1.021)
2
>>>divmod(123,11)
(11,2)
>>>complex("1.23")
(1.23+0j)
>>>r=1.23
>>>r.real
1.23
>>>r.imag
0.0
>>>r.conjugate()
1.23
第三层class Rational(比,有理数类型)
这是Real的抽象子类,增加了numerator(分子)和denominator(分母)两种抽象属性,这两种属性为float()提供底层支持。
>>>from numbers import Rational
>>>r = Rational()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Rational with abstract methods __abs__, __add__, __ceil__, __eq__, __floor__, __floordiv__, __le__, __lt__, __mod__, __mul__, __neg__, __pos__, __pow__, __radd__, __rfloordiv__, __rmod__, __rmul__, __round__, __rpow__, __rtruediv__, __truediv__, __trunc__, denominator, numerator
>>>from fractions import Fraction
>>>fr=Fraction(1,2)
>>>isinstance(fr,Rational)
True
>>>fr.numerator
1
>>>fr.denominator
2
>>>f=1.23
>>>isinstance(f,Rational)
False
>>>f.as_integer_ratio()
(2769713770832855, 2251799813685248)
第四层class Integral(整数类型)
这是Rational的抽象子类,增加int()转换操作支持,为 float(), numerator 和 denominator 提供了默认支持。为 pow() 方法增加了求余,即pow(base, exp, mod)。二进制按位运算的抽象方法: <<(左移), >>(右移), &(按位与), ^(按位异或), |(按位或), ~(按位取反)。 右移 n 位被定义为被pow(2,n)整除。左移n位被定义为乘以 pow(2,n)。
>>>from numbers import Integral
>>>it = Integral()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Integral with abstract methods __abs__, __add__, __and__, __ceil__, __eq__, __floor__, __floordiv__, __int__, __invert__, __le__, __lshift__, __lt__, __mod__, __mul__, __neg__, __or__, __pos__, __pow__, __radd__, __rand__, __rfloordiv__, __rlshift__, __rmod__, __rmul__, __ror__, __round__, __rpow__, __rrshift__, __rshift__, __rtruediv__, __rxor__, __truediv__, __trunc__, __xor__
>>>n=123
isinstance(n,Integral)
True
>>>n.numerator
123
>>>n.denominator
1
>>>pow(12,3,10)
8
>>>bin(0b110101110101>>8), bin(0b110101110101//pow(2,8))
('0b1101', '0b1101')
>>>bin(-0b110101110101>>8), bin(-0b110101110101//pow(2,8))
('-0b1110', '-0b1110')
>>>bin(0b110101110101<<8), bin(0b110101110101*pow(2,8))
('0b11010111010100000000', '0b11010111010100000000')
>>>bin(-0b110101110101<<8), bin(-0b110101110101*pow(2,8))
('-0b11010111010100000000', '-0b11010111010100000000')
>>>bin(1 & 0b110101), bin(-1 & 0b110101)
('0b1', '0b110101')
>>>bin(1 ^ 0b110101), bin(-1 ^ 0b110101)
('0b110100', '-0b110110')
>>>bin(1 | 0b110101), bin(-1 | 0b110101)
('0b110101', '-0b1')
>>>bin(~0b110101), bin(~-0b110101)
('-0b110110', '0b110100')
>>>~123 | 123, ~-123 | -123
(-1, -1)
位移(>>和<<)
整数左移填入0,右移填入符合位(正0负1)。由上面的计算可以看出,绝对值相同,右移后同样位数后,负数的绝对值比正数大1,这是怎么回事呢?
假如用16位表示一个整数,最高位(左起第一位)是符号位,0代表正数,1代表负数。正数是数的本身,负数除了符号位,其它位是这个数绝对值的补数+1。下图第三行是-1的储存结构。
下图是-0b110101110101>>8的过程,储存码移去右边红色部分,左边填充1,然后减1后除了符号位外取反得到移位后的原码。可见这个数的移位操作使相应位置由1101变为1110,在数学上显然是错误的。关于这个问题下一课再讨论。
按位与(&)
“按位与”不区分符号位,把整个数当作0、1序列处理。由于-1的储存码所有位都是1,所以与-1“按位与”操作是数的本身。
利用“按位与”这种特性,查看数的储存码(按位提取数值),例如,查看-1的最后(右)8位是什么数字。
>>>bin(-1 & 0xFF)
'0b11111111'
计算机内储存整数外(最高位是符号位)还可以储存无符号整数(即自然数,最高位也是数位)。最常见的例子是32位IP地址,由于它是无符号整数,所以范围是0x0(0)到0xFFFFFFFF(2^32-1=4294967295)。注意:Python默认不支持无符号整数,但这个不影响与正整数的按位与操作。因为正整数的符号位都是0,所以与正整数的按位与操作一定是正整数。
例1 把IP=4054568328转化为*.*.*.*形式。
分析:就是把这个整数的最后4个字节分开成4个无符号整数。把一个字节看做是无符号整数,它的范围是0到255。
程序代码(文本代码附录1):
运行结果:
按位或(|)
只有对应两个位都是0,结果才是0,否则是1,所以-1与所有的整数“按位或”都是-1。
例2 把IP=“241.171.205.136”转化为整数。
分析:把四个整数分别左移24、16、8、0位后“按位或”就行。
程序代码(文本代码附录2):
运行结果:
按位异或(^)
对应位相同(同是0或1)结果是0,否则是1。
1^1=0,0^1=1;
1^0=1,1^0=1;
0^1=1,1^1=0;
0^0=0,0^0=0。
可见,一个数与另个数“异或”两次,值不变。即
a^b^b=a。
例3 a=123,b=-123,不使用临时变量交换它们的值,即交换后a=-123,b=123。
分析:用a放a和b的异或值,那么a再和b异或就是原来a值,放入b中,a和原来的a值“异或”就是b值,放入a中。
程序代码(文本代码附录3):
运行结果:
按位取反(~)
0变1,1变0。一个数按位取反后与这个数相或等于-1,即两个数互补。按位取反与相反数有差别,看下面运算
>>>~0,~1,~2,~3,~4
(-1, -2, -3, -4, -5)
>>>~-1, ~-2, ~-3, ~-4, ~-5
(0, 1, 2, 3, 4)
练习题:
1、从父类到子类的顺序排列下面的类。
Real、Rational、Complex、Integral、Number。
2、手算-213右移四位是多少?运行验证。
3、把IP=2857487分成*.*.*.*形式,然后合成整数验证。
4、不用中间变量,交换a=9123,b=4536的值。
5、1234567按位取反是什么数,并验证。
附录1:
#按位与分解ip地址
IP=4054568328
print(IP>>24 & 0xFF, end=".")
print(IP>>16 & 0xFF, end=".")
print(IP>>8 & 0xFF, end=".")
print(IP & 0xFF)
附录2:
#按位或合并ip地址
IP="241.171.205.136"
ips = IP.split(".")
ip = (int(ips[0])<<24) | \
(int(ips[1])<<16) | \
(int(ips[2])<<8) | \
(int(ips[3]))
print(ip)
附录3:
#异或交换变量值
a=123
b=-123
print("a=%d, b=%d" % (a,b))
a=a^b #a放a和b的异或值
b=a^b #b放原a值
a=a^b #a放原b值
print("a=%d, b=%d" % (a,b))
收录于合集 #强基初中数学
125个
上一篇强基初中数学&学Python——外加课 负整数向右位移的系统错误与纠正方法下一篇强基初中数学&学Python——第201课 浮点计算“怪”的根源