Skip to content

Latest commit

 

History

History
406 lines (355 loc) · 11.5 KB

File metadata and controls

406 lines (355 loc) · 11.5 KB

2. 数值

2.1. 数值类型及其表示

Python数值类型优势:
相比C/C++避免了数值范围限制。

2.1.1. 数字型(整、浮、复、布)

2.1.1.1. 整数(整型数int)

  • 概念:所有非小数的数;

  • 计算机字面值表示方式:
    十进制表示:±0~9*直接表示。(-5, 0, 99999)
    二进制表示:0b + 0~1。(0b111, 0b101)
    八进制表示:0o + 0~7。(0o7, 0o10, 0o17)
    十六进制表示:0x + 0~9, A~F。(0x11, 0xff, 0xFF)a~f大小写均可

    • 注: Python输出打印的整数均以十进制打印, 其他进制输入只不过被转换成了二进制数存储,普通打印则是以十进制为标准
      示例:
    >>> 0b111
    7
    >>> 0o17
    15
    >>> 0xff
    255
  • int()函数

      1. 将其他类型数值转换为十进制整数
      int([x])
          将其他数值对象统一转换为整数  
      选项[x]:
          缺省参数默认为零, 
          x可以为整数(包括其他进制)、浮点数布尔数, 
          x不可为复数  

      示例(可在交互模式下测试):

      int()    #0, 缺省参数, int()==0
      int(3)   #3, 整数
      int(0b11)  #3, 二进制整数
      int(3.14)  #3, 浮点数
      int(bool())  #0, 布尔值
      int(bool(666))  #1, 布尔值
      1. 将表示数值的字符串转换为十进制整数
      int("obj"[, ase])
          将进制为ase的整型数obj字符串, 统一转换为十进制的int数字
      选项"obj"
          必须为表示"整型数的字符串"
          不可为浮点数复数布尔数True/False
      [ase]
          默认缺省参数为10, 表示该字符串整数的进制数

      示例:

      int("4")       # 4
      int("4", 10)   # 4
      int("0b100")   # 报错, 触发ValueError异常, 因为ase默认参数是10,无法解析
      int("0b100", 2) # 4
      
      int("100", 2)   # 4
      int("100")     # 100, ase缺省参数为10
      int("100") == int("100", 10)  # True
      int("100", 10)  # 100
      # 错误示例:
      int("3.14")  #不是整型数, 报错
      int(3.14)    #3, 正确
      int(100, 2)   #100不是字符串, 报错
      int("100", 2)  #4, 正确
  • 补充:其他进制与编码互相转换的函数
    整数 转换不同进制 字符串 的函数:

    hex(i)    转换为十六进制的字符串
    oct(i)    转换为八进制的字符串
    bin(i)    转换为二进制的字符串
    

    示例:

    >>> hex(31)  # 返回整数17使用十六进制表示的字符串
    '0x11'
    >>> oct(9)   # 返回整数17使用八进制表示的字符串
    '0o21'
    >>> bin(3)   # 返回整数17使用二进制表示的字符串
    '0b10001'

2.1.1.2. 浮点数float(浮点型数)

  • 字面值:
    小数形式:3.14, 3.1, 3., 0.14, .14
    科学计数法:小数 + e/E + 正负号 + 指数
>>> .14
0.14
>>> 3.14e-2
0.0314
>>> 3.14e8
314000000.0

不同于C/C++, 浮点型数无double类型

  • float()函数
float([x])
    将数字(除复数外)统一转换为浮点数
选项:
[x]:
    可以为数值(整数, 浮点数, 布尔值)
    以及表示整数和浮点数的字符串
float(3)       # 3.0
float(3.14)    # 3.14
float(False)   # 0.0
float("3")     # 3.0
float("3.14")  # 3.14
float("False") # 报错

2.1.1.3. 复数complex

  • 字面值:1j, (2j), 1+1J, 3-4J, (-100+100J)
  • 构成:实部(real)和虚部(image)
  • 特点:Python数据类型可以表示复数, 比其他语言更为丰富
>>> -1+9j
(-1+9j)
>>> 1+9j
(1+9j)
  • complex()函数
    complex(a,b) # a,b代表实部和虚部的值
>>> complex(1, 9)
(1+9j)

