【就一行代码,背后却隐藏了这么多,小白也能看懂!】(树状数组前置知识:lowbit详解)

本文详细介绍了二进制的基本概念,包括二进制数的表示方法(原码、反码、补码),以及如何进行整数和小数的二进制转换。重点讲解了lowbit操作的原理,通过实例说明了其在计算机中的应用,强调了理解和掌握底层原理的重要性。
摘要由CSDN通过智能技术生成

引入:

不少人在代码里经常见到这样一行代码:

#define lowbit(x) x&(-x)

或是:

int lowbit(x){return x&(-x);}

这看似简单的一行代码,实则包含了很多知识,也是树状数组这种数据结构的基础。

二进制定义:

首先,不得不提的便是二进制了。

平时我们见到的数,比如 114 , 514 , 998244353 114,514,998244353 114,514,998244353 之类,基本上都是十进制,即满十进一,每一位数字最大为 9 9 9

二进制,顾名思义,即满二进一,每一位数字最大为 1 1 1

由于计算机的存储方式为真/假(即true/false或者说是1/0),二进制便是计算机的存储方式。因此,学计算机,二进制是不可能不学的了。

二进制转换:

我们平常用的都是十进制,那么如何将一个十进制数转换为二进制数呢?

整数:

可根据以下步骤来操作:

记该十进制数为 n n n

  1. 记录 n   m o d   2 n \bmod 2 nmod2 对应的数。
  2. n n n 除以 2 2 2
  3. 重复上述步骤,直至 n = 0 n=0 n=0

例如,我们现在要计算 114 114 114 所对应的二进制数:
我们可以这样用短除法(最右边为余数):

这下应该清楚多了吧。

练习1:写出 514 514 514 对应的二进制。

小数:

取该数的小数部分,每次乘上 2 2 2,取整数部分。

练习2:写出 0.114 0.114 0.114 的二进制。

二进制表示:

二进制跟十进制一样,也有正有负。在计算机当中,存储符号相当复杂,那么是怎样存储的呢?

原码:

首先,我们在二进制串中引入一个定义:符号位。由1/0表示, 1 1 1表示负数, 0 0 0 表示正数。

例如, 114 114 114 的二进制为 1110010 1110010 1110010,那么它的原码就是 01110010 01110010 01110010
那么, − 114 -114 114 的原码就是 11110010 11110010 11110010

反码:

我们发现, 114 + ( − 114 ) 114+(-114) 114+(114) 应该等于 0 0 0,但是 01110010 + 1110010 = 01100100 01110010+1110010=01100100 01110010+1110010=01100100,并不是 0 0 0

因此我们引入了反码的概念。

正数不变,负数除符号位外都取反。

例如, 114 114 114 的二进制为 1110010 1110010 1110010,那么它的反码就是 01110010 01110010 01110010
那么, − 114 -114 114 的反码就是 10001101 10001101 10001101

补码:

正数不变,负数除符号位外都取反再加 1 1 1

例如, 114 114 114 的二进制为 1110010 1110010 1110010,那么它的反码就是 01110010 01110010 01110010
那么, − 114 -114 114 的反码就是 10001110 10001110 10001110

综上:

正数不变,负数用 − 114 -114 114 来举例:

原码反码补码
11110010 11110010 11110010 10001101 10001101 10001101 10001110 10001110 10001110

二进制操作:

  1. 与操作(&):
    两个二进制数,逐位比较,两者 1 1 1的话结果为 1 1 1,否则为 0 0 0
  2. 或操作(|)
    两个二进制数,逐位比较,两者其一 1 1 1的话结果为 1 1 1,否则为 0 0 0
  3. 非操作(!)
    一个二进制数,逐位修改,为 1 1 1的话结果为 0 0 0,否则为 1 1 1

lowbit:

定义 lowbit(x)=x&(-x),举几个例子:

这里的负数取的是补码。

还可以发现 2 2 2 的幂次在 lowbit 操作后仍是原数。

我们可以发现, 114 114 114 的二进制为 01110010 01110010 01110010 2 2 2 正是这个数最右边的 1 1 1 的位置对应的数。

这是因为 − 114 -114 114 的补码是 10001110 10001110 10001110,最右边的 1 1 1 之前的数都被反过来了,总有 1 1 1 位为 0 0 0操作后结果全为 0 0 0。因此最后剩下的便是最右边的 1 1 1 的位置对应的数。

总结:

请大家记住一点:
不能因为代码简单,不懂原理就放过。

阅读量超过 1000 1000 1000 更新下一篇:树状数组

感谢大家的大力支持!

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值