是否存在简单的按位运算(包括加法,mod等),它可以产生以下输出,类似于cur = 6 ...
这是为了使用x264中的字段图片对L0参考列表进行排序。
field_ref_dist( cur, ref );
f( 1, 0 ) = 0
f( 2, 1 ) = 1
f( 2, 0 ) = 0
f( 3, 2 ) = 1
f( 3, 1 ) = 0
f( 3, 0 ) = 2
f( 4, 3 ) = 1
f( 4, 2 ) = 0
f( 4, 1 ) = 3
f( 4, 0 ) = 2
f( 5, 4 ) = 1
f( 5, 3 ) = 0
f( 5, 2 ) = 3
f( 5, 1 ) = 2
f( 5, 0 ) = 4
答案 0 :(得分:1)
我不确定我是否正确推断了这些值,但如果我这样做了,
unsigned field_ref_dist(unsigned cur, unsigned ref) {
return ((cur - ref - 1) & ~1u) + ((cur - ref) & !!ref);
}
做到了:
f(1, 0) = 0
f(2, 1) = 1
f(2, 0) = 0
f(3, 2) = 1
f(3, 1) = 0
f(3, 0) = 2
f(4, 3) = 1
f(4, 2) = 0
f(4, 1) = 3
f(4, 0) = 2
f(5, 4) = 1
f(5, 3) = 0
f(5, 2) = 3
f(5, 1) = 2
f(5, 0) = 4
f(6, 5) = 1
f(6, 4) = 0
f(6, 3) = 3
f(6, 2) = 2
f(6, 1) = 5
f(6, 0) = 4
f(7, 6) = 1
f(7, 5) = 0
f(7, 4) = 3
f(7, 3) = 2
f(7, 2) = 5
f(7, 1) = 4
f(7, 0) = 6
f(8, 7) = 1
f(8, 6) = 0
f(8, 5) = 3
f(8, 4) = 2
f(8, 3) = 5
f(8, 2) = 4
f(8, 1) = 7
f(8, 0) = 6
f(9, 8) = 1
f(9, 7) = 0
f(9, 6) = 3
f(9, 5) = 2
f(9, 4) = 5
f(9, 3) = 4
f(9, 2) = 7
f(9, 1) = 6
f(9, 0) = 8
它甚至可能与查找表一样快。
暂时忽略案例ref == 0
和cur
奇数,这些值自然可以成对分组(2*k, 2*k+1)
,而值只取决于cur - ref
之间的差异cur - ref - 1
交换这些对,我们只有2*k
。因此,为了获得这些对的较小值 - (cur - ref - 1) & ~1u
- 我们可以掩盖最低有效位,因此
1
现在,对的顺序实际上是较大的(奇数)值用于较小(奇数)的差异,因此如果差异是奇数,我们添加((cur - ref - 1) & ~1u) + ((cur - ref) & 1u)
,
cur
适用于除ref == 0
奇数和cur - 1
之外的所有情况,在这种情况下,该值必须为& ~1u
(然后是偶数,因此((cur - ref - 1) & ~1u) + ((cur - ref) & 1u)
不会更改它)而不是0
。
因此,对于这种特殊情况,加数应为1
而不是(cur - ref) & 0
。我们从1
得到了这一点,因此我们需要一个为ref
生成0
的操作,为ref == 0
生成cur
[如果((cur - ref) & 1u) == 0
是偶数,差异也是偶数,1u
,因此0
替换ref == 0
!!ref
不会触及。这是通过{{1}}实现的。