Chap5 数字类型
5.1 数字类型基础
Python支持基本的数字类型,以及更高级的对象,用来处理高级工作:
- integer 和 float 对象
- complex number 对象
- decimal : 固定精度对象
- fraction : fraction 数字对象
- sets : 集合
- booleans: true/false
- 内置函数: round, math, random …
5.1.1 数字字面值
Literal | Interpretation |
---|---|
1234, −24, 0, 99999999999999 | Integers (unlimited size) |
1.23, 1., 3.14e-10, 4E210, 4.0e+210 | Floating-point numbers |
0o177, 0x9ff, 0b101010 | Octal, hex, and binary literals in 3.X |
0177, 0o177, 0x9ff, 0b101010 | Octal, octal, hex, and binary literals in 2.X |
3+4j, 3.0+4.0j, 3J | Complex number literals |
set(‘spam’), {1, 2, 3, 4} | Sets: 2.X and 3.X construction forms |
Decimal(‘1.0’), Fraction(1, 3) | Decimal and fraction extension types |
bool(X), True, False | Boolean type and constants |
几个注意的点:
- float可以是有 小数点的, 也可以是带
e
或者E
的 - float是以C的
double
类型实现的,所以精度高 - python3的 整数已经部分 normal和long了
- python3中,十六进制以
0x
或者0X
开头, 八进制以00
,0o
,0O
开头,二进制0b
或者0B
开头:hex(I), oct(I), andbin(I)
类型转换,还有int(str, base)
- python中 complex number的虚数部分用
j
或者J
, 也可以使用complex(real, imag)
创建
5.1.2 内置数字工具
- 操作符: `+, -, *, /, >>, **, &, etc.
- 函数:
pow, abs, round, int, hex, bin, etc.
- 功能模块:
random, math, etc.
5.1.3 表达式操作符
注意:
- 比较操作符可以链式操作:
X<Y<Z
就相当于X<Y and Y<Z
a. 操作符类型提升
当数字操作混合类型出现时,python也是先将类型提升,之后再进行操作:
graph LR
A[int] -->B[float]
B -->C[complex]
5.2 数字实战
5.2.1 repr 和 str
在交互式环境中,对数字的输出时, 交互echo和 print输出的东西有时候有点不同,主要是由于repr
和str
的区别:
repr
返回更像代码的字符串,而str
返回更人性化的字符串; 有些人让str
来做一般用途,而repr
返回更详细的信息。
5.2.2 比较操作
a. 链式比较
A < B < C #相当于 A < B and B < C
1 < 2 < 3 < 4
1 == 2 >3 # 返回false,相当于 1==2 and 2 > 3 , 这一条就不是很直观了
b. float比较是不精确的
1.1+2.2 == 3.3
False
5.2.3 除法
X / Y # 经典除/真除
X // Y # Floor 除, 不是 truncate除
a. python3中//
除法的结果也仍然依赖于操作数类型:
>>> 10 // 4 # Use this in 2.X if truncation needed
2
>>> 10 // 4.0
2.0
在Python2中对让/
变成python3的结果:
>>> from __future__ import division # Enable 3.X "/" behavior
>>> 10 / 4
2.5
b. Floor vs. Truncation
floor是往负无穷大取整, 而truncate是往0 取整。 //
是floor。
>>> import math
>>> math.floor(2.5) # Closest number below value
2
>>> math.floor(-2.5)
-3
>>> math.trunc(2.5) # Truncate fractional part (toward zero)
2
>>> math.trunc(-2.5)
-2
5.2.4 整数精度
Python3的整数精度是unlimited。只是说太大的整数也会需要消耗性能。
5.2.5 Complex Number
使用J
或者j
来代表虚数部分,Python有cmath
module来处理complex number,相当于math
的复数版。
>>> 1j * 1J
(-1+0j)
>>> 2 + 1j * 3
(2+3j)
>>> (2 + 1j) * 3
(6+3j)
5.2.6 Hex, Octal, Binary: Literals and Conversions
十六进制以0x
或者0X
开头, 八进制以00
,0o
,0O
开头,二进制0b
或者0B
开头: hex(I), oct(I), andbin(I)
类型转换,还有int(str, base)
a. 转换进制方式
oct, hex, bin
int
- string formatting:
{0:o}, {1:x}, {2:b}'.format(64, 64, 64)
'%o, %x, %x, %X' % (64, 64, 255, 255)
>>> oct(64), hex(64), bin(64) # Numbers=>digit strings
('0o100', '0x40', '0b1000000')
5.2.7 位操作
x << 2
x >> 2
x | 2 # or
x & 2 # and
x ^ 2 # xor
~x # not
python3中,直接可以调用的函数,都在namespace
builtins
内。
5.3 其他数字类型
5.3.1 Decimal
decimal和 float很像,但是精度是固定的。适合精确运算。
a.创建:
- Decimal(字符串)
- Decimal(float)
- decimal.Decimal.from_float(1.25)
推荐第一种,因为第三种有时会导致更多精度:
>>> Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)
Decimal('2.775557561565156540423631668E-17')
>>> 0.1 + 0.1 + 0.1 - 0.3 # Python 3.3
5.551115123125783e-17
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')
当不同精度的decimal
一起运算的时,会使用精度最长的作为结果:
>>> Decimal('0.1') + Decimal('0.10') + Decimal('0.10') - Decimal('0.30')
Decimal('0.00')
b. 设置全局精度
>>> import decimal
>>> decimal.Decimal(1) / decimal.Decimal(7) # Default: 28 digits
Decimal('0.1428571428571428571428571429')
>>> decimal.getcontext().prec = 4 # Fixed precision
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1429')
>>> Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3) # Closer to 0
Decimal('1.110E-17')
c. 局部设置精度
with decimal.localcontext() as ctx:
ctx.prec = 2
decimal.Decimal('1.00') / decimal.Decimal('3.00')
5.3.2 Fraction
表示有理数(分数)
# 使用分子分母创建
>>> from fractions import Fraction
>>> x = Fraction(1, 3) # Numerator, denominator
>>> y = Fraction(4, 6) # Simplified to 2, 3 by gcd
>>> x
Fraction(1, 3)
>>> y
Fraction(2, 3)
>>> print(y)
2/3
# 使用小数创建
>>> Fraction('.25')
Fraction(1, 4)
>>> Fraction('1.25')
Fraction(5, 4)
# 运算
>>> x + y
Fraction(1, 1)
>>> x − y # Results are exact: numerator, denominator
Fraction(−1, 3)
>>> x * y
Fraction(2, 9)
注意: 虽然可以从float转变成 Fraction,但是有时还是无可避免的有精度丢失,毕竟float的精度是不准确的。
>>> (4.0 / 3).as_integer_ratio() # Precision loss from float
(6004799503160661, 4503599627370496)
5.3.3 Sets
a. 操作
#创建
set([1, 2, 3, 4]) # Built-in call (all)
{1, 2, 3, 4} # Newer set literals (2.7, 3.X)
>>> 'bob' in engineers # Is bob an engineer?
>>> S.add('alot') # Methods work as before
>
>>> S1 & {1, 3} # Intersection
>>> {1, 2, 3}.intersection((1, 3, 5))
>
>>> {1, 5, 3, 6} | S1 # Union
{1, 2, 3}.union([3, 4])
>>> S1 - {1, 3, 4} # Difference
>
>>> S1 > {1, 3} # Superset
>>> {1, 2, 3}.issubset(range(-5, 5)
# set comprehension
>>> {x ** 2 for x in [1, 2, 3, 4]} # 3.X/2.7 set comprehension
b. sets的特点
sets只能包含不可变对象,因为要被hash
frozenset
可以创建 immutable set
c. set的作用
- 去重
- 排除已有的
- 比较跟顺序无关的相等性
- 集合操作
5.3.4 Boolean
bool
也是一种数字类型, 是int的子集,只有0和1。
True和False
只是对0和1比较好看的表示方式而已,是重写了str
和repr
方法,本质还是数字。