位运算

Objective-C使用位运算设计可复选的枚举

非 Y 不嫁゛ 提交于 2020-03-18 01:12:22
某厂面试归来,发现自己落伍了!>>> 使用位运算设计可复选的枚举 一、枚举使用的一个小例子 在软件开发中,枚举是我们会经常会用到的一种编程方式,通过枚举,可以使我们的代码更具可读性与统一性。通常情况下,我们会通过typedef来定义一种枚举的类型来使用。例如: typedef enum { para1, para2, para3 }myEnum; 我们可以在函数的参数中来使用它: -(void)testEunm:(myEnum)para{ switch (para) { case para1: { NSLog(@"para%d",1); } break; case para2: { NSLog(@"para%d",2); } break; case para3: { NSLog(@"para%d",3); } break; default: break; } } 我们在调用调用这样的一个函数的时候,通过传入一个枚举类型,可以分流执行我们想要的操作。 二、枚举到底是个什么东西 枚举并不是一种奇怪的类型,起实质是整型的另一个名字,如果没有附加的操作,枚举中的第一个参数默认就是整型0,之后依次递加,当然,我们也可以认为的控制这个数值,例如: typedef enum { para1=7, para2, para3=1000 }myEnum; 可以这么理解,我在传参的时候

【算法技巧】位运算装逼指南

江枫思渺然 提交于 2020-03-17 03:03:13
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下 if( n % 2) == 01 // n 是个奇数 }   如果把 n 以二进制的形式展示的话,其实我们只需要判断最后一个二进制位是 1 还是 0 就行了,如果是 1 的话,代表是奇数,如果是 0 则代表是偶数,所以采用位运算的方式的话,代码如下: if(n & 1 == 1){ // n 是个奇数。 }    有人可能会说,我们写成 n % 2 的形式,编译器也会自动帮我们优化成位运算啊,这个确实,有些编译器确实会自动帮我们优化。但是,我们自己能够采用位运算的形式写出来,当然更好了。别人看到你的代码,我靠,牛逼啊。无形中还能装下逼,是不是。当然,时间效率也快很多,不信你去测试测试。 2、交换两个数 交换两个数相信很多人天天写过,我也相信你每次都会使用一个额外来变量来辅助交换,例如,我们要交换 x 与 y 值,传统代码如下: int tmp = x; x = y; y = tmp;  

5/30 c语言中的位运算

99封情书 提交于 2020-03-13 11:00:40
1、什么是位运算? 位运算是指按二进制位进行的运算。因为在系统软件中,常要处理二进制的问题。储存单元中的各二进制位左移或者右移一位,两个数按位相加等。c语言灵活,接近底层,对程序员的要求高,不像其他语言对c语言进行了封装,出错性会高很多。 2、位运算符和位运算。 运算符&按位与 ~取反 |按位或 <<左移 ^按位或 >>右移。位运算中除了~以外,均为二元元运算符,即要求两侧各有一个运算量。 3、与&的应用。 清零,无论任何一个二进制的书与上一个00000000,与之后就全为0 了。 去一个数中某些指定位,假如哦们需要一个字型数据取出其低八位的值时, 11010101 01011011&00000000 11111111=00000000 01011011 来源: https://www.cnblogs.com/serious123/p/10952816.html

位运算

