二进制和位运算

1. 无符号:

int32位可以表示0~2^32-1位数。

2. 有符号:

负数占1/2,正数和0占1/2
首位为0表示非负。首位为1表示负数,后面是数值位。
-1表示:先看正数:0001为1,减1 ——> 0000表示0,每一位取反 ——> 1111。

-2表示:先看正数:0010,减1(向高位借位) ——> 0001表示1,取反 ——> 1110。

-8:1110,减1 ——> 0111 ——> 1000。
从负数表示确定数,整体取反加一看正数。

2进制:01101110——>16进制:67
0110->6,1110->7

3. 相反数

取反:(~)
a=11010001,~a=00101110

取反之后在加1,就是相反数。e=~a+1.
int b=-a == int b=(~a)+1

有符号整数负数的最小值无法转换相反数。
例:-8:1000 取反 0111 再加1 1000 仍旧是本身。且正数处也无对应。

4. 位运算

或运算"|"
int g=00001010,int h=00001100.
g和h每一位只要有一位是1,1就可以留下来
g|h == 00001110.

与运算"&"
g&h 每一位两个都为1才可以留下来。

异或"^"
g^h 相同为0,不同为1。

与逻辑||和&&区别:
设有一个bool t = a||b;
遇到false才会接续执行。如果为ture进程会直接终止。

t = a&&b;
如果为ture接续执行,如果为false直接终止。

但位运算bool t = a|b
两个一定都会执行,确定了状态之后才能取或。

二进制加法(正负均可)加法逻辑一致,对应位相加,大于1进位。溢出位不管(丢弃)。要自己控制溢出。

,>>>右移,对于正数>>,>>>效果一样,用0来补前面的位,对于负数>>用符号位1来补位,>>>用0来补位.
对于非负数 <<1,等于乘以2,非负数<<3,等于乘以8,<<i,等同于乘以2^i。位数向上提了。
非负数>>1等同于除以2,>>i等同于除以2^i.
只有非负数符合这个特性,负数不要用。

例:num = 01101100
如何确定第i位的状态 ——> num&(1<<i)

#include<bits/stdc++.h>
using namespace std;
#define int long long 

signed main()
{
	ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		for(int j=31;j>=0;j--)
		{
			cout<<((i&(1<<j))==0?"0":"1");
                        //((i&(1<<j))==1?"1":"0");不正确,&之后的二进制转化为10进制可能不是1,而是0100=4.不能作为判断标准
                        //如果是long类型,要设定(1L<<48).来表示。默认的int没有48位。
		}
		cout<<endl;
	}
	
	return 0;
}

posted @ 2024-04-06 11:41  miao-jc  阅读(16)  评论(0编辑  收藏  举报