深入浅出计算机组成原理
徐文浩
bothub创始人
立即订阅
13019 人已学习
课程目录
已完结 62 讲
0/4登录后,你可以任选4讲全文学习。
入门篇 (5讲)
开篇词 | 为什么你需要学习计算机组成原理?
免费
01 | 冯·诺依曼体系结构:计算机组成的金字塔
02 | 给你一张知识地图,计算机组成原理应该这么学
03 | 通过你的CPU主频,我们来谈谈“性能”究竟是什么?
04 | 穿越功耗墙,我们该从哪些方面提升“性能”?
原理篇:指令和运算 (12讲)
05 | 计算机指令:让我们试试用纸带编程
06 | 指令跳转:原来if...else就是goto
07 | 函数调用:为什么会发生stack overflow?
08 | ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?
09 | 程序装载:“640K内存”真的不够用么?
10 | 动态链接:程序内部的“共享单车”
11 | 二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?
12 | 理解电路:从电报机到门电路,我们如何做到“千里传信”?
13 | 加法器:如何像搭乐高一样搭电路(上)?
14 | 乘法器:如何像搭乐高一样搭电路(下)?
15 | 浮点数和定点数(上):怎么用有限的Bit表示尽可能多的信息?
16 | 浮点数和定点数(下):深入理解浮点数到底有什么用?
原理篇:处理器 (18讲)
17 | 建立数据通路(上):指令+运算=CPU
18 | 建立数据通路(中):指令+运算=CPU
19 | 建立数据通路(下):指令+运算=CPU
20 | 面向流水线的指令设计(上):一心多用的现代CPU
21 | 面向流水线的指令设计(下):奔腾4是怎么失败的?
22 | 冒险和预测(一):hazard是“危”也是“机”
23 | 冒险和预测(二):流水线里的接力赛
24 | 冒险和预测(三):CPU里的“线程池”
25 | 冒险和预测(四):今天下雨了,明天还会下雨么?
26 | Superscalar和VLIW:如何让CPU的吞吐率超过1?
27 | SIMD:如何加速矩阵乘法?
28 | 异常和中断:程序出错了怎么办?
29 | CISC和RISC:为什么手机芯片都是ARM?
30 | GPU(上):为什么玩游戏需要使用GPU?
31 | GPU(下):为什么深度学习需要使用GPU?
32 | FPGA和ASIC:计算机体系结构的黄金时代
33 | 解读TPU:设计和拆解一块ASIC芯片
34 | 理解虚拟机:你在云上拿到的计算机是什么样的?
原理篇:存储与I/O系统 (17讲)
35 | 存储器层次结构全景:数据存储的大金字塔长什么样?
36 | 局部性原理:数据库性能跟不上,加个缓存就好了?
37 | 高速缓存(上):“4毫秒”究竟值多少钱?
38 | 高速缓存(下):你确定你的数据更新了么?
39 | MESI协议:如何让多核CPU的高速缓存保持一致?
40 | 理解内存(上):虚拟内存和内存保护是什么?
41 | 理解内存(下):解析TLB和内存保护
42 | 总线:计算机内部的高速公路
43 | 输入输出设备:我们并不是只能用灯泡显示“0”和“1”
44 | 理解IO_WAIT:I/O性能到底是怎么回事儿?
45 | 机械硬盘:Google早期用过的“黑科技”
46 | SSD硬盘(上):如何完成性能优化的KPI?
47 | SSD硬盘(下):如何完成性能优化的KPI?
48 | DMA:为什么Kafka这么快?
49 | 数据完整性(上):硬件坏了怎么办?
50 | 数据完整性(下):如何还原犯罪现场?
51 | 分布式计算:如果所有人的大脑都联网会怎样?
应用篇 (5讲)
52 | 设计大型DMP系统(上):MongoDB并不是什么灵丹妙药
53 | 设计大型DMP系统(下):SSD拯救了所有的DBA
54 | 理解Disruptor(上):带你体会CPU高速缓存的风驰电掣
55 | 理解Disruptor(下):不需要换挡和踩刹车的CPU,有多快?
结束语 | 知也无涯,愿你也享受发现的乐趣
免费
答疑与加餐 (5讲)
特别加餐 | 我在2019年F8大会的两日见闻录
FAQ第一期 | 学与不学,知识就在那里,不如就先学好了
用户故事 | 赵文海:怕什么真理无穷,进一寸有一寸的欢喜
FAQ第二期 | 世界上第一个编程语言是怎么来的?
特别加餐 | 我的一天怎么过?
深入浅出计算机组成原理
登录|注册

