vpp代码中有一个clib.h,其中封装了很一些很经典的位运算:

 //计算以2为底的对数,log2(x)
//也就是计算2的N次方为x。x为uint32类型
#if defined (count_leading_zeros)
always_inline uword
min_log2 (uword x)
{
uword n;
n = count_leading_zeros (x);
return BITS (uword) - n - ;
}
#else
always_inline uword
min_log2 (uword x)
{
uword a = x, b = BITS (uword) / , c = , r = ; /* Reduce x to 4 bit result. */
#define _ \
{ \
c = a >> b; \
if (c) a = c; \
if (c) r += b; \
b /= ; \
} if (BITS (uword) > )
_;
_;
_;
_;
#undef _ /* Do table lookup on 4 bit partial. */
if (BITS (uword) > )
{
const u64 table = 0x3333333322221104LL;
uword t = (table >> ( * a)) & 0xf;
r = t < ? r + t : ~;
}
else
{
const u32 table = 0x22221104;
uword t = (a & ) ? : ((table >> ( * a)) & 0xf);
r = t < ? r + t : ~;
} return r;
}
#endif //计算以2为底的对数(有余数的话+1),log2(x)
//也就是计算2的N次方为x。2的N次方大于x
always_inline uword
max_log2 (uword x)
{
uword l = min_log2 (x);
if (x > ((uword) << l))
l++;
return l;
} //计算以2为底的对数,log2(x)
//也就是计算2的N次方为x。x为u64类型
always_inline u64
min_log2_u64 (u64 x)
{
if (BITS (uword) == )
return min_log2 (x);
else
{
uword l, y;
y = x;
l = ;
if (y == )
{
l += ;
x >>= ;
}
l += min_log2 (x);
return l;
}
} //计算基数2的x次幂的值对应的掩码
//比如2的4次幂为16,对应的掩码为15
always_inline uword
pow2_mask (uword x)
{
return ((uword) << x) - (uword) ;
} //计算数字x对应的,以基数2的n次幂的值。x小于等于n
//比如x=15,则得出的数字为16.2的3次幂小于x,2的4次幂大于x。
always_inline uword
max_pow2 (uword x)
{
word y = (word) << min_log2 (x);
if (x > y)
y *= ;
return y;
} //计算x是否可等于基数2的n次幂
//比如x=16,返回1.x=15,返回0
always_inline uword
is_pow2 (uword x)
{
return == (x & (x - ));
} //计算x以pow2对齐的长度。pow2应该为2的n次方。
//如x=15,pow2=4,则返回16。
always_inline uword
round_pow2 (uword x, uword pow2)
{
return (x + pow2 - ) & ~(pow2 - );
} //计算x以pow2对齐的长度。pow2应该为2的n次方。
//如x=15,pow2=4,则返回16。
always_inline u64
round_pow2_u64 (u64 x, u64 pow2)
{
return (x + pow2 - ) & ~(pow2 - );
} //保留二进制下最后出现的1的位置,其余位置置0(即一个数中最大的2的n次幂的因数
//当一个偶数与它的负值向与时,结果是能被这个偶数整除的最大的2的n次幂
//当一个奇数与它的负值向与时结果一定是1
always_inline uword
first_set (uword x)
{
return x & -x;
} //先将x用first_set计算结果,
//然后以2为底做对数运算
always_inline uword
log2_first_set (uword x)
{
uword result;
#ifdef count_trailing_zeros
result = count_trailing_zeros (x);
#else
result = min_log2 (first_set (x));
#endif
return result;
} //将浮点数强转为整型(小数部分舍去)
always_inline f64
flt_round_down (f64 x)
{
return (int) x;
} //将浮点数强转为整型(小数部分四舍五入)
always_inline word
flt_round_nearest (f64 x)
{
return (word) (x + .);
} //若x大于f的一半,则返回f,否则返回0
always_inline f64
flt_round_to_multiple (f64 x, f64 f)
{
return f * flt_round_nearest (x / f);
} //计算x右移start位后,再截取count位有效数字是多少
always_inline uword
extract_bits (uword x, int start, int count)
{
#ifdef __BMI__
return _bextr_u64 (x, start, count);
#endif
return (x >> start) & pow2_mask (count);
} //取x和y两个数中大的数
#define clib_max(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x > _y ? _x : _y; \
}) //取x和y两个数中较小的数
#define clib_min(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x < _y ? _x : _y; \
}) //取x和y两个数中较大的数
#define clib_max(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x > _y ? _x : _y; \
}) //取x的绝对值
//定义类型与x相同的临时变量_x,并将x的值赋予_x
//取绝对值
#define clib_abs(x) \
({ \
__typeof__ (x) _x = (x); \
_x < ? -_x : _x; \
})

