首页 > 其他分享 >五、位运算

五、位运算

时间:2023-11-12 14:34:36浏览次数:33  
标签:std 运算 int 激活码 include cout

五、位运算

​ 位运算主要计算内存中每个小格的数据

1、输出二进制内容
头文件调用 语法 示例
include <bitser> std::bitset<要显示的二进制位数>(要显示的变量) std::cout << std::bitset<16>(a);
//二进制内容输出
#include <iostream>
#include <bitset>

int main()
{
    int a{ 0b100000001100 };
    std::cout << std::bitset<16>(a);  
}

2、左移、右移

1)左移:左移相当于*2,即a*(2n),如a左移2位,即a*(22)

#include <iostream>
#include <bitset>

int main()
{
    int a{ 0b100000001100 };
    std::cout <<"左移8位前:" << std::bitset<16>(a) << std::endl;

    a <<= 8;  //a=a<<8
    std::cout <<"左移8位前:"<< std::bitset<16>(a)<<std::endl;
}

2)右移:右移相当于/2,即a/(2n),如a右移2位,即a/(22)

#include <iostream>
#include <bitset>

int main()
{
    int a{ 0b100000001100 };
    std::cout <<"左移8位前:" << std::bitset<16>(a) << std::endl;

    a <<= 8;  //a=a<<8    左移8位
    std::cout <<"左移8位前:"<< std::bitset<16>(a)<<std::endl;

    a >>= 8;  //右移8位
    std::cout << "右移8位后:" << std::bitset<16>(a) << std::endl;

}

注:位运算左右移,正数补0,负数补1

#include <iostream>
#include <bitset>

int main()
{
    //int a{ 0b100000001100 };
    int a{ -3 };
    std::cout << a << std::endl;
    std::cout << "左移8位前:" << std::bitset<16>(a) << std::endl;

    a <<= 8;  //a=a<<8    左移8位
    std::cout << "左移8位前:" << std::bitset<16>(a) << std::endl;

    a >>= 8;  //右移8位
    std::cout << "右移8位后:" << std::bitset<16>(a) << std::endl;

}

注:在某些CPU下,*2操作会自动转化为位运算,因位运算运算较快。位运算时最好用unsigned类型,因为unsigned类型,在任何CPU下一定是补1,而int类型可能补0或者补1

3、求反运算、与运算

1)求反运算(~):按位取反,0变1、1便0

#include <iostream>
#include <bitset>

int main()
{
	int test{ 0xFFFF };
	std::cout << "求反之前:"<< std::bitset<32>(test) << std::endl;

	test = ~test; //求反
	std::cout << "求反之后:"<< std::bitset<32>(test) << std::endl;
}

2)与运算(&):见0为0,一般用于保留高位

//获取地址高位
#include <iostream>
#include <bitset>

int main()
{
	using std::showbase;   //显示八进制和十六进制前缀
	int test{ 0x2833 };
	std::cout << "正常  输出:" << std::hex<<showbase<<test << std::endl;

	test = test & 0xFF00; //与运算

	std::cout << "与运算之后:" << std::hex <<showbase<<test<< std::endl;
}

4、或运算、异或运算

1)或运算( | ):见1则为1,常用于,只要灯没打开,就把它打开

#include <iostream>
#include <bitset>

//直接将0x2833,调整位0xFF33,即将高位写满
int main()
{
	using std::showbase;   //显示八进制和十六进制前缀
	int test{ 0x2833 };
	std::cout << "正常  输出:" << std::hex << showbase << test << std::endl;

	test = test | 0xFF00; //或运算

	std::cout << "或运算之后:" << std::hex << showbase << test << std::endl;
}

2)异或运算( ^ ):相同为0,不同为1

#include <iostream>
#include <bitset>

int main()
{
	using std::showbase;   //显示八进制和十六进制前缀
	int test{ 0x2833 };
	std::cout << "正常  输出:" << std::hex << showbase << test << std::endl;

	test = test ^ 0xFF00; //异或运算

	std::cout << "或运算之后:" << std::hex << showbase << test << std::endl;
}

5、案例:完善游戏激活码,需求如下

