Python基础 C-02 数据类型-基本数据类型-Number(数字)

数据类型-基本数据类型-Number(数字)

一、数字类型(number)的分类

Python 支持三种不同的数值类型:

  • 整型(int) - 通常被称为是整型或整数,是正或负整数,不带小数点。(注意:Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。)

  • 浮点型(float) - 浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 10 ** 2 = 250)

f1 = 1.23 
f2 = 2.5e2  #250.0
f3 = 3e-2   #0.03
  • 复数(complex) - 复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。如 1 + 2j、 1.1 + 2.2j

二、整数

2.1、什么是整数?

  • Python可以处理任意长度的整数,也包括负整数。

2.1、整数分类

  • int(整型)-说明:在32位及机器上,整数的位数位32位,取值范围(-231~231-1),在64位机器上,取值范围为(-263~263-1)。

注意:以上范围只在2.x版本中,在3.x中int长度理论上是无限的。

  • long(长整型)-说明:Python的长整型没有指定位宽,故没有限制长整数数值的大小,但实际上由于机器内存有限。我们使用的长整数数值不可能无限大。自Python2.2起,如果整数发生溢出,Python会自动将数据转换成为长整数,所以如今长整数数据后面不加字母L也不会导致严重后果了。

注意:Python3没有long类型了,全部都是int。

2.2、整数进制

