V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
m30102
V2EX  ›  职场话题

那些能手写各种排序的人能手写数的补码吗?比如 -1.234 的补码。

  •  
  •   m30102 · 2020-09-25 09:26:10 +08:00 · 3742 次点击
    这是一个创建于 1524 天前的主题,其中的信息可能已经有所发展或是发生改变。
    23 条回复    2020-09-26 13:53:51 +08:00
    whileFalse
        1
    whileFalse  
       2020-09-25 09:33:09 +08:00
    这是一回事儿吗?
    m30102
        2
    m30102  
    OP
       2020-09-25 09:37:30 +08:00
    @whileFalse 都是基础啊
    keith1126
        3
    keith1126  
       2020-09-25 09:37:55 +08:00
    浮点数哪来的补码?楼主水平堪忧。
    yogogo
        4
    yogogo  
       2020-09-25 09:42:01 +08:00
    钓鱼也不用这样钓啊~
    luckyrayyy
        5
    luckyrayyy  
       2020-09-25 09:44:34 +08:00   ❤️ 11
    不能用针在光盘上戳个 linux 内核出来的,一律认定为基础不行。
    m30102
        6
    m30102  
    OP
       2020-09-25 09:47:27 +08:00   ❤️ 1
    @keith1126 不带我定点小数玩了?
    bnrwnjyw
        7
    bnrwnjyw  
       2020-09-25 09:49:15 +08:00
    楼主是不是被喷过啊?报复性提问?
    mazyi
        8
    mazyi  
       2020-09-25 09:50:27 +08:00 via iPhone
    我来问个基础,你是谁?
    yazinnnn
        9
    yazinnnn  
       2020-09-25 09:51:50 +08:00
    你从哪来?要到哪去?
    raaaaaar
        10
    raaaaaar  
       2020-09-25 09:57:57 +08:00 via Android   ❤️ 4
    我们学这些东西,不是做一个什么都纯的硬盘,而是纯它们的缓存,有一个快速的索引。

    就你举的这个例子,除了那些要考试,要面试的,或者打竞赛的人,没有人天天去刷什么排序的哪一步是怎么样的。但是你一说排序,我们就知道排序是什么东西,大概有哪些排序,他们的原理大概是怎么样的,他们的时间复杂度是怎么样的,在某个场景时,我们也能去分析用什么算法,而不是马上打开 IDE 就开始写代码,这种情况在工程中几乎不可能存在,要写我们也会网上查,去笔记中找。

    什么补码就更是如此,我们学这个不是让你拿个数字就能开始算,而是知道,补码是个什么东西?它用在什么地方,为什么要有这个东西?它大概是个什么思路?诸如此类。
    yuruizhe
        11
    yuruizhe  
       2020-09-25 10:04:07 +08:00
    @keith1126 我记得课本上教的是 IEEE754 标准,分为底数和基数,好像两者中确实有一个用补码表示的
    shilyx
        12
    shilyx  
       2020-09-25 10:08:26 +08:00
    能用勺子吃米饭的人,能精确的知道每一勺子有多少米饭粒吗?
    m30102
        13
    m30102  
    OP
       2020-09-25 10:09:17 +08:00
    @raaaaaar 是啊,但面试没答出来就算不会,答出来了 过段时间又忘,这样不是瞎折腾么?
    icyalala
        14
    icyalala  
       2020-09-25 10:18:15 +08:00   ❤️ 10
    假设楼主不是来钓鱼的吧。。
    浮点数一般是按 IEEE 754 二进制来表示的,没有什么补码的概念,正负就是最高位的 1bit 。
    至于将字符串解析为 IEEE 754 二进制,不用说手写了,用代码转换都复杂得很,java 、php 、glibc 甚至编译器都有过各种 bug: https://www.exploringbinary.com/topics/#correctly-rounded-decimal-to-floating-point

    想了解的话可以看一下这个算法: https://www.ampl.com/netlib/fp/dtoa.c 苹果的 iOS macOS 用的就是这份代码。

    具体到 1.234 这个数,如果用手算的话,就是 1234 / 1000,转换为二进制,再进行大整数计算,得到的是一个无限长度的二进制小数:
    1.001110111110011101101100100010110100001110010101100000010000011000100100110111010010111100011010100111111011111001110110...

    这里 54 bit 是 0,则向下舍入,得到二进制:
    1.0011101111100111011011001000101101000011100101011

    转换为 IEEE 754 表示,最高位 1 表示负数,后面 11 位是 exp 0,加上 1023 bias 就是 01111111111,
    最后 52 位就是上面的二进制,隐藏高位 1,合起来就是:
    1 01111111111 0011101111100111011011001000101101000011100101011000

    用 hex 表示就是
    0xbff3be76c8b43958

    我们可以再实际验证一下:
    uint64_t p = 0xbff3be76c8b43958ull;
    double d = *(double *)&p;
    printf("%.17g\n", d);
    IsaacYoung
        15
    IsaacYoung  
       2020-09-25 10:29:12 +08:00 via iPhone
    懂得都懂
    m30102
        16
    m30102  
    OP
       2020-09-25 10:29:32 +08:00   ❤️ 1
    @icyalala 感谢 V 站较真大神
    gadsavesme
        17
    gadsavesme  
       2020-09-25 10:32:53 +08:00
    各种排序我能手写,补码这种早忘了。两件事又没啥关联,能手写排序也不是能力多强,只是平常会经常刷算法题,原反补码这种不经常看忘记很正常。
    coderluan
        18
    coderluan  
       2020-09-25 10:36:51 +08:00
    用这种方式提问的, 肯定都原因, 不知道楼主是辩论还是面试的时候受挫了.

    不抬杠的话, 排序其实是非常好的问题, 考察重点也不只是基础编程能力, 而是优化代码的能力, 一个好的面试官会不会让你写各种排序, 而是让你选择一种你排序来写并且说明为什么选这个, 写完了再引导你进行优化, 随便还能看看你的代码质量. 很多人之所以反感排序是因为很多面试官的水平不够, 并不是写个排序本身有什么问题.
    rebeccaMyKid
        19
    rebeccaMyKid  
       2020-09-25 11:36:06 +08:00
    CSAPP 第二章 第二节 有讲补码。结合前面讲的二进制,十六进制和十进制的转换方法。给定一个数据类型以及值,比如 char 类型( 8 位),值 -90,写补码是很简单的事情,我觉得应该记住。(温馨提示:阅读时间大概 1 小时)

    我之前记不住是因为没有接触到这个公式和体系,看的都是知乎的什么解释,现在发现看的知乎那个解释适合理解,但不适合计算。
    rebeccaMyKid
        20
    rebeccaMyKid  
       2020-09-25 11:36:56 +08:00
    浮点数还没看,我上面说的是整数。
    shino996
        21
    shino996  
       2020-09-25 11:43:08 +08:00 via iPhone
    就硬杠
    oaix
        22
    oaix  
       2020-09-26 08:02:13 +08:00
    补码如果知道原理是不用记规则的。
    比如一个 byte 类型的负数-5
    1. 先用二进制表示他对应的正数:0000 0101
    2. 再用 0 减去这个正数

    ```
    0000 0000
    -0000 0101
    --------------
    1111 1011

    ```
    m30102
        23
    m30102  
    OP
       2020-09-26 13:53:51 +08:00
    @oaix 小数走起?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1029 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:16 · PVG 04:16 · LAX 12:16 · JFK 15:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.