• 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:
    ");
        for (int i = 0; i < 32; i++) {
            int v = 1 << i;
            bitset<32> b(v);
            printf("%12u(%s): %2d  %s 
    ", v, b.to_string().c_str(), __builtin_clz(v), __builtin_clz(v) == 31 - i ? "OK" : "Err");
        }
        printf("
    ");
    
        // ctz
        printf("__builtin_ctz:
    ");
        for (int i = 0; i < 32; i++) {
            int v = 1 << i;
            bitset<32> b(v);
            printf("%12u(%s): %2d  %s 
    ", v, b.to_string().c_str(), __builtin_ctz(v), __builtin_ctz(v) == i ? "OK" : "Err");
        }
    
        return 0;
    }
    

    感谢CSND论坛的zwfgdlc提供帮助

  • 相关阅读:
    闭包函数 (字符编码,文件处理,函数基础总结)
    函数参数详解
    文件处理及函数基础
    文件处理高级
    面向对象----反射
    正则表达式与re模块
    常用模块
    模块和包
    内置函数与匿名函数
    HDU
  • 原文地址:https://www.cnblogs.com/gleam/p/5025867.html
Copyright © 2020-2023  润新知