位运算符之算法一
eg::求 a*b%p;
掌握位运算符的用法来解决这道题
总所周知任何一个整数都可以用不同的若干指数不同的2的次幂的和。
假设b的二进制位数为k,C表示每一位的数值哦!
b=C(k-1)2^(k-1)+…+C02(0);
ab=aC(k-1)*2(k-1)x…xa^C0*2(0);;
也就是用乘法表示出来,
用k次a的次幂相乘。
当C为零的时候这个a的次幂也就为一,经过每次判断b的最后一位来判断是否把得来的结果相乘。用(b&1)来表示用b>>=1来进行中间转换。
每次判断都把a变成的平方。
下面看一下代码:
#include<stdio.h>
int main(void)
{
int a,b,p;//如果题目要求数值int范围以内
scanf("%d %d %d",&a,&b,&p);
int sum=1%p;//防止p为1的时候加以判断
while(b)
{
if(b&1)
{
sum=(long long)suma%p;//相乘可能会溢出,先用longlong暂时存储,最后再次转换成int
}
b>>=1;
a=(long long)aa%p;//同上
}
printf("%d\n",sum);
return 0;
}
最后补充一下两个知识点。
第一个知识:假如我定义一个int a;
是不是只要不把a赋值一个带符号的数,这个数就会直接存储到内存中,
也就是在内存中这个数本身就是补码,就假如0xffffffff;也不例外
但是如果我直接给他赋值为负数,就会先对这个数进行从原码到补码的转换。
然后再存储到内存中。
第二个知识:
由于16进制和八进制只支持无符号的输出
假如我定义一个int 类型的a=-0x1;
然后输出 为0xffffffff;
然后我试了一下用 char类型定义一个b=-0x1;
然后再用16进制输出,按照我的思想应该是0xff,也就是一个字节的长度,
但是结果仍然是0xffffffff;
这就是16进制和8进制系统默认为int类型数据。