C/C++基础-原码/反码/补码/位操作实现四则运算

序言

上次文章提到算术移位和逻辑移位的区别,这里学习如何用位操作实现四则运算。


1. 原码、反码和补码
  • [1] 原码

    • 第一位表示符号,其余位表示值。

    • 注意:不同类型符号数表示范围不同

8:00001000
-810001000
8位二进制符号数的取值范围

[11111111, 01111111][-127,127]
  • [2] 反码

    • 正数的反码就是其本身

    • 负数的反码:符号位不变,其余各位取反

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反
  • [3] 补码

    • 正数的补码就是其本身

    • 负数的补码:符号位不变,其余位取反,再+1 (反码+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补


2. 常见的位操作
  • 判断奇偶

    • 最末位:为1为奇数,为0为偶数
奇数:a & 1 == 1

偶数:a & 1 == 0
  • n & (n - 1)

    • [1] 判断一个数是否是2的幂次

    • [2] 求一个(正)数二进制中1的个数

if (n & (n - 1) == 0)
    printf("2的幂次或0");
while (n > 0)
{
    count++;
    n = n & (n - 1);
}
- n = ~n + 1 = ~(n - 1)
  • 获取整数最右边的1
n & (-n)

也即: n & ~(n - 1)
  • 去除整数最右边的1
n & (n - 1)


3. 四则运算
  • 加法

    • 异或操作:得到本位的加法结果
    • 与操作:得到高位的进位值
int add(int a, int b)
{
    int add, jin_wei;
    while (b != 0)                     //循环到没有进位退出
    {
        add = a^b;
        jin_wei = (a & b) << 1;        //得到高位的进位值
        a = add;
        b = jin_wei;
    }
    return add;
}
  • 减法

    • 减法容易转换为加法:a - b = a + (-b) = a + (~b + 1)
int subtract(int a, int b)
{
    return add(a, add(~b, 1));
}
  • (正整数)乘法

    • 乘法:与十进制乘法类似,逐位乘的结果在不同位上相加
int multiply(int a, int b)
{
    int ans = 0;
    while (b)
    {
        if (b & 1)
            ans = add(ans, a);
        a = a << 1;
        b = b >> 1;
    }
    return ans;
}
  • 除法

    • 二进制除法竖式运算(正负数)
int divide(int a, int b)
{
    bool neg = (a > 0)^(b > 0);
    if (a < 0)
        a = -a;
    if (b < 0)
        b = -b;
    if (a < b)
        return 0;

    int zuoyi;
    //zuoyi记录除数要左移的位数
    for (zuoyi = 0; zuoyi < 32; zuoyi++)
    {
        if ((b << zuoyi) >= a)
            break;
    }

    //记录每次除法的商
    int shang = 0;
    int i;
    for (i = 0; i < zuoyi; i++)
    {
        if ((b << i) > a)              //确定商的位置,保证够除
            continue;
        shang = shang | (1 << i);    //新的商
        a = a - (b << i);            //新的除数
    }
    if (neg)
        return -shang;
    return shang;
}
  • 正数除法
int divide(int a, int b)
{
    int count = 0;
    while (a >= b)
    {
        a = substract(a, b);
        count++;
    }
    return count;
}



参考文章
http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
http://blog.csdn.net/u013074465/article/details/42680239(推荐)
http://www.cnblogs.com/wuchanming/p/4359341.html

2017.10.25

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值