纵饮孤独 提交于 2020-03-13 06:42:23
  &(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。 其中,按位取反运算符是单目运算符,其余均为双目运算符。 位运算符的优先级从高到低,依次为~、&、^、|, 其中~的结合方向自右至左,且优先级高于算术运算符,其余运算符的结合方向都是自左至右,且优先级低于关系运算符。 位运算应用口诀 清零取反要用与,某位置一可用或 若要取反和交换,轻轻松松用异或                 (2)表示二进制数 移位运算 要点 1 它们都是双目运算符,两个运算分量都是【整形】,结果也是【整形】。 2 "<<" 左移 :右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。       按位左移。将一个运算量的各位(二进制表示)依次左移若干位,低位补0,高位舍弃不要。             注意:位移操作的右操作数必须小于左操作数的位长度,否则结果未定义。     如:     int a=10,c= a<<2;     即:         a:00000000 00000000 00000000 00001010         c:00000000 00000000 00000000 00101000         所以,c=40。 3 ">>"右移 :右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。    

java系统优化中的位操作优化

独自空忆成欢 提交于 2020-03-11 15:46:19
本博客来自我的新书 《Java系统性能优化》 的第四章15节,也欢迎阅读我的的经典书 《Spring Boot 2 精髓 》 4.15 位运算 Java位运算非常高效,可以使用位运算代替部分算数运算以提高性能,比如,最常用的判断奇数 int a = 111; System.out.print((a & 1)==1); 乘以2或者除以2,也可以使用位运算 int a = 111; //右移1位,相当于除以2 System.out.println(a>>1); //左移1位,相当于乘以2 System.out.println(a<<1); 在JAVA8的Integer里,也使用了位运算来实现int转字符串。 //r=i-q*10 优化为如下 r = i - ((q << 3) + (q << 1)); //q=i/10,优化为如下 q = (i * 52429) >>> (16+3); 这里 (i * 52429) >>> (16+3) 相当于i*0.1000000003,因此对于i较小的数据,可以认为俩着是相等的。 对比直接使用i/10 和 (i * 52429) >>> (16+3),性能如下 Benchmark Mode Samples Score Score error Units c.i.c.c.BitTest2.bit avgt 5 0.669 0.031 ns/op c

iOS程序猿必知的位运算相关知识

匆匆过客 提交于 2020-03-09 11:09:19
从现代计算机电路来说,只有 通电/没电 两种状态,即为 0/1 状态,计算机中所有的数据按照具体的编码格式以二进制的形式存储在设备中。   直接操作这些二进制数据的位数据就是位运算,在 iOS开发 中基本所有的位运算都通过枚举声明传值的方式将位运算的实现细节隐藏了起来: typedef NS_OPTIONS(NSUInteger, UIRectEdge) { UIRectEdgeNone = 0, UIRectEdgeTop = 1 << 0, UIRectEdgeLeft = 1 << 1, UIRectEdgeBottom = 1 << 2, UIRectEdgeRight = 1 << 3, UIRectEdgeAll = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight } NS_ENUM_AVAILABLE_IOS(7_0);   位运算是一种极为高效乃至可以说最为高效的计算方式,虽然现代程序开发中编译器已经为我们做了大量的优化,但是合理的使用位运算可以提高代码的可读性以及执行效率。 基础计算   在了解怎么使用位运算之前,笔者简单说一下CPU处理计算的过程。如果你对 CPU 的计算方式有所了解,可以跳过这一节。   当代码 int sum = 11 + 79 被执行的时候

c++位运算

こ雲淡風輕ζ 提交于 2020-03-09 10:14:58
前言 今天准备写一下关于位运算的东西。 其实位运算并没有什么难点,也没有什么太多的内容。 啥也不说了,下面就直接进入文章正文。 初识位运算 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行. 这就是位运算的概念,不难理解吧。 位运算符号 含义 Pascal语言 C/C++语言 Java 按位与 a and b a & b a & b 按位或 a or b a | b a | b 按位异或 a xor b a ^ b a ^ b 按位取反 not a ~a ~a 左移 a shl b a << b a << b 带符号右移 a shr b a >> b a >> b 无符号右移 / / a>>> b 这里各种语言都写在这里了。要用的话就那去吧。 下面说一说位运算符号的具体作用 符号使用方法 按位与 按位与,在c++的表示中为 & 位运算其实只有一种情况,用竖式两位对齐计算。下面是运算结果: 0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1 也就是只有当两个数都是1的时候,按位与的结果才是1 按位或 按位或,在c++的表示中为 | 或运算的四种情况如下: 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1 按位或就是只要两个数中有一个1的时候,按位或的结果就是1 按位异或(xor)

c++位运算

我们两清 提交于 2020-03-09 10:12:44
前言 今天准备写一下关于位运算的东西。 其实位运算并没有什么难点,也没有什么太多的内容。 啥也不说了,下面就直接进入文章正文。 初识位运算 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行. 这就是位运算的概念,不难理解吧。 位运算符号 含义 Pascal语言 C/C++语言 Java 按位与 a and b a & b a & b 按位或 a or b a | b a | b 按位异或 a xor b a ^ b a ^ b 按位取反 not a ~a ~a 左移 a shl b a << b a << b 带符号右移 a shr b a >> b a >> b 无符号右移 / / a>>> b 这里各种语言都写在这里了。要用的话就那去吧。 下面说一说位运算符号的具体作用 符号使用方法 按位与 按位与,在c++的表示中为 & 位运算其实只有一种情况,用竖式两位对齐计算。下面是运算结果: 0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1 也就是只有当两个数都是1的时候,按位与的结果才是1 按位或 按位或,在c++的表示中为 | 或运算的四种情况如下: 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1 按位或就是只要两个数中有一个1的时候,按位或的结果就是1 按位异或(xor)

Xor and Sum(位运算)

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-09 00:55:00
题目描述 给定一个大小为N的数组A,第i个元素为Ai。 问有多少的子区间[LR],满足区间数值异或和等于区间数值和,即: Al xor Al+1 xor…xor Ar = Al + Al+1 +…+Ar(l+1表示下标) a和b的xor即为a和b二进制表示按位取xor得到新数c的十进制表示 5和12的xor计算如下: 510=01012 (12)10=(1100)2 01012xor11002=(1001)2 (1001)2=(9)10 输入 第一行给定一个整数N。 第二行给定N个整数,第i个数即为Ai。 1≤N≤2×10^5 0≤A_i≤2^30 输出 输出满足条件的子区间LR的数量。 样例输入 10 0 0 740 361 473 0 0 826 479 974 样例输出 18 题解: xor运算可以视为二进制下没有进位的加法,加法运算本身是有进位的加法。 那么可以简单得出这样一个性质:对于一个区间而言,如果异或和加法答案一样,那么把区间缩小答案肯定还是一样;如果异或和加法答案不一样,那么把区间扩大答案肯定还是不一样。 于是我们就可以枚举区间右端点,去寻找最小的左端点,这个区间异或等于区间和,那么以这个区间右端点的合法区间个数就是区间的长度(左端点往里缩都是合法的)。 这个可以预处理出前缀和还有前缀异或和,用双指针维护出来。 1 #include<iostream> 2

四种GCC内置位运算函数

我们两清 提交于 2020-03-08 10:18:00
int __builtin_ffs (unsigned int x) 返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4。 int __builtin_clz (unsigned int x) 返回前导的0的个数。 int __builtin_ctz (unsigned int x) 返回后面的0个个数,和__builtin_clz相对。 int __builtin_popcount (unsigned int x) 返回二进制表示中1的个数。 int __builtin_parity (unsigned int x) 返回x的奇偶校验位,也就是x的1的个数模2的结果。 此外,这些函数都有相应的usigned long和usigned long long版本,只需要在函数名后面加上l或ll就可以了,比如int __builtin_clzll。 vs版 int builtin_clz(unsigned int type)//返回前导的0的个数 { int num = 0; type |=1; //防止type为0时,出现无限循环infinite loop,type为0时的计算结果为31。 while(!(type & 0x80000000)) //检测最高位是不是1。 { num +=1; type <<= 1; } return num; }