LoginSignup
3
3

More than 5 years have passed since last update.

下から(上から)nビットを立てたビットマスクを作る

Posted at

下から(LSBから)nビットが1のビットマスクを作りたいとき。もしくは上から(MSBから)について同様のものがほしい場合について。
ビット演算としては基本的だけど、定期的に自信がなくなってしまうのでまとめた。

下からnビットを立てたビットマスク

全部のビットが立ったものを左シフトしてからビット反転すればよい。
定数のロード、シフト、NOTで合計3命令。

uint32_t f(int n)
{
  return ~(0xffffffffu << n);
}

x86かつHaswell世代以降のCPUに特化していいのであれば、BMI2にbzhiという命令がある。
演算が1命令で済むようになる。

#include <immintrin.h>

uint32_t g(int n)
{
  return _bzhi_u32(0xffffffffu, n);
}

上からnビットを立てたビットマスク

ほぼ同様のやり方ができる。全部のビットが立ったものを右シフトしてからビット反転すればよい。

uint32_t h(int n)
{
  return ~(0xffffffffu >> n);
}

下からnビットには特化した命令としてbzhiがあったが、bzloというものは存在しない様子。

アセンブリの確認

出力の確認はCompiler Explorerを使った。とても便利。
https://godbolt.org/z/mtStCk

f(int):                                  # @f(int)
        mov     eax, -1
        shlx    eax, eax, edi
        not     eax
        ret
g(int):                                  # @g(int)
        mov     eax, -1
        bzhi    eax, eax, edi
        ret
h(int):                                  # @h(int)
        mov     eax, -1
        shrx    eax, eax, edi
        not     eax
        ret
3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3