1)我们收到了一位用户的激活请求,用户的硬件码为:930529060092641281,我们需要回馈给用户一个激活码,该激活码是N组16进制数,每组4位。例如:192E-987E-675E-3E98-9172-972E。设计我们游戏中的激活部分程序,通过输出该激活码可以激活用户的游戏,

2)激活码中包含了16个等级的初始金币礼包,计算方式为:等级*等级*10000,包含了用户初始幸运属性,分为16个等级,这将影响到用户日后游戏中的爆率。

3)我们还赠送了三件装备,分别是武器、护甲、首饰、这三件装备等级分为16个阶,适用不同的等级阶段,最高可以强化至16,比如武器,可以是16阶强化+16。根据激活码对用户初始装备进行强化

4)同时要求我们的激活码还具备一定的防伪能力,能够与用户的硬件码相呼应,即在其他的电脑中不能使用(我们假设用户提交的硬件码是唯一的)

#include <iostream>

int main()
{
	long long mcode{ 930529060092641281 }; //用户提供的硬件码
	long long test_code{ (int)0xF2349876EF56CA24LL }; //内置测试码
	long long end = mcode ^ test_code;  //第一次异或,计算出激活码
	//std::cout << end << std::endl;     
	std::cout << "给予用户的激活码为:"<< std::hex << end << "2556595f" << std::endl;  //给用户的激活码,f316 18bf ef56 ca25 2556 595f

	//模拟用户输入激活码,1、2、3、4组代表机器码,5、6组代表用户初始属性
	unsigned short in_code1, in_code2, in_code3, in_code4, in_code5, in_code6;
	std::cin >> std::hex;    //因激活码为16进制数,因此切换输入流为16进制
	std::cout << "请输入第一组激活码:";
	std::cin >> in_code1;
	std::cout << "请输入第二组激活码:";
	std::cin >> in_code2;
	std::cout << "请输入第三组激活码:";
	std::cin >> in_code3;
	std::cout << "请输入第四组激活码:";
	std::cin >> in_code4;
	std::cout << "请输入第五组激活码:";
	std::cin >> in_code5;
	std::cout << "请输入第六组激活码:";
	std::cin >> in_code6;

	//将用户输入的激活码,按照每组进行取出
	long long end_final{};
	long long ls{}; //临时变量
	ls = in_code1;
	ls <<= 48;      //获取到第一组激活码
	//std::cout << ls << std::endl;  //f316000000000000
	end_final |= ls;

	ls = in_code2;
	ls <<= 32;
	end_final |= ls;    
	//std::cout << ls << std::endl; //18bf00000000

	ls = in_code3;
	ls <<= 16;
	//std::cout << ls << std::endl; //ef560000
	end_final |= ls;
	end_final |= in_code4;
	std::cout <<"取出的用户激活码为:"<< end_final << std::endl;  //将用户输入的激活码,完整取出

	long long mcode_calc = end_final ^ test_code;     //将用户输入的激活码和游戏内置测试码进行比较,若计算结果不是用户机器码,则不予激活
	std::cout << "计算出的用户机器码为:"<<std::dec << mcode_calc << std::endl;

	if (mcode_calc == mcode)
	{
		std::cout << "你输入的激活码正确,游戏激活成功!!!\n";
		//f316 18bf ef56 ca25 2556 595f
		//定义第1位至8为分别代表金币礼包等级、幸运等级、武器的阶、武器的强化等级、护甲的阶、护甲的强化等级、首饰的阶、首饰的强化等级、
		unsigned gmoney{};   //金币礼包等级
		gmoney = (in_code5 & 0xF000) >> 12;  //0x2000
		gmoney *= gmoney;
		gmoney *= 10000;
		std::cout << "你获得的初始金币为:" << gmoney << std::endl;
		
		char gluck{};  //角色幸运等级
		gluck = (in_code5 & 0x0F00) >> 8;  //0x0500
		std::cout << "你的幸运值为:" << (short)gluck << std::endl;

		char weapon_lv; //武器的阶
		weapon_lv = (in_code5 & 0x00F0) >> 4;
		std::cout << "你的武器阶为::" << (short)weapon_lv << std::endl;

		char weapon_ev; //武器的强化
		weapon_ev = (in_code5 & 0x000F) ;
		std::cout << "你的武器阶为::" << (short)weapon_ev << std::endl;

		char army_lv{}; //护甲的阶
		army_lv = (in_code6 & 0xF000) >> 12;
		std::cout << "你的护甲阶为::" << (short)army_lv << std::endl;

		char army_ev{}; //护甲的等级
		army_ev = (in_code6 & 0x0F00) >> 8;
		std::cout << "你的护甲等级为:" << (short)army_ev << std::endl;

		char neck_lv{}; //首饰的阶
		neck_lv = (in_code6 & 0x00F0) >> 4;
		std::cout << "你的首饰阶为:" << (short)neck_lv << std::endl;

		char neck_ev{}; //首饰的等级
		neck_ev = (in_code6 & 0x000F);
		std::cout << "你的首饰等级为:" << (short)neck_ev + 1<< std::endl;
	}
	else
	{
		std::cout << "你输入的激活码错误,游戏激活失败!!!\n";
	}
}

