VC中实现GCC的2个比较常用的位运算函数
在GCC中内嵌了两个位运算的函数,但在VC中并没有这两个函数(有相似函数)。
//返回前导的0的个数。
int __builtin_clz (unsigned int x)
//返回后面的0个个数,和__builtin_clz相对。
int __builtin_ctz (unsigned int x)
这两个函数在radix tree中直接计算索引,对性能有一定要求。
自己写有些效率问题不是很理想,所以想确定vc2015 版本中是否有带已经优化过的函数。
在网上兜了一圈,没有找到类似VC实现的代码。折腾了半天没找到解决方案,后来到CSDN上发了个贴解决问题。
VC相似函数
_BitScanForward()
[ref]: https://msdn.microsoft.com/en-us/library/wfd9z0bb.aspx
_BitScanReverse()
[ref]: https://msdn.microsoft.com/en-us/library/fbxyd7zd.aspx
有64位版本的处理,需要处理一下就和GCC中得到相同结果
基本原理
- 正向扫描指令BSF(BitScan Forward)从右向左扫描,即:从低位向高位扫描;
- 逆向扫描指令BSR(BitScan Reverse)从左向右扫描,即:从高位向低位扫描。
处理方法
下面简单实现这两个函数。把这两个测试代码贴出来供遇到同样问题的人提帮助。
输出的值和GCC版本是一致的,可直接使用。
vc test code(32位)
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <bitset>
using namespace std;
__inline int __builtin_clz(int v)
{
if (v == 0)
return 31;
__asm
{
bsr ecx, dword ptr[v];
mov eax, 1Fh;
sub eax, ecx;
}
}
__inline int __builtin_ctz(int v)
{
int pos;
if (v == 0)
return 0;
__asm
{
bsf eax, dword ptr[v];
}
}
int main()
{
// clz
printf("__builtin_clz:\n");
for (int i = 0; i < 32; i++) {
int v = 1 << i;
bitset<32> b(v);
printf("%12u(%s): %2d %s \n", v, b.to_string().c_str(), __builtin_clz(v), __builtin_clz(v) == 31 - i ? "OK" : "Err");
}
printf("\n");
// ctz
printf("__builtin_ctz:\n");
for (int i = 0; i < 32; i++) {
int v = 1 << i;
bitset<32> b(v);
printf("%12u(%s): %2d %s \n", v, b.to_string().c_str(), __builtin_ctz(v), __builtin_ctz(v) == i ? "OK" : "Err");
}
return 0;
}
感谢CSND论坛的zwfgdlc提供帮助
VC中实现GCC的2个比较常用的位运算函数的更多相关文章
- 剑指offer-面试题56_1-数组中只出现一次的两个数字-位运算
/* 题目: 求数组A中只出现一次的数字,该数组中有2个数字a.b仅出现一次,其余均出现两次 */ /* 思路: 两个相同的数字异或为0. 遍历数组,得到数组中各数字异或后的结果x,结果x=a^b. ...
- 状态压缩中常用的位运算(DP)
面对位运算,一直很无感...可能数学太差,脑洞太小. 1.首先是最基本的: 与&,或|,非~,异或^. 2.获取一个或者多个固定位的值: 假设 x = 1010(二进制),我们要取左数第二位的 ...
- C语言中的位运算的技巧
一.位运算实例 1.用一个表达式,判断一个数X是否是2的N次方(2,4,8,16.....),不可用循环语句. X:2,4,8,16转化成二进制是10,100,1000,10000.如果减1则变成01 ...
- C#枚举中的位运算权限分配
什么是位运算 常用的位运算主要有与(&), 或(|)和非(~), 比如: & = ; | = ; ~ = ; 运用在权限设计中 先建立一个枚举表示所有的权限管理操作: [Flags] ...
- 旧文备份:VC中嵌入NASM编写的汇编函数
在公司开发的RT下没法使用C库,并且替代库函数没有几个,需要用到setjmp和longjmp函数,没办法,只能自己想办法了,上sourceforge淘换到一个小日本的工程,提供这两个函数的替代源码,名 ...
- VC++中StretchBlt图像失真问题的解决办法
在 VC 中使用 StretchBlt 会碰到一些与点阵图大小缩放相关的一些问题.在扩展一个点阵图时,StretchBlt必须复制图素行或列.如果放大倍数不是原图的整数倍,那么此操作会造成产生的图像有 ...
- VC++中开发汇编语言(转)
汇编程序结构 一个显示字符串的汇编程序 程序格式 一.模式定义 二.includelib语句 三.函数声明语句 四.数据和代码部分 Visual C/C++环境 建立工程 汇编程序的调试 一.设置断点 ...
- VC中实现文字竖排的简单方法
好多人都觉得在VC中实现文字竖排是一件很难的事情,其实可以使用“躺”着的字体很方便的实现文字竖排. Windows中有一些字体是“躺”着的,例如:@Fixedsys.@System.@宋体.@黑体等等 ...
- VC中基于 Windows 的精确定时[转]
在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等.特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要 ...
随机推荐
- [系统] 安装Ubuntu 双系统 - 失败
因为工作原因, 所以需要装ubuntu系统. 在网络上查了一下, 一般都是使用U盘安装. 但是由于手头上既没有U盘又没有光盘,只能用硬盘安装了. 查一下, 使用wubi安装方式从硬盘安装, 非常方便. ...
- Android开发-API指南-Android简介
Introduction to Android 英文原文:http://developer.android.com/intl/zh-cn/guide/index.html 采集日期:2014-4-16 ...
- 华为OJ平台——矩阵乘法
题目描述: 如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C. 输入: 1.第一个矩阵的行数 2.第一个矩阵的列数(也是第二个矩阵的行数) 3.第二个矩阵 ...
- phpexcel 导入导出
导出excel /** * 以下是使用示例,对于以 //// 开头的行是不同的可选方式,请根据实际需要 * 打开对应行的注释. * 如果使用 Excel5 ,输出的内容应该是GBK编码. */ //r ...
- CLRS:Insert sort in in c
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>#define ...
- centreon 画图x轴乱码
rrdtool默认不指定locale,使用本地locale.乱码我估记是中文字体,由于操作系统最小化安装,本地没有中文字体,导致乱码. 1 安装中文字体 yum -y install wqy-zenh ...
- Linux:/bin/bash和/bin/sh的区别
bash.dash(/bin/bash和/bin/sh) 原文:http://www.cnblogs.com/dkblog/archive/2011/04/02/2003822.html Linux中 ...
- 【linux】 静态库编译
文件如下: root@ubuntu:/home/test# ll total drwxr-xr-x root root Sep : ./ drwxr-xr-x root root Sep : ../ ...
- poj2027
#include <stdio.h> int main(){ int n; int a,b; while(~scanf("%d",&n)){ while(n-- ...
- 盒子的padding不影响总的大小css代码
-moz-box-sizing: border-box; /*Firefox3.5+*/-webkit-box-sizing: border-box; /*Safari3.2+*/-o-box-siz ...