摘要:本篇文章介绍计算二进制数字尾部连续0的数目的相关算法,例如:v=(1101000)2,该数尾部连续0的数目=3方法1:线性时间算法unsigned int v; // 需要计算的目标整数int c; // c用来保存计算的结果if (v){ v = (v ^ (v - 1)) >> 1; for (c = 0; v; c++) { v >>= 1; }}else{ c = CHAR_BIT * sizeof(v);}原理比较简单,下面提供一段C测试代码,根据代码显示的结果不难理解算法:#include#include#includevoid tranlate(long
阅读全文
随笔分类 - 位操作
摘要:本篇文章介绍一个整数的以10为底的对数的整数部分,即对于整数N,求log10(N)整数部分方法一 :unsigned int v; //32位非0整数 int r; // r保存结果int t; //临时变量static unsigned int const PowersOf10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};t = (IntegerLogBase2(v) + 1) * 1233 >> 12; //使用之前介绍过的...
阅读全文
摘要:本篇文章主要讲述几种反转比特位的方法:将一个32位数:abcd efgh 转置为hgfe dcba1、常规方法unsigned int v; // 目标待转置数unsigned int r = v; //r保存反转后的结果,开始获取v的最低有效位int s = sizeof(v) * CHAR_BIT - 1; // 剩余需要移位的比特位for (v >>= 1; v; v >>= 1){ r > 8) & 0xff] > 16) & 0xff] > 24) & 0xff]);原理:通过嵌套宏定义构造一张表,BitReverse
阅读全文
摘要:本文主要介绍一系列算法,算法主要功能是判断一个数字(二进制)中是否包含全零字节e.g.1010 1111 0000 0000 1001 1111 0001 1111即 32位整数:A4A3A2A1中Ai =0(i=1 or 2 or 3 or 4)// 较少操作算法版本:unsigned int v; // 32位整型目标整数判断是否包含全0字节bool hasZeroByte = ~((((v & 0x7F7F7F7F) + 0x7F7F7F7F) | v) | 0x7F7F7F7F);原理:0x7F7F7F7F=0111 1111 0111 1111 0111 1111 0111
阅读全文
摘要:位操作允许程序员对单独的位进行操作,例如,早某些机器上,短整型占16位,位操作将每一位单独操作。位操作允许程序员设置、清除、测试与其他的操作,这些操作如下表:操作含义&按位与|按位或^按位异或~取反<<左移>>右移这些操作用于整型或者字符型1、按位与(&)Bit1Bit2Bit1 & Bit2000010100111通常我们可把按位“与”操作 & 作为关闭某位(即将该位置0)的手段,例如我们想要关闭a数中的第3位,而又不影响其它位的现状,可以用一个数0xF7,即二进制数1111 0111去与a数作按位“与”运算: 0x88 1000 10
阅读全文
摘要:unsigned int a; // value to merge in non-masked bitsunsigned int b; // value to merge in masked bitsunsigned int mask; //if mask=1,结果数据从b中选择,else 从a中选择unsigned int r; //结果r= (a & ~mask) | (b & mask)r = a ^ ((a ^ b) & mask); C测试代码: 1 #include<stdio.h> 2 #include<string.h> 3 4
阅读全文
摘要:不使用选择分支语句按条件设置、清除比特位:bool f; // 条件标识符 flagunsigned int m; // 比特掩码unsigned int w; // 需要设置的数字: if (f) w |= m; else w &= ~m; w ^= (-f ^ w) & m;//或者,对于超标量cpuw = (w & ~m) | (-f & m);C测试代码如下: 1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 bool f; //条件标志 7 u...
阅读全文
摘要:可变位宽的符号扩展: 有时,我们需要扩展数字的符号位,但是我们不知道该数字的总位数,如果用b表示(或者我们可能会使用类似于java这样缺乏位域的语言编程)unsigned b; // 表示数x的位数int x; //将这个b位数符号扩展到r位int r; // 保存r位数字int const m = 1U << (b - 1); // 如果b固定,中间量可以提前计算x = x & ((1U << b) - 1); // (Skip this if bi...
阅读全文
摘要:计算机的内嵌类型进行自动的符号扩展,比如char与int类型等等,但是也许你遇到一个有符号的二进制补码数x,并且使用仅仅b位,更进一步,也许你需要将x转化为整型,如果x为正数,一个简单的复制操作就可以搞定,但是如果为负数,符号位必须扩展。例如:假如我们仅仅用4位来存储一个数,于是-3用二进制就表示为1101,如果我们用8位,那么-3就表示为11111101.最值得注意的位是4位的相关数使用更多位数在左边进行填充,这被称为“符号扩展”,在C语言中,符号扩展对于固定长度的数很普通,因为位域可能是结构体或是联合体,例如:将5位数转换为全整型:int x; //待转换的数int r; //...
阅读全文
摘要:unsigned int v; // 判断v是否为2的幂bool f; // f为判断的结果f = (v & (v - 1)) == 0; // 结果为0表示不是2 的幂// 改变表示方法,可以使用下面的方法:f = v && !(v & (v - 1));
阅读全文
摘要:不用选择分支找出指定两整数中的最大值与最小值:int x; int y; // 找出x与y的最大值与最小值int r; // r保存结果r = y ^ ((x ^ y) & -(x < y)); // min(x, y)在一些很少的机器上,分支比较很耗资源,而且没有条件移动指令存在,以上的实现可能比传统的方法:r = (x < y) ? x : y要快。即使比后者多执行两步指令。(通常,前面的方法要快)它的工作原理如下:如果x<y,那么-(x-y)全部为1, 结果r= y ^ (x ^ y) & ~0 = y ^ x ^ y = x.否则,如果x>=y,
阅读全文
摘要:判断两整数是否异号:int x, y; //输入比较的两数bool f = ((x ^ y) < 0); // 返回真,当且仅当x与y异号说明:当x、y异号,x与y的最高位分别为0和1,取"^"后为1,结果为负数不用选择语句得到指定整数的绝对值:int v; // 需要得到整数v的绝对值unsigned int r; // r保存结果int const mask = v >> sizeof(int) * CHAR_BIT - 1;r = (v + mask) ^ mask; 变式:r = (v ^ mask) - mask;
阅读全文
摘要:关于衡量计算操作的方法: 当为算法统计操作的数量的时候,所有的C运算符被认为是一样的操作。中间过程不被写入随机存储器(RAM)而不被计算,当然,这种操作数的计算方法,只是作为那些接近机器指令和CPU运行时间的服务。所有的操作被假设成花相同的运行时间,事实上是不正确的。有很多不同的因素决定一个系统能多快运行一段样例代码,例如:缓存大小,内存带宽,指令集合等等……。最后,建立一套标准才是衡量一种方法快过另一种方法的最好方法。 判断一个整数的符号int v; // v为我们要判断的整数int sign; // 保存结果 sign = -(v < 0); // if v < 0 si...
阅读全文

浙公网安备 33010602011771号