Python - 数值型
目录
数值类型
数字并不是一个真正的对象类型,而是一组类似类型的分类
python中数字有四种类型:
- bool (布尔):True,False;不是 true 和 false,也没有 YES, NO。
- int (整数),是正或负整数,不带小数点。如 1, 只有一种整数类型 int,表示为长整型;没有 python2 中的 Long。
- float (浮点数),由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250),如 1.23、3E-2;
- complex (复数),由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示,复数的实部a和虚部b都是浮点型。如 1 + 2j、 1.1 + 2.2j。
查看类型
>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
数值类型说明
bool
布尔对象 True/False 的本质是 两个指向
固定内存单元
的内置变量
>>> type(True), type(False)
(<type 'bool'>, <type 'bool'>)
>>> isinstance(True, int), isinstance(False, int)
(True, True)
>>> True == 1, False == 0
(True, True)
>>> True is 1, False is 0
(False, False)
从上面可以看出 True 或 False 的本质是 1 和 0,只是基于bool类型创建的对象,重写了其 __str__
和__repr__
魔术方法
创建
# 方式一: 通过字面量形式创建
>>> True
True
>>> False
False
# 方式二: 通过类型创建
"""
bool(x) -> bool
"""
>>> bool(0)
False
>>> bool(1)
True
运算
# 赋值运算:将变量名指向内置变量True/False对应的内存单元,至此可通过 变量名 操作此内存单元数据
>>> x = True
>>> y = False
### 身份运算,常用于比较两个对象是否指向同一个内存单元
>>> x is y
False
>>> x is not y
True
### 逻辑运算
# 与, 都为真为真
>>> x and y
False
# 或, 一个真即真
>>> x or y
True
# 非,总是隐式转换为布尔对象
>>> not x
False
真假测试
分支结构和循环结构中的条件测试何为真? 何为假?
对于布尔对象, False表示假, True表示真
-
对于数字对象, 0表示假, 非0表示真
-
对于其它对象, 空对象表示假, 非空对象表示真
-
对于比较运算, 真假与数学中的真假概念一致
-
对于身份运算, 真假取决于两个对象是否指向同一内存单元
-
对于逻辑运算, and都为真为真, or一个为真为真, not取反
# 假
>>> bool(False)
False
# 真
>>> bool(True)
True
# 假
>>> bool(0)
False
# 真
>>> bool(1)
True
# 真
>>> bool(-1)
True
# 假
>>> bool(None)
False
# 假
>>> bool('')
False
# 假
>>> bool([])
False
# 假
>>> bool(())
False
# 假
>>> bool(set())
False
# 假
>>> bool({})
False
# 真
>>> bool('521')
True
# 真
>>> bool(['5', '2', '1'])
True
# 真
>>> bool(('5', '2', '1'))
True
# 真
>>> bool({'5', '2', '1'})
True
# 真
>>> bool({'5': '5', '2': '2', '1': '1'})
True
# 真
>>> bool(1 < 2)
True
# 真
>>> bool(1 <= 2)
True
# 真
>>> bool(2 > 1)
True
# 真
>>> bool(2 >= 1)
True
# 真
>>> bool(1 < 2 < 5)
True
# 真
>>> bool(5 > 2 > 1)
True
# 真
>>> bool(5 >= 2 >= 1)
True
# 真
>>> 1 is 1
True
# 真
>>> bool(5 and 2 and 1)
True
# 真
>>> bool(5 or 2 or 0)
True
# 真
>>> bool(not 521)
False
int
- 整数包含正数,负数和0;
- 允许使用二进制,八进制,十六进制字面量表示;
- 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
如:-521, 521, 0, 无穷小~无穷大(只和内存有关)
对象创建
# 方式一: 通过字面量形式创建
>>> 521
521
# 方式二: 通过类型创建
"""
int(x=0) -> int or long
int(x, base=10) -> int or long
"""
>>> int('521')
521
>>> int('1000001001', base=2)
521
>>> int('1011', base=8)
521
>>> int(521)
521
>>> int('200', base=16)
521
进制
相关函数
函数 | 说明 |
---|---|
bin(number) | 将整数转换为二进制字符串并返回 |
oct(number) | 将整数转换为八进制字符串并返回 |
int(x, base=10) | 将base进制字符串x转换为十进制整数并返回 |
hex(number) | 将整数转换为十六进制字符串并返回 |
pow(x, y[, z]) | 计算x的y次方后选择性对z取模并返回 |
abs(number) | 计算数字number的绝对值并返回 |
round(number[, ndigits]) | 将数字number四舍五入保留ndigits位小数并返回 |
>>> number = 0xA0F # 十六进制
>>> number
2575
>>> number=0o37 # 八进制
>>> number
31
# 向内存申请一空闲内存单元存储521,并将变量名dec_num指向此内存单元的地址
# 十进制
>>> dec_num = 521
# 二进制
>>> bin_num = 0b1000001001
# 八进制
# for Python2
>>> oct_num = 01011
# for Python3
>>> oct_num = 0o1011
# 16进制
>>> hex_num = 0x209
>>> type(dec_num), type(bin_num), type(oct_num), type(hex_num)
(<type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>)
# 查看变量dec_num类型的定义
>>> help(dec_num)
# 查看变量dec_num类型的属性和方法
>>> dir(dec_num)
# bin(number)
>>> bin(521)
'0b1000001001'
# oct(number)
>>> oct(521)
'01011'
# int(x, base=10)
>>> int('1000001001', base=2)
521
>>> int('1011', base=8)
521
# hex(number)
>>> hex(521)
'0x209'
# pow(x, y[, z])
>>> 5 * pow(10, 2) + 2 * pow(10, 1) + 1 * pow(10, 0)
521
>>> 5 * 10 ** 2 + 2 * 10 ** 1 + 1 * 10 ** 0
521
# 求根: 方式一
>>> import math
>>> math.sqrt(521)
22.825424421026653
# 求根: 方式二
>>> pow(521, .5)
22.825424421026653
# 求根: 方式三
>>> 521 ** .5
22.825424421026653
# abs(number)
>>> abs(-521)
521
# round(number[, ndigits])
>>> round(5.21, 0)
5.0
进制转换
核心思想就是D进制满D向左进1位,也就是说从右到左的基数依次为d0~dn
# 十进制, 满十进一位
> 521
= 1 * 1 + 2 * 10 + 5 * 100
= 1*10^0 + 2*10^1 + 5*10^2
# 二进制, 满二进一位
> 1000001001
= 1*2^0 + 0*2^1 + 0*2^2 + 1*2^3 + 0*2^4 + 0*2^5 + 0*2^6 + 0*2^7 + 0*2^8 + 1*2^9
# 八进制, 满八进一位
> 1011
= 1*8^0 + 1*8^1 + 0*8^2 + 1*8^3
# 16进制, 满16进一位
# 0 1 2 3 4 5 6 7 8 9 a(10) b(11) c(12) d(13) e(14) f(15)
> 209
= 9*16^0 + 0*16^1 + 2*16^2
10 进制转 2 进制
dec_num = 10
res = ''
while True:
y = dec_num % 2; #取余
s = dec_num // 2; #商
res = str(y) + res
print('商:{0}, 余数:{1}'.format(s,y))
if(s == 0):
print(res)
break
dec_num = s
8 进制转 2 进制
一个8进制位最多用3个二进制位表示
>>> int('17',base=8)
15
>>> bin(15)
'0b1111'
八进制转二进制
# 17 -- 0b1111
oct_num = '17'
res = ''
for i in oct_num:
tmp_res = ''
int_i = int(i)
while True:
y = int_i % 2
s = int_i // 2
tmp_res = str(y) + tmp_res
print('商:{0}, 余数:{1}'.format(s,y))
if(s == 0):
z_num = 3 - len(tmp_res)
tmp_res = '0' * z_num + tmp_res
res = res + tmp_res
print(res)
break
int_i = s
print(res)
float
浮点数为包含小数部分的数字,同时允许使用单点,科学计数法的字面量表示
# 浮点数类型
# 5.21, .5, 5., 5.21e2/5.21E2, 512e-2/512E-2
# 向内存申请一空闲内存单元存储5.21并将变量名f指向此内存单元的地址
>>> f = 5.21
>>> type(f)
<type 'float'>
# 查看变量f类型的定义
>>> help(f)
# 查看变量f类型的属性和方法
>>> dir(f)
对象创建
# 方式一: 通过字面量形式创建
>>> 5.21
5.21
# 方式二: 通过类型创建
"""
float(x) -> floating point number
"""
>>> float(521)
521.0
精度丢失
浮点数转换二进制时可能出现死循环,CPU为了阻止此默认行为而导致的精度丢失是必然行为且不可控
# 问题: 浮点数运算为何会丢失精度?
>>> 0.2 + 0.4
0.6000000000000001
# 模拟: 浮点数转二进制通过不断乘2直至小数部分为0,然后倒序组合整数部分与0.组合即为二进制
"""
部分浮点数如0.2,0.4会导致转换过程死循环,CPU会在计算到固定位数时中断此行为,所以就出现了精度丢失的问题
"""
# 0.2转换为二进制模拟 0.0011...
0.2 * 2 = 0.4,整数部分为0,小数部分为0.4
0.4 * 2 = 0.8,整数部分为0,小数部分为0.8
0.8 * 2 = 1.6,整数部分为1,小数部分为0.6
0.6 * 2 = 1.2,整数部分为1,小数部分为0.2 # 无限循环
# 0.4转换为二进制模拟 0.0110...
0.4 * 2 = 0.8 整数部分为0,小数部分为0.8
0.8 * 2 = 1.6 整数部分为1,小数部分为0.6
0.6 * 2 = 1.2 整数部分为1,小数部分为0.2
0.2 * 2 = 0.4 整数部分为0,小数部分为0.4 # 无限循环
# 解决: 使用双精度浮点数或分数精确表示
# 方式一: 使用decimal.Decimal类转换为小数对象
"""
优点: 从代码层面模拟CPU算法支持精确到任意精度
缺点: 提升精度的同时会带来性能上的损耗
"""
>>> from decimal import Decimal
>>> Decimal('0.2') + Decimal('0.4')
Decimal('0.6')
# 方式二: 使用fractions.Fraction类转换为分子对象
>>> Fraction('0.2') + Fraction('0.4')
Fraction(3, 5)
In [24]: from fractions import Fraction
In [25]: Fraction(0.2) + Fraction(0.4)
Out[25]: Fraction(10808639105689191, 18014398509481984)
In [19]: 5.21e1
Out[19]: 52.1
In [20]: 5.21e2
Out[20]: 521.0
In [21]: 5.21e0
Out[21]: 5.21
In [22]: 5.21e5
Out[22]: 521000.0
精度扩展
Python2中会自动将大整数转换为长整型数并且以后缀l/L标识,但Python3中则隐藏了此默认行为
>>> import sys
# for Python2
>>> sys.maxint + 1
9223372036854775808L
# for Python3
>>> sys.maxsize + 1
9223372036854775808
complex
复数为包含实部和虚部(以 j 或 J 结尾)的数字
# 复数类型
# 100j
# 向内存申请一空闲内存单元存储0+100j并将变量名c指向此内存单元的地址
>>> c = 0+100j
>>> type(c)
<type 'complex'>
# 查看变量c类型的定义
>>> help(c)
# 查看变量c类型的属性和方法
>>> dir(c)
创建对象
>>> 0 + 100j
100j
方式二: 通过类型创建
# 方式一: 通过字面量形式创建
>>> 0 + 100j
100j
# 方式二: 通过类型创建
"""
complex(real[, imag]) -> complex number
"""
>>> complex(0, 100)
100j
In [11]: import sys
In [12]: sys.maxsize
Out[12]: 9223372036854775807
# 复数类型
# 100j
# 向内存申请一空闲内存单元存储0+100j并将变量名c指向此内存单元的地址
>>> c = 0+100j
>>> type(c)
<type 'complex'>
# 查看变量c类型的定义
>>> help(c)
# 查看变量c类型的属性和方法
>>> dir(c)
数值通用方法
运算符:
数学函数(三角函数、随机数等):
数学模块标准库:
数字类型转换
int(x)
将x转换为一个整数;float(x)
将x转换到一个浮点数;complex(x)
将x转换到一个复数,实数部分为 x,虚数部分为 0;complex(x, y)
将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式;
>>> a = 1.0
>>> int(a)
1
基本数字运算
-
在整数除法中,除法
/
总是返回一个浮点数;如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符//
; -
//
得到的并不一定是整数类型的数,它与分母分子的数据类型有关系; -
+
,-
,*
,/
-
**
:幂运算;
>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # 总是返回一个浮点数
1.6
>>> 17 / 3 # 整数除法返回浮点型
5.666666666666667
>>>
>>> 17 // 3 # 整数除法返回向下取整后的结果
5
>>> 17 % 3 # %操作符返回除法的余数
2
>>> 5 * 3 + 2
17
>>> 5 ** 2 # 5 的平方
25
对象属性、方法
对象
方法 | 版本 | 说明 |
---|---|---|
.bit_length() | 计算数字二进制位数并返回 | |
.as_integer_ratio() | 将浮点数转换为分数并以元祖形式返回 |
# .bit_length()
# 方式一: 低效率
>>> len(bin(x)) - 2
10
# 方式二: 高效率
>>> x.bit_length()
10
# .as_integer_ratio()
>>> z.as_integer_ratio()
(5865938514650071, 1125899906842624)