c语言素数求余能用位运算,C语言,开篇-位运算

位运算有很大的妙用,在C语言中发扬光大。有什么作用呢?在数据结构和算法中有个很重要的概念就是:时间和空间。位运算就可以提高时间的效率和空间的利用率。

一、位运算增加空间的利用率。

没有什么神奇之处,只是以紧凑的二进制格式来描述数据结构,应用之多举不胜举。记住,最小的存储单元是bit而不是byte

二、位运算提高时间的效率。

根本原因是读取内存次数少,我们知道CPU一次读取内存的最大字节数和字长有关,正是因为把数据压缩在有限的数据结构中,读取内存的次数大大减少。

应用举例:

1、如何不使用中间变量,交换两个变量?

a = a ^ b;

b = a ^ b;

a = a ^ b;

可能会有人说使用加减法也可以,如:

a = a + b;

b = a - b;

a = a - b;

但是加减法是有副作用的,容易导致数据溢出。

2、状态的改变,我们可能经常写类似下面的代码:

if (b) {

b = false;

} else {

b = true;

}

或者更精简一点

b = b ? false : true;

但依然会别扭,因为你要改变一个标志的状态,首先要知道原有状态,使用位运算可以避免

b ^= b;

3、位向量,很多底层库中都有位向量的类,可用于很多场合,高效环保。我自己写了一个位向量,求解1亿一下素数,时间不到3秒,内存占用不到13M,可见位运算的威力。

#define LONG_BIT_LENGTH sizeof(long)

#define BIT_SHIFT_UNIT (LONG_BIT_LENGTH/8 + 1)

#define BIT_MASK (LONG_BIT_LENGTH-1)

//位向量结构:方便同时使用多个位向量

typedef struct tag_bit_vector {

long *bit_buffer; //数据区

long max_bit_num; //总bit数

}TBitVector;

//========================================================================================

//分配一个位向量

TBitVector *mallc_bit_vector(long bit_max) {

TBitVector *pbit_vector = 0;

pbit_vector = (TBitVector *)malloc(sizeof(TBitVector));

if (pbit_vector == NULL) return NULL;

pbit_vector->bit_buffer = (long *)calloc(LONG_BIT_LENGTH, (bit_max + BIT_MASK) >> BIT_SHIFT_UNIT);

if (pbit_vector->bit_buffer == NULL) return NULL;

pbit_vector->max_bit_num = bit_max;

return pbit_vector;

}

//释放一个位向量

void free_bit_vector(TBitVector *bit_vector) {

free(bit_vector->bit_buffer);

free(bit_vector);

}

//========================================================================================

//设置

void set_bit_vector(TBitVector *bit_vector, long idx) {

if (idx >= bit_vector->max_bit_num) return;

bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] |= 1 << (idx & BIT_MASK);

}

//清除

void cls_bit_vector(TBitVector *bit_vector, long idx) {

if (idx >= bit_vector->max_bit_num) return;

bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] &= ~(1 << (idx & BIT_MASK));

}

//探测

int test_bit(TBitVector *bit_vector, long idx) {

if (idx >= bit_vector->max_bit_num) return 0;

return bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] & (1 << (idx & BIT_MASK));

}

求解素数代码:

int sievePrime(TBitVector *pBitVerctor, unsigned long prime)

{

unsigned long i;

if (prime*prime >= pBitVerctor->max_bit_num)

{

return 0;

}

for (i=prime<<1; imax_bit_num; i+=prime)

{

set_bit_vector(pBitVerctor, i);

}

return -1;

}

//测试

#define PRIME_NUMBER_MAX 100000000

int main(int argc, char *argv[])

{

int milisection = 0;

int i = 0;

int primeCount = 0;

struct timeval start;

struct timeval end;

TBitVector *pdata = mallc_bit_vector(PRIME_NUMBER_MAX);

milisection = GetTickCount(&start);

for (i=2; i

{

if (test_bit(pdata, i))

continue;

if (sievePrime(pdata, i) == 0)

{

break;

}

}

GetTickCount(&end);

printf("times : %d\n", (end.tv_sec * 1000 * 1000 + end.tv_usec) - (start.tv_sec * 1000 * 1000 + start.tv_usec));

free_bit_vector(pdata);

getchar();

return 0;

}

总结: 位运算应用场景还有很多,要想用好,主要看你的抽象能力。现在是大内存和多核时代,没有必要时也不建议使用,除非用在密集运算或需要高效率的算法上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值