标签:std,运算,int,激活码,include,cout
From: https://www.cnblogs.com/piaolaipiaoqu/p/17827146.html

相关文章

  • 无涯教程-Dart - 运算符
    在本章中,我们将讨论Dart中可用的运算符。算术运算符关系运算符类型运算符按位运算符赋值运算符逻辑运算符算术运算符下表显示了Dart支持的算术运算符。Sr.NoOperators&Meaning1+相加2-相减3-expr一元减号,也称为负数4*相乘5/相除6~/相除,返回整......
  • 运算2
    #include<iostream>usingnamespacestd;intmain(intargc,char**argv){stringn;intx=0;intn1,n2;getline(cin,n);if(n.find("")>=0&&n.find("")<n.size()){for(inti=0;i<n.size(......
  • 四则运算
    #include<bits/stdc++.h>usingnamespacestd;intf(stringa,stringb);//计算stringno1(stringx);//清除空格intmain(){stringa;getline(cin,a);a=no1(a);if(a.find("+")>0&&a.find("+")<a.size()){......
  • 四则运算(don't完整)
    #include<bits/stdc++.h>usingnamespacestd;stringkong(stringa){ while(a.find("")>=0&&a.find("")<=a.size()){ a.replace(a.find(""),1,""); } returna;}intb(stringa,stringb){ intc......
  • 四则运算
    #include<bits/stdc++.h>usingnamespacestd;intjs(stringa,stringb);//计算//intjianfa(stringa);//intchengfa(stringa);//intchufa(stringa);stringno1(stringx);//清除空格intmain(){ stringa; getline(cin,a); a=no1(a); if(a.find("+&......
  • PHP 中的相等性比较运算符(== 双等号)和恒等性比较运算符(=== 三等号)有什么区别?
    内容来自DOC[https://q.houxu6.top/?s=PHP中的相等性比较运算符(==双等号)和恒等性比较运算符(===三等号)有什么区别?](https://q.houxu6.top/?s=PHP中的相等性比较运算符(%3D%3D双等号)和恒等性比较运算符(%3D%3D%3D三等号)有什么区别?)==和===之间有什么区别?宽松的==......
  • F 和和和 (与运算)
    F和和和Description:给定两个非负整数\(a,b\),判断是否存在两个非负整数\(x,y\),使得\(x+y=a\)且\(x\&y=b\)。其中,\(\&\)表示二进制的按位与运算。Constraints:\(1\leqT\leq10^5\)\(0\leqa,b\leq10^{18}\)Analysis:数据量显然不能够枚举模拟,那就从......
  • 加号优先级高于 三目运算。低于括号。
    假设val已经声明,可定义为任何值。则下面js代码有可能输出的结果为:console.log('Valueis'+(val!='0')?'define':'undefine');AValueisdefineBValueisundefineCdefineDundefineEValueisdefine或者ValueisundefineFdefine或者undef......
  • 四则运算
    #include<iostream>#include<stack>#include<deque>#include<string>usingnamespacestd;//C++混合四则运算intpri(charc)//标识运算符优先级{switch(c){case'+':case'-':return0;break;......
  • 运算
    #include<iostream>usingnamespacestd;intmain(intargc,char**argv){ stringn; intx=0; intn1,n2; getline(cin,n); if(n.find("")>0&&n.find("")<n.size()){ for(inti=0;i<n.size();i++){ x=n.find(&q......