show | version | enable_checker |
---|---|---|
step |
1.0 |
true |
- 浮点数的单词来自于float
- float 的意思是 浮动
- 浮动的东西是小数点
- 浮点数 就是 小数点可以浮动的 类型
- 浮点数 是 如何进行运算 的呢?🤔
- 小数使用基本上是 ok 的
- 可以观察到1/3的结果
- 被截取了小数
- 可以观察到1/3的结果
- 后面的计算结果没有问题
- 但有时候也会出问题
- 这显然不对!
- 观察数据类型
- 3 个
$0.1$ 相加等于$0.30000000000000004$ - 观察
$0.1$
- 这个字节状态存储的0.1算出来
- 确实比
$0.1$ 大
- 确实比
- 加在一起确实超过
$0.3$ 🤪
- 这里我们使用的是
- 双精度浮点数
- double
- 8-byte
- 我们先来看看
- 和 的 双精度二进制形态
-
$0.1+0.1+0.1$ 的双精度字节形态\x34\x33\x33\x33\x33\x33\xd3\x3f
- 8-byte
-
\x34\x33\x33\x33\x33\x33\xd3\x3f
对应十进制 $0.30000000000000004$ - 前后都能说通
- 可是,这个和
$0.1$ 到底是怎么加的呢?
- 首先获得
$0.1$ 的双精度浮点型的二进制形态
- 刨去前面的符号位和指数部分
- 还剩下总共 52 位 2 进制数
- 如上图选中的数字部分
- 还剩下总共 52 位 2 进制数
-
$1001100110011001100110011001100110011001100110011010$ - (可复制到剪切板)
-
分成两部分
- 有效数字
- 指数
-
有效数字
- 前面有个缺省的 1
- 把这 52 位 2 进制数前面补 1
- 并加上小数点
$1.1001100110011001100110011001100110011001100110011010$
- 指数部分
- -4
- 综合起来就是
-
$1.1001100110011001100110011001100110011001100110011010$ x 2-4
-
- 0.1原来的有效数字 乘以 3
- 得到新的 有效数字
- 此时的数值是原来的3倍
- 大致是0.3
- 数量级和原来差22
-
ieee-754要求第1位必须有个缺省的1
- 所以小数点要向左移动2位
- 由于是2进制数
- 小数点向左移动2位就相当于要除以 4
-
综合起来就是
- 要对有效数字
- 先✖3
- 再÷4
- 要对有效数字
- 先算有效数字
- 先粘贴有效数字部分
- 再✖3÷4
- 结果向上(ceil)取整
- 并转化为2进制(binary)
- 有效数字是(1.)0011001100110011001100110011001100110011001100110100
- 去掉红框中的1
- 保留后面的有效数字
- 然后转化为 16 进制
$0x3333333333334$
- 依然是 52 位 2 进制数
- 共 13 位 16 进制数
- 指数部分 加2
- 从3FB变成3FD
- 整体是
- 00111111 11010011 00110011 00110011 00110011 00110011 00110011 00110100
- 0x3FD3333333333334
- 可复制出来去binaryconvert.com验证
- 通过系统中的字节状态进行验证
- 与
$0.1+0.1+0.1$ 得到的$0.30000000000000004$
- 结果和0.3在尾数上差一
- 对比直接进行的二进制编码
- 确实出现了误差
- 可以手算这个过程么?
- 说干就干,走起来~
- 把后 52 位复制出来
- 先移位
- 相当于 乘以2
- 在 与原数相加
- 相当于 三次累加
- 第一步是移位
- 两个一样的数相加
- 左移 1 位
- 然后再加上自身
- 得到结果是尾数
- 尾数以
$1.xxx$ 开头- 向右移动 2 位
- 去掉开头的 1
- 结尾多出两位
- 有进位
- 保持 52 位 尾数
- 运算结果一致!!!
- 这次了解浮点类型变量
- 有两种表示法
- float 4-byte 单精度浮点型
- double 8-byte 双精度浮点型
- 浮点型特点
- 第一位都是符号
- 小数点都浮动
- 浮动程度由指数部分决定
- 尾数部分默认 1 开头
- 后面的小数部分是有效数字
- 这就是浮点类型的数据
- 为什么 会有 float和double
- 这样 存储数字的方法 呢?
- 整体是如何进化的呢?🤪
- 下次再说 👋