位运算

位运算

放肆的年华 提交于 2019-11-29 12:00:48
快速幂问题 求 \(a\) 的 \(b\) 次方对 \(p\) 取模的值, \(1<=a,b,p<=10^9\) 典型快速幂解法, b&1为真,表示为奇数,b>>=1右移1位,表示除2 long long solve(long long a, long long b, long long p){ long long ans = 1; while(b){ if(b & 1) ans = ans * a % p; a = a * a % p; b >>= 1; } return ans; } 从二进制的角度看,实际是 将b表示为二进制的按权展示式 \(b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+...+c_02^0\) , \(a^b=a^{c_{k-1}2^{k-1}}*a^{c_{k-2}2^{k-2}}*...*a^{c_02^0}\) 同时注意到!! b&1可以取出b的二进制表示的最低位,b>>=1可以去除最低位 , 于是可以从0号位遍历每个数位进行累积运算!! long long solve(long long a, long long b, long long p){ long long ans = 1; for(;b;b>>=1){ if(b & 1) ans = ans * a % p; //为1时才累计进ans a = a * a % p; /

java中位运算和移位运算详解

拟墨画扇 提交于 2019-11-29 10:11:50
一、位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0。首先我们看一下对正数的运算 分别看一下正数和负数的具体运算步骤 正数直接取二进制运算,负数取反加一得补码再运算,得到的结果符号位为0,不需要做任何操 作直接给出结果,后面会讲到如果结果为负数的情况 (2)按位或 | 有1为1,否则为0 分别看一下正数和负数的具体运算步骤 讲一下负数求反和补码的直接给结果,当运算结果符号位是1为负数,那就需要进行减1操作,再按位取反,这个时候得到的才是正确的结果 (3)异或 ^ 相同为0,不同为1 二、移位运算 (1)左 移 (<< ) 右边空出的位用0填补高位左移溢出则舍弃该高位。计算机中常用补码表示数据,注,用补码计算 (2)右 移 (>> ) 左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;低位右移溢出则舍弃该位。 (3)无 符 号 右 移 (>>> ) 无符号右移:正数与右移规则一样,负数的无符号右移,就是相应的补码移位所得,在高位补0即可 原文地址:https://www.cnblogs.com/xiuyu/p/8428963.html 一、位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0。首先我们看一下对正数的运算

位运算

别来无恙 提交于 2019-11-29 06:46:10
位运算 位运算介绍 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如, and 运算本来是一个逻辑运算符,但整数与整数之间也可以进行 and 运算。举个例子, 6 的二进制是 110 , 11 的二进制是 1011 ,那么 6 and 11 的结果就是 2 ,它是二进制对应位进行逻辑运算的结果( 0 表示 Fase , 1 表示 True ,空位都当 0 处理)。 由于位运算直接对内存数据进行操作不需要转成十进制,因此处理速度非常快。 符号 描述 运算规则 & 与 两个位都为 1 时,结果才为 1 | 或 两个位都为 0 时,结果才为 0 ^ 异或 两个位相同为 0 ,相异为 1 - 取反 0 变 1,1 变 0 << 左移 各二进位全部左移若干位,高位丢弃,低位补 0 >> 右移 各二进位全部右移若干位,对无符号数,高位补 0 ,有符号数,各编译器处理方法不样,有的补符号位(算术右移),有的补 0 (逻辑右移) 异或操作的一些特点: x ^ 0 = x x ^ 1s =~x // 1s = ~0 x ^ (~x) = 1 x ^ x = 0 // interesting and important! a ^ b = c => a ^ c = b, b ^ c = a //swap a ^ b ^ c = a ^

状态压缩

痴心易碎 提交于 2019-11-28 23:05:27
定义 状态压缩,实际上是将一个30左右长度的bool数组用一个int来表示。为什么呢?众所周知,bool类型只有0,1两种两种类型。而计算机又是用二进制来存储数字,加之强大的位运算功能,我们便可以更改整数在二进制下表示的每一位的数字,来表示不同的状态。由于其与位运算密切相关,所以我们先来讨论一下位运算的事情。 位运算 不做演示,可以自行演示验证 S是原集合 S&(1<<(k-1)) 取出第k位 ^ 将第k位取反 | 将第k位强制变1 S^(1<<k-1) 取补集 S&(-S) 取出右起第一个1 ,减掉这个结果数就更新状态 lowbit S|A==S A是S的子集 for(x=s;x;s&(x-1) 枚举子集 来源: https://www.cnblogs.com/Uninstalllingyi/p/11432672.html

位运算专题

爱⌒轻易说出口 提交于 2019-11-28 20:35:55
LeetCode 231:给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 示例 1: 输入: 1 输出: true 解释: 20 = 1 示例 2: 输入: 16 输出: true 解释: 24 = 16 示例 3: 输入: 218 输出: false 方法一:   思路:此题判断该数字二进制中1的个数,如果非负,其中1的位数只有一位就一定是2的幂,否则就不为2的幂,所以可以采取一位一位的判断比较,但是这样就更慢,所以可以采取其他办法,即n&(n-1)一定可以消去右边第一个出现的1;   大家可以这样理解,不管对于n中最后一个一的位置如何比如为....1000...(N个)假设1的后面有N个0,对于该数字减一而言就变成了....01111....(N个)后面的0全部就因为借位变成了1,此时将两个数字相与就会把最后一个1之后(包括1)全部变成了0.所以我们消去一个1之后如果还有1 那么这个数一定不为0,所以只需要进行与运算之后判断是否为0即可。 1 class Solution 2 { 3 public: 4 bool isPowerOfTwo(int n) 5 { 6 if(n<=0) return false; 7 return (n&(n-1))==0; 8 } 9 }; 方法二:   思路:整数最大的2的整数幂是2^30;该数对所有2的幂取余都为0

位运算与位移运算符

不打扰是莪最后的温柔 提交于 2019-11-28 19:57:24
这篇Java教程基于JDK1.8。教程中的示例和实践不会使用未来发行版中的优化建议。 位运算与位移运算符 Java编程语言为整数类型提供了位运算和位移运算符。这类操作符相比较而言使用的频率较低。因此,它们的覆盖面较短,只需要了解这些操作符的存在即可。 一元位补运算符“~”反转位运算,它可以用在任何整数类型上,使得“0”变成“1”,然后“1”变成“0”。比如一个字节包含8位,将补运算符运用在位形式表示的数“00000000”上则会得到“11111111”。 带符号的左移操作符“<<” 向左移动一个位模式,带符号的右移操作符“>>” 向右移动一个位模式。位模式由左操作数给出,移动的位数由右操作数给出。无符号的右移操作符“>>>”用0填充右移后最左边的位置,有符号的右移操作符“>>”最左边的位置则取决于该数的符号位。 & 操作符完成按位与运算 ^ 操作符完成按位异或运算 | 操作符完成按位或运算 下面的程序使用位与运算打印出了数字“2”到标准输出: public class BitDemo { public static void main ( String [ ] args ) { int bitmask = 0x000F ; int val = 0x2222 ; // print 2 System . out . println ( val & bitmask ) ; } } 来源:

剑指offer47:位运算+递归。求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

自闭症网瘾萝莉.ら 提交于 2019-11-28 19:44:23
1 题目描述   求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 2 思路和方法   (1)递归,不能使用if等条件判断语句,可以使用&&逻辑运算符的短路特性实现。 当n=0时,不进行后一个判断的计算,作为递归终止 。   (2)利用sizeof(a)计算bool数组的字节数,bool类型在C++中占一个字节。bool a = [n][n+1]; 因一共有n*(n+1)个1,下三角或者上三角,第一行:[1]和为1;第二行:[1][1] 和为2;第三行:[1][1][1]和为3,……。bool类型的数据a,sizeof(a)=n*(n+1),所以1+2+3+...+n=sizeof(a)=n*(n+1)/2,或者是sizeof(a)>>1。 3 C++核心代码 1 #include<iostream> 2 3 #include<vector> 4 5 using namespace std; 6 7 class Solution { 8 public: 9 int Sum_Solution(int n) { 10 int sum = n; 11 sum && (sum += Sum_Solution(n - 1));// 利用前一个判断短路;当n=0时,不进行后一个判断的计算,作为递归终止

JS 位运算符

送分小仙女□ 提交于 2019-11-28 19:27:57
进行位运算前先将number类型的数字转化成二进制的数字,再进行位运算   位与:&     当两个都为真(1)时,结果为真(1);反之为假(0)。   位或:|     当两个中有一个为真(1)时,结果为真(1);两个均为假(0)时,结果为假(0)。   位异或:^     当两个均为真(1)或两个均为假(0)时,结果为假(0);一真(1)一假(0),结果为真(1)。 例如:将3和5进行位运算;   1)先将3和5转化成二进制;即:     3 = 0011;    5 = 0101;   2)3 位与 5;即 3 & 5:     3=      0011     5=      0101     3&5=     0001    =1   3)3 位或 5;即 3 | 5:     3=      0011     5=      0101     3|5=      0111    =7   4)3 位异或 5;即 3 ^ 5:     3=      0011     5=      0101     3^5=     0110    =6 JS实现代码如下: var a = 3; var b = 5; var result1 = a^b; var result2 = a&b; var result3 = a|b; console.log(result1); //6

位运算[转载]

大憨熊 提交于 2019-11-28 19:16:31
位运算 位运算 首先 补码 按位与(&) 按位或(|) 按位异或(^) 左移(<<) 右移(>>) 取反(~) 首先 要明白位运算是在二进制中的运算方式,所有其他进制的数在进行位运算时都要先转化成二进制数再进行运算。 位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反( ~ )、左移(<<)、右移(>>)这几种。 其中除了取反( ~ )以外,其他的都是二目运算符,即要求运算符左右两侧均有一个运算量。 补码 补码是为了表示一个负数的二进制形式。 其转化方式是先将负数当成正数转化成二进制的形式再将二进制正数的各个位上取反再加上一。 例如-5 先求出5的二进制数 : 0000 0000 0101 然后将各个位上0变1,1变0 : 1111 1111 1010 最后再加1 : 1111 1111 1011 这里5二进制下是101表示时前面全是0,这里省略就只写了几个意思一下^ _ ^ 按位与(&) 运算的两个数,转换算为二进制后,进行与(&)运算。 当相应位上的数都是1时,该位取1,否则该为0。 例如5 & -5 5 : 0000 0000 0101 -5 :1111 1111 1011 答案 : 0000 0000 0001 按位或(|) 运算的两个数,转换为二进制后,进行或(|)运算。 只要相应位上存在1,那么该位就取1,如果都不为1,就为0。 还是5 | -5 0000