位运算---直接操作--节约内存??

2024-02-07 11:38

本文主要是介绍位运算---直接操作--节约内存??,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

位运算主要是直接操控二进制时使用 ,主要目的是节约内存,使你的程序速度更快,还有就是对内存要求苛刻的地方使用,以下是一牛人总结的方法,分享一下:位运算应用口诀
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或移位运算
要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。2 " < < " 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。3 " > > " 右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。4 " > > > " 运算符,右边的位被挤掉,对于左边移出的空位一概补上0。位运算符的应用 (源操作数s 掩码mask)
(1) 按位与-- & 
1 清零特定位 (mask中特定位置0,其它位为1,s=s& mask)
2 取某数中指定位 (mask中特定位置1,其它位为0,s=s& mask)
(2) 按位或-- |常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
(3) 位异或-- ^
1 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
2 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)目 标                    操 作                          操作后状态
a=a1^b1                a=a^b                          a=a1^b1,b=b1
b=a1^b1^b1          b=a^b                          a=a1^b1,b=a1
a=b1^a1^a1          a=a^b                          a=b1,b=a1二进制补码运算公式:
-x = ~x + 1 = ~(x-1)
~x = -x-1
-(~x) = x+1
~(-x) = x-1
x+y = x - ~y - 1 = (x|y)+(x& y)
x-y = x + ~y + 1 = (x|~y)-(~x& y)
x^y = (x|y)-(x& y)
x|y = (x& ~y)+y
x& y = (~x|y)-~x
x==y:      ~(x-y|y-x)
x!=y:      x-y|y-x
x< y:      (x-y)^((x^y)& ((x-y)^x))
x< =y:      (x|~y)& ((x^y)|~(y-x))
x< y:      (~x& y)|((~x|y)& (x-y))//无符号x,y比较
x< =y:      (~x|y)& ((x^y)|~(y-x))//无符号x,y比较 
应用举例 
(1) 判断int型变量a是奇数还是偶数                      
a& 1    = 0 偶数a& 1 =    1 奇数 
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a> > k& 1 
(3) 将int型变量a的第k位清0,即a=a& ~(1< < k) 
(4) 将int型变量a的第k位置1, 即a=a|(1< < k) 
(5) int型变量循环左移k次,即a=a< < k|a> > 16-k    (设sizeof(int)=16) 
(6) int型变量a循环右移k次,即a=a> > k|a< < 16-k    (设sizeof(int)=16) 
(7)整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y)    //返回X,Y 的平均值
{       return (x& y)+((x^y)> > 1); 
} 
(8)判断一个整数是不是2的幂,对于一个数 x > = 0,判断他是不是2的幂
boolean power2(int x)
{ return ((x& (x-1))==0)& & (x!=0);
} 
(9)不用temp交换两个整数
void swap(int x , int y)
{ x ^= y; y ^= x; x ^= y; 
} 
(10)计算绝对值
int abs( int x )
{ 
int y ; 
y = x > > 31 ; 
return (x^y)-y ;               //or: (x+y)^y
} 
(11)取模运算转化成位运算 (在不产生溢出的情况下)a % (2^n) 等价于 a & (2^n - 1) 
(12)乘法运算转化成位运算 (在不产生溢出的情况下)a * (2^n) 等价于 a< < n 
(13)除法运算转化成位运算 (在不产生溢出的情况下)a / (2^n) 等价于 a> > n例: 12/8 == 12> > 3 
(14) a % 2 等价于 a & 1              
(15) if (x == a) x= b; else x= a; 等价于 x= a ^ b ^ x; 
(16) x 的 相反数 表示为 (~x+1)
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或移位运算
要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。2 " < < " 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。3 " > > " 右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。4 " > > > " 运算符,右边的位被挤掉,对于左边移出的空位一概补上0。位运算符的应用 (源操作数s 掩码mask)
(1) 按位与-- & 
1 清零特定位 (mask中特定位置0,其它位为1,s=s& mask)
2 取某数中指定位 (mask中特定位置1,其它位为0,s=s& mask)
(2) 按位或-- |常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
(3) 位异或-- ^
1 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
2 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)目 标                    操 作                          操作后状态
a=a1^b1                a=a^b                          a=a1^b1,b=b1
b=a1^b1^b1          b=a^b                          a=a1^b1,b=a1
a=b1^a1^a1          a=a^b                          a=b1,b=a1二进制补码运算公式:
-x = ~x + 1 = ~(x-1)
~x = -x-1
-(~x) = x+1
~(-x) = x-1
x+y = x - ~y - 1 = (x|y)+(x& y)
x-y = x + ~y + 1 = (x|~y)-(~x& y)
x^y = (x|y)-(x& y)
x|y = (x& ~y)+y
x& y = (~x|y)-~x
x==y:      ~(x-y|y-x)
x!=y:      x-y|y-x
x< y:      (x-y)^((x^y)& ((x-y)^x))
x< =y:      (x|~y)& ((x^y)|~(y-x))
x< y:      (~x& y)|((~x|y)& (x-y))//无符号x,y比较
x< =y:      (~x|y)& ((x^y)|~(y-x))//无符号x,y比较 
应用举例 
(1) 判断int型变量a是奇数还是偶数                      
a& 1    = 0 偶数a& 1 =    1 奇数 
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a> > k& 1 
(3) 将int型变量a的第k位清0,即a=a& ~(1< < k) 
(4) 将int型变量a的第k位置1, 即a=a|(1< < k) 
(5) int型变量循环左移k次,即a=a< < k|a> > 16-k    (设sizeof(int)=16) 
(6) int型变量a循环右移k次,即a=a> > k|a< < 16-k    (设sizeof(int)=16) 
(7)整数的平均值
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:
int average(int x, int y)    //返回X,Y 的平均值
{       return (x& y)+((x^y)> > 1); 
} 
(8)判断一个整数是不是2的幂,对于一个数 x > = 0,判断他是不是2的幂
boolean power2(int x)
{ return ((x& (x-1))==0)& & (x!=0);
} 
(9)不用temp交换两个整数
void swap(int x , int y)
{ x ^= y; y ^= x; x ^= y; 
} 
(10)计算绝对值
int abs( int x )
{ 
int y ; 
y = x > > 31 ; 
return (x^y)-y ;               //or: (x+y)^y
} 
(11)取模运算转化成位运算 (在不产生溢出的情况下)a % (2^n) 等价于 a & (2^n - 1) 
(12)乘法运算转化成位运算 (在不产生溢出的情况下)a * (2^n) 等价于 a< < n 
(13)除法运算转化成位运算 (在不产生溢出的情况下)a / (2^n) 等价于 a> > n例: 12/8 == 12> > 3 
(14) a % 2 等价于 a & 1              
(15) if (x == a) x= b; else x= a; 等价于 x= a ^ b ^ x; 
(16) x 的 相反数 表示为 (~x+1)

这篇关于位运算---直接操作--节约内存??的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687613

相关文章

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

动手学深度学习【数据操作+数据预处理】

import osos.makedirs(os.path.join('.', 'data'), exist_ok=True)data_file = os.path.join('.', 'data', 'house_tiny.csv')with open(data_file, 'w') as f:f.write('NumRooms,Alley,Price\n') # 列名f.write('NA

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

理解java虚拟机内存收集

学习《深入理解Java虚拟机》时个人的理解笔记 1、为什么要去了解垃圾收集和内存回收技术? 当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术实施必要的监控和调节。 2、“哲学三问”内存收集 what?when?how? 那些内存需要回收?什么时候回收?如何回收? 这是一个整体的问题,确定了什么状态的内存可以

MySQL——表操作

目录 一、创建表 二、查看表 2.1 查看表中某成员的数据 2.2 查看整个表中的表成员 2.3 查看创建表时的句柄 三、修改表 alter 3.1 重命名 rename 3.2 新增一列 add 3.3 更改列属性 modify 3.4 更改列名称 change 3.5 删除某列 上一篇博客介绍了库的操作,接下来来看一下表的相关操作。 一、创建表 create