This module contains a collection of bit-level operations.
Scans the bits in v starting with bit 0, looking for the first set bit.
assert(bsf(0x21) == 0); assert(bsf(ulong.max << 39) == 39);
Scans the bits in v from the most significant bit to the least significant bit, looking for the first set bit.
assert(bsr(0x21) == 5); assert(bsr((ulong.max >> 15) - 1) == 48);
Tests the bit. (No longer an intrisic - the compiler recognizes the patterns in the body.)
size_t[2] array; array[0] = 2; array[1] = 0x100; assert(bt(array.ptr, 1)); assert(array[0] == 2); assert(array[1] == 0x100);
Tests and complements the bit.
Tests and resets (sets to 0) the bit.
Tests and sets the bit.
size_t* p
| a non-NULL pointer to an array of size_ts. |
size_t bitnum
| a bit number, starting with bit 0 of p[0], and progressing. It addresses bits like the expression: p[index / (size_t.sizeof*8)] & (1 << (index & ((size_t.sizeof*8) - 1))) |
size_t[2] array;
array[0] = 2;
array[1] = 0x100;
assert(btc(array.ptr, 35) == 0);
if (size_t.sizeof == 8)
{
assert(array[0] == 0x8_0000_0002);
assert(array[1] == 0x100);
}
else
{
assert(array[0] == 2);
assert(array[1] == 0x108);
}
assert(btc(array.ptr, 35));
assert(array[0] == 2);
assert(array[1] == 0x100);
assert(bts(array.ptr, 35) == 0);
if (size_t.sizeof == 8)
{
assert(array[0] == 0x8_0000_0002);
assert(array[1] == 0x100);
}
else
{
assert(array[0] == 2);
assert(array[1] == 0x108);
}
assert(btr(array.ptr, 35));
assert(array[0] == 2);
assert(array[1] == 0x100);
Range over bit set. Each element is the bit number that is set.
This is more efficient than testing each bit in a sparsely populated bit set. Note that the first bit in the bit set would be bit 0.
import core.stdc.stdlib : malloc, free;
import core.stdc.string : memset;
// initialize a bit array
enum nBytes = (100 + BitRange.bitsPerWord - 1) / 8;
size_t *bitArr = cast(size_t *)malloc(nBytes);
scope(exit) free(bitArr);
memset(bitArr, 0, nBytes);
// set some bits
bts(bitArr, 48);
bts(bitArr, 24);
bts(bitArr, 95);
bts(bitArr, 78);
enum sum = 48 + 24 + 95 + 78;
// iterate
size_t testSum;
size_t nBits;
foreach (b; BitRange(bitArr, 100))
{
testSum += b;
++nBits;
}
assert(testSum == sum);
assert(nBits == 4);
Number of bits in each size_t
Construct a BitRange.
const(size_t)* bitarr
| The array of bits to iterate over |
size_t numBits
| The total number of valid bits in the given bit array |
Range functions
Swaps bytes in a 2 byte ushort.
ushort x
| value |
x with bytes swappedassert(byteswap(cast(ushort)0xF234) == 0x34F2); static ushort xx = 0xF234; assert(byteswap(xx) == 0x34F2);
Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 becomes byte 0.
assert(bswap(0x01020304u) == 0x04030201u); static uint xx = 0x10203040u; assert(bswap(xx) == 0x40302010u);
Swaps bytes in an 8 byte ulong end-to-end, i.e. byte 0 becomes byte 7, byte 1 becomes byte 6, etc. This is meant to be recognized by the compiler as an intrinsic.
assert(bswap(0x01020304_05060708uL) == 0x08070605_04030201uL); static ulong xx = 0x10203040_50607080uL; assert(bswap(xx) == 0x80706050_40302010uL);
Reads I/O port at port_address.
Writes and returns value to I/O port at port_address.
Calculates the number of set bits in an integer.
Calculates the number of set bits in an integer using the X86 SSE4 POPCNT instruction. POPCNT is not available on all X86 CPUs.
Reverses the order of bits in a 32-bit integer.
Reverses the order of bits in a 64-bit integer.
Bitwise rotate value left (rol) or right (ror) by count bit positions.
ubyte a = 0b11110000U; ulong b = ~1UL; assert(rol(a, 1) == 0b11100001); assert(ror(a, 1) == 0b01111000); assert(rol(a, 3) == 0b10000111); assert(ror(a, 3) == 0b00011110); assert(rol(a, 0) == a); assert(ror(a, 0) == a); assert(rol(b, 63) == ~(1UL << 63)); assert(ror(b, 63) == ~2UL); assert(rol!3(a) == 0b10000111); assert(ror!3(a) == 0b00011110);
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/core_bitop.html