16 | 浮点数和定点数(下):深入理解浮点数到底有什么用?

徐文浩 2019-05-31
上一讲,我们讲了用“浮点数”这样的数据形式,来表示一个不能确定大小的数据范围。浮点数可以大到 ,也可以小到 这样的数值。同时,我们也发现,其实我们平时写的 0.1、0.2 并不是精确的数值,只是一个近似值。只有 0.5 这样,可以表示成 这种形式的,才是一个精确的浮点数。
你是不是感到很疑惑,浮点数的近似值究竟是怎么算出来的?浮点数的加法计算又是怎么回事儿?在实践应用中,我们怎么才用好浮点数呢?这一节,我们就一起来看这几个问题。

浮点数的二进制转化

我们首先来看,十进制的浮点数怎么表示成二进制。
我们输入一个任意的十进制浮点数,背后都会对应一个二进制表示。比方说,我们输入了一个十进制浮点数 9.1。那么按照之前的讲解,在二进制里面,我们应该把它变成一个“符号位 s+ 指数位 e+ 有效位数 f”的组合。第一步,我们要做的,就是把这个数变成二进制。
首先,我们把这个数的整数部分,变成一个二进制。这个我们前面讲二进制的时候已经讲过了。这里的 9,换算之后就是 1001。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入浅出计算机组成原理》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(37)

  • 有米
    decimal是如何实现保证不丢精度呢?
    2019-05-31
    3
    16
  • 一步
    老师 ,这里我用 JS 代码实验了一下,JS 中的数值类型都是 IEEE754实现的浮点数类型:
        let a = 20000000;
        let b = 1;
        let c = a + b;
        console.log("c is " + c);
        let d = c - a;
        console.log("d is " + d);
    输出是:
    // "c is 20000001"
    // "d is 1"

    然后2千万个数相加:
    let result = 0;
    for (let j = 0; j < 20000000; j++) {
      result ++;
    };
    console.log('result', result)
    // result 20000000

    这里都是正确的,是 自己实现了 Kahan Summation 算法吗 ? 还是其他的原因?

    作者回复: 因为js里面你用的是64位的float啦,所以精度不再是1600万分之1了,你可以自己看看64位的精度应该是多少,试试看是不是有一样的问题。

    2019-06-06
    5
  • 小木匠
    老师,在Kahan 算法里,如果累积的损失精度c也不能达到1600万的条件,是不是也就不能被累加呢?比如做1亿6千万零9次加1计算,这9次是不是也就加不上了呢
    2019-06-14
    3
  • 有铭
    decimal难道就是所谓定点数?Java里的BigDecimal的原理是什么?
    2019-05-31
    3
  • Deecyn
    老师你好,

    对于 Kahan Summation 算法的这段 Java 代码:

    public class KahanSummation {
      public static void main(String[] args) {
        float sum = 0.0f;
        float c = 0.0f;
        for (int i = 0; i < 20000000; i++) {
         float x = 1.0f;
         float y = x - c;
         float t = sum + y;
         c = (t-sum)-y;
         sum = t;
        }
        System.out.println("sum is " + sum);
      }
    }

    当我把 i 改成循环到 2 亿左右的数,如 199999998、200000004,结果就会丢失精度,累加和总会是 2 亿,请问这是什么问题呢?
    2019-10-11
    1
    2
  • DreamItPossible
    课后思考题解答:
    首先,64位浮点数的表示方法如下:符号位是1位,指数部分为11位,尾数部分为52位;
    其次,应用本节的可知,当做加法的两个64位的浮点数的指数位相差52位后,较小的那个数就会因为要右移53位导致有效位数完全丢失;
    最后,精度缺失问题同样可以使用`Kahan Summation`算法来补偿;
    2019-08-15
    2
  • Junho
    老师好。平时会听说一种说法:在现代CPU下,定点数的执行效率比浮点数慢一到两个数量级。不知这个说法是否合理?如果合理的话,原理是什么呢?
    对于这两种表示法,在工作中的应用:游戏中涉及要求计算一致性的场合,如王者荣耀的网络同步方案。
    王者的同步方案是帧同步,在这个方案下,需要确保逻辑层的所有计算,在所有硬件下都是完全一致的,否则同步就会出现灾难性的后果。
    据找得到的资料,王者官方的分享是说,他们是用分数来代替浮点数的(分子和分母分别用整数表示),但没提及不用定点数的缘由。
    倒是腾讯另外某位技术专家,就提及了浮点数与定点数在执行效率上的差异,但没涉及原理说明,所以想请教一下老师这个问题。谢谢!
    2019-06-20
    3
    2
  • humor
    对于64位的符点数,符号位是52位,所以应该是如果两个相差2^53倍及以上的数相加,较小的数会完全丢失吧。
    2019-05-31
    2
  • 初心丶可曾記
    64位浮点数,有效位是52位,所以相差2^53会丢失较小的数
    2019-05-31
    2
  • supermouse
    老师,我想问一个问题,为什么19000000.0f+1.0f=19000000.0f,而19000002.0f+1.0f=19000004.0f?(数字后面跟个f代表这个数是float类型)
    19000000.0f+1.0f=19000000.0f 我能理解,因为大数吃小数,在对阶的时候 1.0f 的有效数位右移了 24 位导致精度损失,但是 19000002.0f+1.0f=19000004.0f 的结果为什么不是 19000002.0f 而是 19000004.0f呢?
    2019-11-05
    1
  • 活的潇洒
    过去的两个月工作有点忙,现在有时间回来开始补笔记啦:
    day16 笔记:https://www.cnblogs.com/luoahong/p/11321590.html
    2019-08-21
    1
  • Knight²º¹⁸
    国内Wikipedia访问不了啊,不是每个人都有vpn吧
    2019-06-17
    1
  • -W.LI-
    老师好!我能说我没看懂么。。。f怎么算知道了e那个3怎么来的。9.1那个。。
    2019-06-16
    1
    1
  • 逍遥思
    对Kahan Summation算法的理解:

    x,本轮要加的数
    第一个c,截止上一轮损失的精度
    第二个c,截止本轮损失的精度
    y,本轮要加的数与之前累计损失的精度之和
    前两个sum,上一轮的求和结果
    t和第三个sum,本轮的求和结果
    2019-06-16
    1
  • senekis
    老师,我使用了IEEE754的网站,输入浮点数9.1,得到结果:
    010000010 0010 0011001100110011 010
    而按照老师的算法, 得到的结果是:
    010000010 0010 0011001100110011 001
    差了一位,这是为什么呢?是使用方法不正确吗?
    推算了N次也没有对上,求老师给答个疑~!谢谢老师!
    2019-06-01
    3
    1
  • 小广
    吴老师好,既然9.1按浮点数合适存储起来的时候,精度已经损失了,那为什么在程序里面定义了一个变量的值为9.1后再打印结果,它还是显示9.1,而不是那个在浮点数格式中存储的不精确的的小数位很长的数呢?
    2019-10-31
  • 布丁国王
    010000010 0010 0011001100110011 001 这个二进制转十进制难道不是1091672473吗???请问9.09999942779541015625这个数是怎么来的啊???
    2019-10-23
  • prader
    1 因为浮点书在计算集中的二进制表示形式,所以在进行浮点数运算的时候,存在精度丢失的问题,为解决这个问题,可以使用软件层面的 kahan summation 算法。就是每次运算的时候,用先取到丢失的精度(通过减法),然把丢失的精度加到总和上去。
    2019-09-16
  • 小先生
    请教,为什么 1.3 + 1.6 就不会是近似数?
    2019-08-06
  • 蒋旺Foo
    Kahan summation 最后一次相加的精度一定会有损失。
    2019-08-03
收起评论
37
返回
顶部