vpp之clib.h分析的更多相关文章

  1. ioctl.h 分析

    ioctl.h 分析 我自己画了个解析图...不要嫌弃丑啊.. . 哈哈 type The magic number. Just choose one number (after consulting ...

  2. SGI STL源码stl_vector.h分析

    前言 vector 是最常用的 C++ 容器,其动态扩容的特性是普通数组不具备的,这大大增加了编程的灵活性.虽然平时用 vector 很多,也能基本理解其原理,但无法从深层次理解.直到研读了 vect ...

  3. ios的xxxAppDelegate.h分析

    #import "BIDAppDelegate.h" #import "BIDViewController.h" @implementation BIDAppD ...

  4. SGI STL源码stl_bvector.h分析

    前言 上篇文章讲了 STL vector 泛化版本的实现,其采用普通指针作为迭代器,可以接受任何类型的元素.但如果用来存储 bool 类型的数据,可以实现功能,但每一个 bool 占一个字节(byte ...

  5. String源码分析

    前言:String类在日常开发过程中使用频率非常高,平时大家可能看过String的源码,但是真的认真了解过它么,笔者在一次笔试过程中要求写出String的equals方法,瞬间有点懵逼,凭着大致的理解 ...

  6. hashCode()方法源码分析

    执行代码 public class Demo06 { public static void main(String[] args) { String s="hello"; Syst ...

  7. Linux Linux程序练习十五(进程间的通信共享内存版)

    /* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2.子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进 ...

  8. C语言 百炼成钢3

    //题目7:用*号输出空心菱形图案 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...

  9. C语言 百炼成钢2

    //题目4:输入某年某月某日,判断这一天是这一年的第几天? #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<st ...

随机推荐

  1. SQL去掉重复数据

    SELECT vc_your_email,vc_our_ref_or_code INTO #tmp FROM( SELECT vc_your_email,vc_our_ref_or_code,ROW_ ...

  2. Hexo快速构建个人小站-自定义域名和自定义主题(二)

    背景交代: 在上一章<Hexo快速构建个人小站-Hexo初始化和将项目托管在Github(一)>中,我们已经成功的利用hexo初始化了博客项目,并托管在Github上,且通过Github的 ...

  3. cb47a_c++_STL_算法_排列组合next_prev_permutation

    cb47a_c++_STL_算法_排列组合next_prev_permutation 使用前必须先排序.必须是 1,2,3或者3,2,1.否者结果不准确.如果, 1,2,4,6.这样数据不会准确nex ...

  4. WINCC 应用与提高(78讲15.98G)视频教程网盘下载

    收集与网络,供参考. https://blog.csdn.net/txwtech/article/details/94225748

  5. WireShark——IP协议包分析(Ping分析IP协议包)

    互联网协议 IP 是 Internet Protocol 的缩写,中文缩写为“网协”.IP 协议是位于 OSI 模型中第三层的协议,其主要目的就是使得网络间能够互联通信.前面介绍了 ARP 协议, 该 ...

  6. 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相信相信的力量! 从懵懂的少年,到拿起键盘,可以写一个Hell ...

  7. java基础-java与c#的可变参数

    正文 可变参数,必须最为参数的最后一个参数:可变参数只能有一个: c#可变参数例子:       class Program { static void Main(string[] args) { T ...

  8. 一种基于LQR使输出更加稳定的算法(超级实用)

    已知: 令: 则: 以上三式成立 具体步骤: 状态量最后一行加入“上一时刻的控制量”: A,B根据上述方法变形: Q,R增加维度(控制量一般都为一个,此时R维度不变): 最关键的是——输出量已经变为“ ...

  9. ShellExecute指定IE浏览器打开网页

    ShellExecute(NULL,L"open", L"iexplore.exe", L"www.baidu.com", NULL, SW ...

  10. CountDownLatch和CyclicBarrier 傻傻的分不清?超长精美图文又来了

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...