2.1.1.4. 布尔值bool

  • 字面值:True, False
    转换布尔值非零既真;
    布尔值与0/1字面值相等(如Ture == 1), 可以参与数值运算;
    True也在Python程序初始化时就创建并保留于对象池内, 使用结束对象不销毁;
# 布尔函数输入, 非零即真
>>> bool("123")  
Ture
>>> bool(2)
Ture

# 字面值相同, 但不属于相同对象
>>> print(True, 1, True==1, True is 1, id(True), id(1)) 
True 1 True False 140736271460688 140736271982992
262398640
>>> True == 6  # 布尔值字面值只等于0或1
False
>>> True + 1  # 可加减
2
  • bool()函数
bool(x)  # 不为零即为真
返回True  False, 可直接参与数值运算bool(x)返回假值的情况当x表示为零或空, 如下
bool()        # 无参数
bool(None)    # 空值
bool(False)   # 布尔假值
bool(0.0)     # 浮点数
bool(0j)      # 复数
bool('')      # 空字符串
bool(())      # 空元组
bool([])      # 空列表
bool({})      # 空字典
bool(set())   # 空集合

2.1.2. 空值None对象

概念:None是一个表示不存在的特殊对象, 空值对象
作用:用来占位;用来变量绑定

a = None
a = [None, None, 1]  # 该列表中占位, 列表见下一章

2.2. 数值间的运算

2.2.1. 常用运算函数

函数 输入参数 返回 作用
abs(x) x为4大数值 int/float 返回给定参数的绝对值
pow(x, y[, z]) x基数,y指数,[z]除数 int/float 指数计算,pow(x,y,z)结果等效于pow(x,y)%z
math.pow(x, y) x基数,y指数 float 指数计算
round(number[, ndigits]) number, 待处理数值;
ndigits, 缺省默认参数为None,默认时四舍五入返回为整数;
正数表示保留小数点后多少位进行四舍五入,负数则表示保留小数点前左多少位进行四舍五入,返回整数或浮点数
int/float 对数值进行四舍五入
abs(-9)   # 9

pow(2,3)  # 8
print(8 % 3)  # 2
pow(2,3,3)    # 2
import math  # 导入数学计算模块 
math.pow(2,3)  # 8.0

round(3.66, 1) # 3.7
# 字符串格式化语法,见下一章
'%.1f'%3.66    # '3.7'  "%.1f"%num相当于round(num, 1)

round(1234, -2) # 1200
round(1234.567, -1)  # 1230.0
round(1234.567, 0)   # 1235.0
round(1234.567, 1)   # 1234.6
round(1234, -1) # 1230
round(1234, 1) # 1234
round(1234, 0) # 1234
round(1234, 1) # 1234
round(1234)    # 1234

2.3. 运算及运算符

2.3.1. 算术运算符

所有的运算都遵循数学法则, 如5/2=2.5。

  • 算术运算符包括:

    +     加法
    -     减法
    *     乘法
    /     除法后都变成浮点数, 如4/2=2.0。注意python2中不遵循该规则
    //     地板除(除的结果去掉小数部分向下取整),如5//2=2, 3.25//1.5=2.0
    %     取余(也叫取模)
    **     幂运算
    

    Python计算优势:

    1. Python运算中有混合类型自动升级。如1+2.2=3.2
    2. 在表达式的运算过程中, 相比C/C++不损失精度, 如1/3*3=1.0

2.3.2. 运算符优先级:

()    # 1, 最高优先级,括号分组子表达式, 用"()"可以将表达式分组, "()"内的表达式先进行计算
**    # 2, 幂运算
*  /  //  %    # 3, 乘除运算
+  -  # 4, 加减运算

示例:

(1 + 3) * 3 ** 2 + 4 // 2
= 4 * 3 ** 2 + 4 // 2
= 4 * 9 + 4 // 2
= 36 + 2
= 38

2.3.3. 复合赋值运算符

y += x   ==>   y = y + x
y *= x   ==>   y = y * x
...
  • 小知识——增量赋值:
    在可变对象的增量赋值中,有可能提高运行效率,减少数据反复创建销毁,大量的计算过程中便能体现出来。
