• 谈谈补码与移位


    在计算机中整数的表示使用补码来表示的。

    什么是补码呢?首先要明白什么是原码。

    数字是有符号的,计算机中,用最高位作为符号位。以四位机器码举例:1的原码表示是:0001; -1 的原码表示是:1001。

    也就是说表示实际数值的只有3位。因此4位机器码原码表示数的范围是:[-7, 7],其中0有两种表示,+0:  0000; -0:   1000。

    原码表示清晰易懂,但对机器来说却是个麻烦,因为我们必须设计两套电路分别表示加法和减法。

    为了统一加减法电路,人们想到了同余原理,让符号位也参与运算,补码应运而生。(反码没有实际应用,没必要记,这里就不解释了,实际上如果不是为了引出正数的补码表示,原码也没必要记)

    对于正数,补码表示就是其原码,还以四位机器码举例:1的补码表示是:0001。

    对于负数,补码表示就是对于相应的正数表示,连同符号位一起,各位取反后加1。 -1的补码表示为: 1111。(0001 各位取反,1110, 再加1)

    对于补码来说,我们没办法直接看出负数的值,想知道负数的真值,我们需要对负数求补,再加上符号位即可。

    以-3举例:1101。最高位是1,我们知道它是个负数。对其求补:0010 + 1 = 0011。我们也就知道了其值为-3。

    也就是说,正数求补就是其对应的负数,负数求补就是其对应的正数。

    对于减法,加上其负数的补码即可。我们成功的把减法运算变成为了加法运算。(不理解同余原理的,可能难以理解。记住结论即可,我不详细展开介绍了)

    对于4位机器码来说,补码表示范围为:[-8, 7]。这里0只有一种表示:0000. 所以比原码多表示了一个负数:-8 : 1000。+8的补码为 01000,由于溢出的原因,无法表示。

    下面给出8位机器码表示的几个数字的补码:

    0           0000 0000

    1           0000 0001

    2           0000 0010

    ... ...

    127       0111 1111

    -1          1111 1111

    -2          1111 1110

    ... ...

    -128      1000 0000

     有了补码之后,计算机中的加减乘除都可以用加法和求补电路实现,大大简化了电路设计。

    下面谈谈移位。这里不多谈,就只谈谈java中的移位操作。

    java这种语言竟然有移位操作,确实出乎人意料。不过考虑到java设计初衷是用于嵌入电视机机顶盒的,有这种面向底层的操作倒也不奇怪。

    谈到移位,不得不提位运算符 | 或;  & 与; ^ 异或; ~ 取反。

    这四种都是按位执行,也很简单,不详细展开。记住异或,异1同0即可。

    java中左移 << :  高位舍去,低位补0。相当于乘2,当然前提是不溢出。 

    java中右移 >>: 正数补0,负数补1,低位舍去。相当于除2,易知正数右移,最小得0;负数右移,最小得-1。

    上面两种移位操作,称为算术移位,因为它们保存了算术符号,这与C C++是一样的。(左移在不溢出的情况下,符号是不会变化的。不过要注意溢出的发生。)

    java中还有一种逻辑右移:>>> , 无论正负,高位补0,低位舍去。这是C C++ 没有的。

    想要查看二进制表示,可以调用Integer.toBinaryString(int i)方法。

  • 相关阅读:
    汇编 if else
    汇编  cdecl 函数调用约定,stdcall 函数调用约定
    汇编 push ,pop指令
    汇编 EBP ,ESP 寄存器
    汇编 sub减法指令 比较指令CMP JZ条件跳转指令
    thrift使用案例
    基于hiredis,redis C客户端封装
    golang 3des/ecb/cbc/pkcs5 加解密
    ortp 发送RTP实例
    go:基于时间轮定时器方案
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6553181.html
Copyright © 2020-2023  润新知