Skip to content

Latest commit

 

History

History
329 lines (227 loc) · 8.15 KB

373-189618-[专业选修]深入浮点型数字.sy.md

File metadata and controls

329 lines (227 loc) · 8.15 KB
show version enable_checker
step
1.0
true

深入浮点型数字

回忆

  • Decimal是精确十进制类型的变量
    • 可以以字符串作为参数
    • 可以直接进行运算
    • 比Fraction更适合做基础
  • 如果精度不够
    • 可以把上下文中的 精度(prec)提高
    • 这样就可以体高精度了

图片描述

  • 例子里面有个1e-2 这是什么意思?🤪

Decimal 函数

  • Decimal 函数一定接收字符串型变量参数才能保持精确性
  • 如果接收浮点型参数无法保持精确性

图片描述

  • Fraction 和 Decimal 都可以保持精确性
  • 例子里面有个 $3e^{-1}$ 这是什么意思?🤪

图片描述

e

  • 使用 $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 包
  • 这里面有各种数学函数包
  • 还有什么函数呢?

help(math)

图片描述

  • 通过 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 和 nan

  • inf
    • infinity
    • 正无穷
  • nan
    • not a number
    • 不是数

图片描述

图片描述

  • 最大值 $1e308$ 再乘以 $10$
    • 得到了 float("inf")
    • 也是一个 float 型的值
  • 正无穷乘以 0
    • 可以得到 float("nan")
    • 因为他乘出来不好说具体是多少所以得到了 float("nan")
    • Not a Number
    • 不是数
  • 这些系统参数可以快速得到吗?

sys.float_info

图片描述

  • 数据含义

图片描述

  • 这些东西都是谁规定的呢?

浮点运算指令

  • 60年代
    • CDC公司的6000系列的旗舰6600

图片描述

  • 这台机器开始有了浮点运算指令
    • 浮点乘法
    • 浮点除法
    • 浮点加法
    • 满足60-bit的浮点数运算

图片描述

  • 当时Byte还没有作为一个存储单位固定下来
    • 也就还没有ieee-754
  • 不过
    • 754也在萌芽在此基础上酝酿

基础

  • 落实到底层
    • 数字电路是基于模拟电路的

图片描述

  • 至今也没有变化

总结

  • 这次了解科学计数法
  • 科学计数法分成有效数字和指数两块
  • 找到了双精度 double 型中绝对值最小和最大的数
  • 最后发现 int 型在大数方面有效数字超过了双精度?
  • 这可能吗?🤪
  • 下次再说 👋