2.2.1、整数不同进制的表示方式
  • Python中int默认是十进制,此外也支持二进制、八进制、十六进制表示。
    Python3中用不同方式定义变量a,a的实际值为10。如下:
    [外链图片转存失败(img-oXQctYpB-1568903229450)(evernotecid://80031049-E486-4FD3-9EC6-7B083434A989/appyinxiangcom/1518045/ENResource/p902)]
2.2.2、不同进制间的相互转换
  • 十进制转二进制方法bin(): binary 二进制的
>>> bin(10)
'0b1010'
  • 十进制转八进制方法oct(): octonary 八进制的
>>> oct(10)
'0o12'
  • 十进制转十六进制方法hex():hexadecimal 十六进制的
>>> hex(10)
'0xa'

三、浮点数

3.1、浮点数

  • 浮点数由整数部分与小数部分组成。浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)

3.2、浮点数运算争议和限制

  • 浮点数在计算机硬件中表示为以 2 为基数(二进制)的小数。

举例而言,十进制的小 0.125 等于 1/10 + 2/100 + 5/1000 。
同理,二进制的小数 0.001 等于0/2 + 0/4 + 1/8。
这两个小数具有相同的值,唯一真正的区别是第一个是以 10 为基数的小数表示法,第二个则是 2 为基数。

  • 不幸的是,大多数的十进制小数都不能精确地表示为二进制小数。这导致在大多数情况下,你输入的十进制浮点数都只能近似地以二进制浮点数形式储存在计算机中。

用十进制来理解这个问题显得更加容易一些。
考虑分数 1/3 。我们可以得到它在十进制下的一个近似值 0.3 或者更近似 0.33 或者更近似 0.333 以此类推。结果是无论你写下多少的数字,它都永远不会等于 1/3 ,只是更加更加地接近 1/3 。
同样的道理,无论你使用多少位以 2 为基数的数码,十进制的 0.1 都无法精确地表示为一个以 2 为基数的小数。 在以 2 为基数的情况下, 1/10 是一个无限循环小数
0.0001100110011001100110011001100110011001100110011...
在任何一个位置停下,你都只能得到一个近似值。因此,在今天的大部分架构上,浮点数都只能近似地使用二进制小数表示,对应分数的分子使用每 8 字节的前 53 位表示,分母则表示为 2 的幂次。在 1/10 这个例子中,相应的二进制分数是 3602879701896397 / 2 ** 55 ,它很接近 1/10 ,但并不是 1/10 。

  • 大部分用户都不会意识到这个差异的存在,因为 Python 只会打印计算机中存储的二进制值的十进制近似值。在大部分计算机中,如果 Python 想把 0.1 的二进制对应的精确十进制打印出来,将会变成这样
>>> 0.1
0.1000000000000000055511151231257827021181583404541015625

这比大多数人认为有用的数字更多,因此Python通过显示舍入值来保持可管理的位数

>>>
>>> 1 / 10
0.1

牢记,即使输出的结果看起来好像就是 1/10 的精确值,实际储存的值只是最接近 1/10 的计算机可表示的二进制分数。

  • 有趣的是,有许多不同的十进制数共享相同的最接近的近似二进制小数。例如,
    0.1 、 0.10000000000000001 、0.1000000000000000055511151231257827021181583404541015625全都近似于 3602879701896397 / 2 ** 55 。由于所有这些十进制值都具有相同的近似值,因此可以显示其中任何一个,同时仍然保留不变的 eval(repr(x)) == x 。

在历史上,Python 提示符和内置的 repr() 函数会选择具有 17 位有效数字的来显示,即 0.10000000000000001。 从 Python 3.1 开始,Python(在大多数系统上)现在能够选择这些表示中最短的并简单地显示 0.1 。

请注意这种情况是二进制浮点数的本质特性:它不是 Python 的错误,也不是你代码中的错误。 你会在所有支持你的硬件中的浮点运算的语言中发现同样的情况(虽然某些语言在默认状态或所有输出模块下都不会 显示 这种差异)。

表示性错误

表示性错误 是指某些(其实是大多数)十进制小数无法以二进制(以 2 为基数的计数制)精确表示这一事实造成的错误。 这就是为什么 Python(或者 Perl、C、C++、Java、Fortran 以及许多其他语言)经常不会显示你所期待的精确十进制数值的主要原因。

为什么会这样? 1/10 是无法用二进制小数精确表示的。 目前(2000年11月)几乎所有使用 IEEE-754 浮点运算标准的机器以及几乎所有系统平台都会将 Python 浮点数映射为 IEEE-754 “双精度类型”。 754 双精度类型包含 53 位精度,因此在输入时,计算会尽量将 0.1 转换为以 J/2**N 形式所能表示的最接近分数,其中 J 为恰好包含 53 个二进制位的整数。 重新将
1 / 10 ~= J / (2**N)
写为
J ~= 2**N / 10
并且由于 J 恰好有 53 位 (即 >= 2**52< 2**53),N 的最佳值为 56

>>> 2**52 <=  2**56 // 10  < 2**53
True

也就是说,56 是唯一的 N 值能令 J 恰好有 53 位。 这样 J 的最佳可能值就是经过舍入的商:

>>>
>>> q, r = divmod(2**56, 10)
>>> r
6

由于余数超过 10 的一半,最佳近似值可通过四舍五入获得:

>>>
>>> q+1
7205759403792794

这样在 754 双精度下 1/10 的最佳近似值为:
7205759403792794 / 2 ** 56
分子和分母都除以二则结果小数为:
3602879701896397 / 2 ** 55
请注意由于我们做了向上舍入,这个结果实际上略大于 1/10;如果我们没有向上舍入,则商将会略小于 1/10。 但无论如何它都不会是 精确的 1/10!

因此计算永远不会“看到”1/10:它实际看到的就是上面所给出的小数,它所能达到的最佳 754 双精度近似值:

>>>
>>> 0.1 * 2 ** 55
3602879701896397.0

如果我们将该小数乘以 10**55,我们可以看到该值输出为 55 位的十进制数:

>>>
>>> 3602879701896397 * 10 ** 55 // 2 ** 55
1000000000000000055511151231257827021181583404541015625

这意味着存储在计算机中的确切数值等于十进制数值 0.1000000000000000055511151231257827021181583404541015625。 许多语言(包括较旧版本的 Python)都不会显示这个完整的十进制数值,而是将结果舍入为 17 位有效数字:

>>>
>>> format(0.1, '.17f')
'0.10000000000000001'

fractions 和 decimal 模块可令进行此类计算更加容易:

>>>
>>> from decimal import Decimal
>>> from fractions import Fraction

>>> Fraction.from_float(0.1)
Fraction(3602879701896397, 36028797018963968)

>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)

