0

次の出力を生成できる単純なビット単位の操作 (加算、mod などを含む) はありますか?

これは、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
4

1 に答える 1

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。からそれを取得するため、非ゼロとfor [が偶数の場合、差も偶数であり、 forに置き換えても影響されない](cur - ref) & 0を生成する操作が必要です。それはによって達成されます。1ref0ref == 0cur((cur - ref) & 1u) == 01u0ref == 0!!ref

于 2013-01-19T00:00:21.913 に答える