Python - 当初版
bitmask.py
# b5-b3のマスクを得る.
startbit=3 # startbitをb3
bitlen=3 # startbitを含めて3bitのビット長(b5b4b3)
b=0
for i in range(startbit, startbit + bitlen):
b|=1<<i
bin(b) #=> '0b111000'
# b10-b0のマスクを得る.
startbit=0 # startbitをb0
bitlen=11 # startbitを含め11bitのビット長(b10...b1b0)
b=0
for i in range(startbit, startbit + bitlen):
b|=1<<i
bin(b) # '0b11111111111'
# b49-45のマスクを得る.
startbit=45 # startbitをb45
bitlen=5 # startbitを含め5bitのビット長(b49b48b47b46b45)
b=0
for i in range(startbit, startbit + bitlen):
b|=1<<i
bin(b) #=> '0b11111000000000000000000000000000000000000000000000'
Python - shiracamusさん版
bitmask.py
def bitmask(startbit, bitlen):
return ((1 << bitlen) - 1) << startbit
startbit=3, bitlen=3で具体化すると、補数的な感じでマスクが求められていることがわかる
1 << bitlen :
1 <<3 = 0b1000
(1 << bitlen) - 1 :
(1 << 3) - 1 = 0b1000 - 1 = 0b111
(1 << bitlen) - 1) << starbit :
((1 << 3) - 1) << 3 = 0b111 << 3 = 0b111000
C - 当初版
- bitmask(0,64)(b63-b0のbitmask)が作成できないバグあり(コメント参照)
bitmask.c
#include <stdio.h>
unsigned long long bitmask1(
unsigned char startbit,
unsigned char bitlen
){
return (((unsigned long long)0x1 << bitlen)-0x1) << startbit;
}
C - shiracamusさん版
bitmask2.c
unsigned long long bitmask2(
unsigned char startbit,
unsigned char bitlen
){
if (startbit >= 64) return 0;
if (bitlen >= 64) return ~0ULL << startbit;
return ((1ULL << bitlen) - 1ULL) << startbit;
}
C - 第3版
いろいろ考えた結果、あまり面白くない感じになりました。
* 間違いがあったため、修正(bm %= 64u; → bitlen %= 64u;)
実行結果比較
http://melpon.org/wandbox/permlink/hTrTCCmfgjORuGsT
bitmask3.c
unsigned long long bitmask3(
unsigned char startbit,
unsigned char bitlen
){
unsigned long long bm = 0x0UL;
if (bitlen == 64u){
bm = ~(0x0ULL);
} else {
bitlen %= 64u;
bm = (0x1ULL << bitlen) - 0x1ULL ;
}
startbit %= 64u;
bm <<= startbit;
return bm ;
}