>>> Decimal.from_float(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

>>> format(Decimal.from_float(0.1), '.17')
'0.10000000000000001'

3.3、浮点数运算总结

  • python是以双精度(64)位来保存浮点数,多余的位会被截掉。在python中,一共用多少位的精度来表示一个浮点数( 53):
a = 2.1
b = 4.2
c = a + b
print(c)
print(c == 6.3)
# 运行结果:
6.300000000000001
False
  • 在不同的机器上浮点运算的结果可能会不一样。在整数除法中,除法 / 总是返回一个浮点数
>>> 8 / 5  # 总是返回一个浮点数
1.6
>>> 17 / 3  # 整数除法返回浮点型
5.666666666666667
  • 不同类型的数混合运算时会将整数转换为浮点数:
>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5
  • print %f 默认显示小数后6位
>>> print("%f" % 1.500)
1.500000

3.4、浮点数的精度补充

如果需要更加精确,并能容忍一定的性能损耗,可以使用 decimal 模块:from decimal

import Decimal
a = Decimal('2.1')
b = Decimal('4.2')
c = a + b
print(c)
print(c == Decimal('6.3'))
# 运行结果:
6.3
TrueDecimal

对象会像普通浮点数一样,支持所有的常用数学运算。 打印或者进行字符串格式化时,跟普通浮点数没有区别。讨论decimal 模块实现了IBM的“通用小数运算规范”。Python新手会倾向于使用 decimal 模块来处理浮点数的精确运算。 然而,先理解你的应用程序目的是非常重要的。 如果你是在做科学计算或工程领域的计算、电脑绘图,或者是科学领域的大多数运算, 那么使用普通的浮点类型是比较普遍的做法。 其中一个原因是,在真实世界中很少会要求精确到普通浮点数能提供的17位精度。 因此,计算过程中的那么一点点的误差是被允许的。 第二点就是,原生的浮点数计算要快的多-有时候你在执行大量运算的时候速度也是非常重要的。即便如此,却不能完全忽略误差。数学家花了大量时间去研究各类算法,有些处理误差会比其他方法更好。 也得注意下减法删除以及大数和小数的加分运算所带来的影响。比如:

nums = [1.23e+18, 1, -1.23e+18]
print(sum(nums))
0.0

上面的错误可以利用 math.fsum() 所提供的更精确计算能力来解决:

import math
nums = [1.23e+18, 1, -1.23e+18]
print(math.fsum(nums))

1.0总的来说, decimal 模块主要用在涉及到金融的领域。 在这类程序中,哪怕是一点小小的误差在计算过程中蔓延都是不允许的。当Python和数据库打交道的时候,也通常会遇到 Decimal 对象,通常也是在处理金融数据的时候。

四、复数

复数:实数部分和虚数部分构成
后续补充

五、整数相关库方法介绍

方法列举

类型函数返回值 ( 描述 )
数学函数abs(x)返回数字的绝对值,如abs(-10) 返回 10
fabs(x)返回数字的绝对值,如math.fabs(-10) 返回10.0
ceil(x)返回数字的上入整数,如math.ceil(4.1) 返回 5
floor(x)返回数字的下舍整数,如math.floor(4.9)返回 4
modf(x)返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。#返回整数部分与小数部分 print(math.modf(22.3)) 返回(0.3000000000000007, 22.0)
round(x [,n])返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。print(round(3.456, 2)) 返回 3.46
max(x1, x2,…)返回给定参数的最大值,参数可以为序列。 #返回给定参数的最大值print(max(1,2,3,4,5,6,7,8))
min(x1, x2,…)返回给定参数的最小值,参数可以为序列。 #返回给定参数的最小值print(min(1,2,3,4,5,6,7,8))
pow(x, y)x**y 运算后的值。
sqrt(x)返回数字x的平方根。
exp(x)返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
log(x)如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x)返回以10为基数的x的对数,如math.log10(100)返回 2.0
cmp(x, y)如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃 。使用 使用 (x>y)-(x<y) 替换。
转换函数int()print(int(1.9), int(“123”), int("-123")) 返回1 123 -123
float()print(float(1), float(“12.3”)) 返回 1.0 12.3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值