# 增量赋值有时可以避免生成新对象,这在后续需要学习的numpy维度数据操作中很常用
import numpy as np
L = [3]
print(id(L), L)  # 1973013544328 [3]
L *= 3
print(id(L), L)  # 1973013544328 [3, 3, 3]
L = L*3
print(id(L), L)  # 1973013543240 [3, 3, 3, 3, 3, 3, 3, 3, 3]
# id发生改变,新对象被创建,旧对象因引用计数为零被销毁析构

# numpy示例
X = np.array([1, 2, 3])
print(id(X), X)  # 2755056447040 [1 2 3]
X += 1
print(id(X), X)  # 2755056447040 [2 3 4]
X *= 3
print(id(X), X)  # 2755056447040 [ 6  9 12]
X = X * 3
print(id(X), X)  # 2755072558144 [18 27 36]
# id发生改变,新对象被创建,旧对象因引用计数为零被销毁析构

2.3.4. 比较运算符

包括:<<=>>===!=
返回:布尔类型的值TrueFalse
运算规则:多个比较运算符的运算规则, 从左到右
例如:

>>> 3>2<3
True
  • 了解:
    Python2中存在过内建函数cmp
    cmp(x,y) #比较x和y的大小, x<y返回-1, x=y返回0, x>y返回1
    Python3中该函数已被废弃(奥卡提姆剃须刀), 这也遵循了Python当初设计的简洁原则
    当然,可以写成这样
>>> x, y = 4, 2
>>> 0 if x==y else (-1 if x<y else 1 )   # 详细理解见后续章节流程控制
1
>>> 0 if x==y else int((x-y)/abs(x-y))
1

2.3.5. 位运算符

(此内容初学仅作了解)

& 按位运算符
| 按位运算符
^ 按位异或运算符
~ 按位取反运算符
<< 左移动运算符
>> 右移动运算符

以下实例演示了Python所有位运算符的操作: 示例:

a = 60            # 60 ==  0011 1100 
b = 13            # 13 ==  0000 1101

c = a & b;        # 12 ==  0000 1100     &找都为真的。 相加得2为1, 其余为0
c = a | b;        # 61 ==  0011 1101     |找都为假的。 相加的0为0, 其余为1
c = a ^ b;        # 49 ==  0011 0001     ^找一真一假的。相加得1为1,其余为0
c = ~a;           # -61 == 1100 0011     ~每一位取反。相当于-a-1,在一个有符号二进制数的补码形式。
c = a << 2;       # 240 == 1111 0000     <<指定左移两位, 高位丢弃, 低位补0。
c = a >> 2;       # 15 ==  0000 1111     >>指定右移两位, 补零

2.4. 运算误差问题汇总

2.4.1. 浮点数的减法误差

问题引入:如下比较有问题吗?

>>> 7/3 - 2 == 1/3
False

从数学角度来说,它们应该相等,可程序给出的结果并非如此,为什么会出现这样的情况?
验证:

# 构造函数int()会让得到的数值产生误差吗?不会
>>> int(3.14)==3
True

# 浮点数相减相除会产生误差吗?会
>>> 3.14 - 3
0.14000000000000012     # 损失精度
>>> 3.14 - 3.0
0.14000000000000012
>>> 3.14 - 3.00
0.14000000000000012

>>> 7/3
2.3333333333333335      # 最后一位不遵循四舍五入。
>>> 7/3 - 2
0.3333333333333335
>>> 1/3
0.3333333333333333      # 得到的是一个确定的数, 非无理数
>>> 1/3 == 0.3333333333333333    # 保留16位小数, 两者相等
True

>>> 3.25 % 1.5
0.25
>>> 3.26 % 1.5
0.2599999999999998      # 结果应该为0.26, 但损失了精度
>>> 3.25-3.25//1.5*1.5
0.25
>>> 3.26-3.26//1.5*1.5
0.2599999999999998

误差本质其实是浮点数值的二进制位运算处理, 是当前计算机理论模型框架下的一种缺陷, 期待这样的误差未来能被修复。

emmm..小思索:计算机存在误差, 这些因素究竟如何解决?当前,我们的计算也根本无法进行抽象概念的计算,如何解决?也许如此微小的进步,需要的是巨大的科学进步,创造真正的机器智能, 或是探索到宇宙本质。

2.4.2. round()函数的误差

round中亦存在误差。
如下示例:round结果应该是3.65≈3.7, 但返回3.6

>>> round(3.65,1)
3.6
>>> '%.1f'%3.65  # 字符串格式化语法,见下一章
'3.6'