show | version | enable_checker |
---|---|---|
step |
1.0 |
true |
- Decimal是精确十进制类型的变量
- 可以以字符串作为参数
- 可以直接进行运算
- 比Fraction更适合做基础
- 如果精度不够
- 可以把上下文中的 精度(prec)提高
- 这样就可以体高精度了
- 例子里面有个1e-2 这是什么意思?🤪
- Decimal 函数一定接收字符串型变量参数才能保持精确性
- 如果接收浮点型参数无法保持精确性
- Fraction 和 Decimal 都可以保持精确性
- 例子里面有个
$3e^{-1}$ 这是什么意思?🤪
- 使用
$3e^{-1}$
- 第一个符号表示当前数字的正负
- 第二个符号表示十的指数
-
$-47e^{-2}$ =$-47 × 10^{-2}$ - 这些都是float
- 小数点可以浮动的
- 浮点数
- 不过要注意浮点型的精度问题
- 浮点型有效数字是有限的
- 有些内容会被四舍五入
- 想要精确十进制数怎么办来着?
- decimal.Decimal()函数
- 好像精准十进制和浮点型并不相等
- 为什么呢?
- 这就回到浮点型的存储方式了
- 还记得 ieee754 么
- 精确的 0.1 是无法使用 8 字节 2 进制小数形式表示的
- 确实不相等
- 0.1 在二进制中是一个无限循环小数
- 如果用 ieee754 的方式来存储
- 有效数字肯定要进行四舍五入
- 得到的值就不是 0.1 了
- 那这种情况怎么办呢?
- 与其判断相等不如找到差值
- 想要得到差值就要做减法
- 想要做减法就对操作数类型有要求
- 在统一了减法运算符的两个操作数的类型之后
- 如果他们之间的差值
- 小于 10 的-6 次方
- 也可以认为他们相等
- 具体精度可以调节
- 比如调整为 1e-12
- 专门有一套理论
- 叫计算数学
- 这种表示法是科学计数法
- 一般来说小数点前面有一个数字
- 后面有尾数
- 再乘以指数
- 但是最终还是用 2 进制的方式存储的
- 有了这个我们可以算点复杂的东西了
- 假设正五边形的边长为 a
- area =
$\frac{5*a^{2}}{4 * tan\frac{π}{5}}$ - 这就是面积公式
import math
a = eval(input("请输入边长:"))
area = 5*a*a/(4*math.tan(math.pi/5)
- 这里面就涉及到了 math 这个 module 包
- 这里面有各种数学函数包
- 还有什么函数呢?
- 通过 import 可以把这个包引入进来
- 以上就是我们可以看到的函数
- 看名字你知道他们含义么?
- 这些都是可以用在浮点型运算里面的函数
- 但是浮点型数字究竟是如何存储的呢?
-
$0.5$ =
$2^{-1}$ -
$0.625$ =
$2^{-1} + 2^{-3}$ =
$1 × 2^{-1} + 0 x 2^{-2} + 1 × 2^{-3}$ =$(0.101)_{2 进制}$
-
$0.1$ =
$2^{-4} + 2^{-5} + 2^{-8} + 2^{-9}$ ...=
$0 × 2^{-1} + 0 × 2^{-2} + 0 × 2^{-3} + 1 × 2^{-4} + 1 × 2^{-5}$ ...$(0.000110011...)_{2 进制}$ -
$0.1$ 是无法找到绝对对应的二进制数
- 最终还是落实到浮点数形式进行存储
- 三部分
- 正负号
- 指数
- 尾数
- p 之前是有效数字
- p 之后是指数
- 如果是
$10$ 的$-347$ 次方- 就看不到了
- 无法记录
- 变成了 0
- 具体最小多小能存的下呢?
- 这个规则叫做
$ieee-754$ - 是从 c 语言的时候就定下来的
- 指数部分最小
- 当指数部分为 0 时
- 尾数开头的 1 取消
- 尾数如果全零就是零
- 尾数部分最小只有最后 1 位
- 63 个
$0$ ,1 个$1$ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
- 验证一下
- 这就是绝对值最小的浮点数
- 绝对值最大的浮点数是多少呢?
- 尝试指数全 1
- 指数全 1 的结果是 NaN
- Not a Number
- 不是一个数字
- 看来指数不能全 1
- 继续尝试
- 从指数全 1 减去 1
- 得到下图的指数状态
- 有效数字部分都是 1
$1.79769313486231570814527423732 * 10^{308}$ - 验证一下
- 这个数值是可以得到的
- 但为什么加 1 没有效果
- 因为是浮点运算
- 所以需要移位才能相加
- 在 $10$ 的 $308$ 次方面前
- 1 一移位就变成了 0 了
- 但是如果能够把尾数最后 1 位加 1
- 就直接进上去了
- 结果是 inf 正无穷
- infinite
- 就是我们所说的正无穷
- 如果我还想往上加可能么?
- 用浮点型是不行了
- 改成整型
- 一行 80 个字符
- 3 行多大概 308 个字符
- 不但可以乘以 10
- 居然可以来个最大值的乘方
- python 肯定对 int 整型做了些什么
- 这就要查看 python 的源代码了
- 我们回到浮点型
- inf
- infinity
- 正无穷
- nan
- not a number
- 不是数
- 最大值
$1e308$ 再乘以$10$ - 得到了 float("inf")
- 也是一个 float 型的值
- 正无穷乘以 0
- 可以得到 float("nan")
- 因为他乘出来不好说具体是多少所以得到了 float("nan")
- Not a Number
- 不是数
- 这些系统参数可以快速得到吗?
- 数据含义
- 这些东西都是谁规定的呢?
- 60年代
- CDC公司的6000系列的旗舰6600
- 这台机器开始有了浮点运算指令
- 浮点乘法
- 浮点除法
- 浮点加法
- 满足60-bit的浮点数运算
- 当时Byte还没有作为一个存储单位固定下来
- 也就还没有ieee-754
- 不过
- 754也在萌芽在此基础上酝酿
- 落实到底层
- 数字电路是基于模拟电路的
- 至今也没有变化
- 这次了解科学计数法
- 科学计数法分成有效数字和指数两块
- 找到了双精度 double 型中绝对值最小和最大的数
- 最后发现 int 型在大数方面有效数字超过了双精度?
- 这可能吗?🤪
- 下次再说 👋