std/bitops
SourceEditЭтот модуль реализует ряд методов низкого уровня для работы с битами.
По умолчанию, там, где это возможно, используются встроенные функции компилятора для повышения производительности на поддерживаемых компиляторах: GCC, LLVM_GCC, CLANG, VCC, ICC.
Модуль переходит к чистым процедурам Nim, если бэкенд не поддерживается. Вы также можете использовать флаг noIntrinsicsBitOpts для отключения встроенных функций компилятора.
Этот модуль также совместим с другими бэкендами: JavaScript, NimScript а также с compiletime VM.
В результате использования оптимизированных функций/встроенных функций некоторые функции могут возвращать неопределённые результаты, если входные данные некорректны. Вы можете использовать флаг noUndefinedBitOpts для принудительного обеспечения предсказуемого поведения для всех входных данных, что приведёт к небольшой потере производительности.
В настоящее время только fastLog2, firstSetBit, countLeadingZeroBits и countTrailingZeroBits могут возвращать неопределённые и/или зависящие от платформы значения, если предоставлены некорректные входные данные.
Импорты
- macros, since, bitops_utils, countbits_impl
Типы
Процедуры
func bitnot[T: SomeInteger](x: T): T {.magic: "BitnotI", ...raises: [], tags: [], forbids: [].}- Вычисляет
bitwise complementцелого числаx. Исходный код Редактировать proc bitslice[T: SomeInteger](v: var T; slice: Slice[int]) {.inline.}- Изменяет
vв извлечённый (и сдвинутый) срез битов изv.Пример:
var x = 0b101110 x.bitslice(2 .. 4) doAssert x == 0b011
Исходный код Редактировать func bitsliced[T: SomeInteger](v: T; slice: Slice[int]): T {.inline.}- Возвращает извлечённый (и сдвинутый) срез битов из
v.Пример:
doAssert 0b10111.bitsliced(2 .. 4) == 0b101 doAssert 0b11100.bitsliced(0 .. 2) == 0b100 doAssert 0b11100.bitsliced(0 ..< 3) == 0b100
Исходный код Редактировать proc clearBit[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.}- Изменяет
v, установив бит в позицииbitв 0.Пример:
var v = 0b0000_0011'u8 v.clearBit(1'u8) doAssert v == 0b0000_0001'u8
Исходный код Редактировать proc clearMask[T: SomeInteger](v: var T; mask: T) {.inline.}-
Изменяет
v, установив все1биты сmaskв 0.Эффективно соответствует операции bitand с инвертированной маской.
Пример:
var v = 0b0000_0011'u8 v.clearMask(0b0000_1010'u8) doAssert v == 0b0000_0001'u8
Исходный код Редактировать proc clearMask[T: SomeInteger](v: var T; slice: Slice[int]) {.inline.}-
Изменяет
v, установив все1биты в диапазонеsliceв 0.Эффективно соответствует операции bitand с инвертированной маской.
Пример:
var v = 0b0000_0011'u8 v.clearMask(1 .. 3) doAssert v == 0b0000_0001'u8
Исходный код Редактировать func clearMasked[T: SomeInteger](v, mask: T): T {.inline.}-
Возвращает
v, установив все1биты сmaskв 0.Эффективно соответствует операции bitand с инвертированной маской.
Пример:
let v = 0b0000_0011'u8 doAssert v.clearMasked(0b0000_1010'u8) == 0b0000_0001'u8
Исходный код Редактировать func clearMasked[T: SomeInteger](v: T; slice: Slice[int]): T {.inline.}-
Возвращает
v, установив все1биты в диапазонеsliceв 0.Эффективно соответствует операции bitand с инвертированной маской.
Пример:
let v = 0b0000_0011'u8 doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
Исходный код Редактировать func countLeadingZeroBits(x: SomeInteger): int {.inline.}-
Возвращает количество старших нулевых битов в целом числе. Если
xравно нулю, когдаnoUndefinedBitOptsустановлено, результат равен 0, в противном случае результат не определён.См. также:
Пример:
doAssert countLeadingZeroBits(0b0000_0001'u8) == 7 doAssert countLeadingZeroBits(0b0000_0010'u8) == 6 doAssert countLeadingZeroBits(0b0000_0100'u8) == 5 doAssert countLeadingZeroBits(0b0000_1000'u8) == 4 doAssert countLeadingZeroBits(0b0000_1111'u8) == 4
Исходный код Редактировать func countSetBits(x: SomeInteger): int {.inline.}- Считает установленные биты в целое число (также называется весом Хэмминга).
Пример:
doAssert countSetBits(0b0000_0011'u8) == 2 doAssert countSetBits(0b1010_1010'u8) == 4
Исходный код Редактировать func countTrailingZeroBits(x: SomeInteger): int {.inline.}-
Возвращает количество концевых нулей в целом числе. Если
xравно нулю, когдаnoUndefinedBitOptsустановлено, результат равен 0, в противном случае результат не определён.См. также:
Пример:
doAssert countTrailingZeroBits(0b0000_0001'u8) == 0 doAssert countTrailingZeroBits(0b0000_0010'u8) == 1 doAssert countTrailingZeroBits(0b0000_0100'u8) == 2 doAssert countTrailingZeroBits(0b0000_1000'u8) == 3 doAssert countTrailingZeroBits(0b0000_1111'u8) == 0
Исходный код Редактировать func fastLog2(x: SomeInteger): int {.inline.}- Быстро находит логарифм по основанию 2 целого числа. Если
xравно нулю, когдаnoUndefinedBitOptsустановлено, результат равен -1, в противном случае результат не определён.Пример:
doAssert fastLog2(0b0000_0001'u8) == 0 doAssert fastLog2(0b0000_0010'u8) == 1 doAssert fastLog2(0b0000_0100'u8) == 2 doAssert fastLog2(0b0000_1000'u8) == 3 doAssert fastLog2(0b0000_1111'u8) == 3
Исходный код Редактировать func firstSetBit(x: SomeInteger): int {.inline.}- Возвращает индекс (с учётом 1) наименее значащего установленного бита
x. Еслиxравно нулю, когдаnoUndefinedBitOptsустановлено, результат равен 0, в противном случае результат не определён.Пример:
doAssert firstSetBit(0b0000_0001'u8) == 1 doAssert firstSetBit(0b0000_0010'u8) == 2 doAssert firstSetBit(0b0000_0100'u8) == 3 doAssert firstSetBit(0b0000_1000'u8) == 4 doAssert firstSetBit(0b0000_1111'u8) == 1
Исходный код Редактировать proc flipBit[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.}- Изменяет
v, инвертируя бит в позицииbit.Пример:
var v = 0b0000_0011'u8 v.flipBit(1'u8) doAssert v == 0b0000_0001'u8 v = 0b0000_0011'u8 v.flipBit(2'u8) doAssert v == 0b0000_0111'u8
Исходный код Редактировать proc flipMask[T: SomeInteger](v: var T; mask: T) {.inline.}-
Изменяет
v, инвертируя все1биты сmask.Эффективно соответствует операции bitxor.
Пример:
var v = 0b0000_0011'u8 v.flipMask(0b0000_1010'u8) doAssert v == 0b0000_1001'u8
Исходный код Редактировать proc flipMask[T: SomeInteger](v: var T; slice: Slice[int]) {.inline.}-
Изменяет
v, инвертируя все1биты в диапазонеslice.Эффективно соответствует операции bitxor.
Пример:
var v = 0b0000_0011'u8 v.flipMask(1 .. 3) doAssert v == 0b0000_1101'u8
Исходный код Редактировать func flipMasked[T: SomeInteger](v, mask: T): T {.inline.}-
Возвращает
v, инвертируя все1биты сmask.Эффективно соответствует операции bitxor.
Пример:
let v = 0b0000_0011'u8 doAssert v.flipMasked(0b0000_1010'u8) == 0b0000_1001'u8
Исходный код Редактировать func flipMasked[T: SomeInteger](v: T; slice: Slice[int]): T {.inline.}-
Возвращает
v, инвертируя все1биты в диапазонеslice.Эффективно соответствует операции bitxor.
Пример:
let v = 0b0000_0011'u8 doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
Исходный код Редактировать
proc mask[T: SomeInteger](v: var T; mask: T) {.inline.}-
Изменяет
v, при этом только биты1изmaskсовпадающие с битамиvустанавливаются в 1.Эффективно соответствует операции bitand.
Пример:
var v = 0b0000_0011'u8 v.mask(0b0000_1010'u8) doAssert v == 0b0000_0010'u8
Исходный код Изменить proc mask[T: SomeInteger](v: var T; slice: Slice[int]) {.inline.}-
Изменяет
v, при этом только биты1в диапазонеsliceсовпадающие с битамиvустанавливаются в 1.Эффективно соответствует операции bitand.
Пример:
var v = 0b0000_1011'u8 v.mask(1 .. 3) doAssert v == 0b0000_1010'u8
Исходный код Изменить proc masked[T: SomeInteger](v, mask: T): T {.inline.}-
Возвращает
v, при этом только биты1изmaskсовпадающие с битамиvустанавливаются в 1.Эффективно соответствует операции bitand.
Пример:
let v = 0b0000_0011'u8 doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
Исходный код Изменить func masked[T: SomeInteger](v: T; slice: Slice[int]): T {.inline.}-
Возвращает
v, при этом только биты1в диапазонеsliceсовпадающие с битамиvустанавливаются в 1.Эффективно соответствует операции bitand.
Пример:
let v = 0b0000_1011'u8 doAssert v.masked(1 .. 3) == 0b0000_1010'u8
Исходный код Изменить func parityBits(x: SomeInteger): int {.inline.}- Вычисление чётности бита в целом числе. Если количество битов 1 нечётное, чётность равна 1, иначе 0.
Пример:
doAssert parityBits(0b0000_0000'u8) == 0 doAssert parityBits(0b0101_0001'u8) == 1 doAssert parityBits(0b0110_1001'u8) == 0 doAssert parityBits(0b0111_1111'u8) == 1
Исходный код Изменить func popcount(x: SomeInteger): int {.inline.}- Псевдоним для countSetBits (вес Хэмминга). Исходный код Изменить
func reverseBits[T: SomeUnsignedInt](x: T): T
- Возвращает обращение битов x.
Пример:
doAssert reverseBits(0b10100100'u8) == 0b00100101'u8 doAssert reverseBits(0xdd'u8) == 0xbb'u8 doAssert reverseBits(0xddbb'u16) == 0xddbb'u16 doAssert reverseBits(0xdeadbeef'u32) == 0xf77db57b'u32
Исходный код Изменить func rotateLeftBits[T: SomeUnsignedInt](value: T; shift: range[0 .. (sizeof(T) * 8)]): T {. inline.}- Циклический сдвиг влево битов в
value.Пример:
doAssert rotateLeftBits(0b0110_1001'u8, 4) == 0b1001_0110'u8 doAssert rotateLeftBits(0b00111100_11000011'u16, 8) == 0b11000011_00111100'u16 doAssert rotateLeftBits(0b0000111111110000_1111000000001111'u32, 16) == 0b1111000000001111_0000111111110000'u32 doAssert rotateLeftBits(0b00000000111111111111111100000000_11111111000000000000000011111111'u64, 32) == 0b11111111000000000000000011111111_00000000111111111111111100000000'u64
Исходный код Изменить func rotateRightBits[T: SomeUnsignedInt](value: T; shift: range[0 .. (sizeof(T) * 8)]): T {.inline.}- Циклический сдвиг вправо битов в
value.Пример:
doAssert rotateRightBits(0b0110_1001'u8, 4) == 0b1001_0110'u8 doAssert rotateRightBits(0b00111100_11000011'u16, 8) == 0b11000011_00111100'u16 doAssert rotateRightBits(0b0000111111110000_1111000000001111'u32, 16) == 0b1111000000001111_0000111111110000'u32 doAssert rotateRightBits(0b00000000111111111111111100000000_11111111000000000000000011111111'u64, 32) == 0b11111111000000000000000011111111_00000000111111111111111100000000'u64
Исходный код Изменить proc setBit[T: SomeInteger](v: var T; bit: BitsRange[T]) {.inline.}- Изменяет
v, устанавливая бит в позицииbitв 1.Пример:
var v = 0b0000_0011'u8 v.setBit(5'u8) doAssert v == 0b0010_0011'u8
Исходный код Изменить proc setMask[T: SomeInteger](v: var T; mask: T) {.inline.}-
Изменяет
v, устанавливая все биты1изmaskв 1.Эффективно соответствует операции bitor.
Пример:
var v = 0b0000_0011'u8 v.setMask(0b0000_1010'u8) doAssert v == 0b0000_1011'u8
Исходный код Изменить proc setMask[T: SomeInteger](v: var T; slice: Slice[int]) {.inline.}-
Изменяет
v, устанавливая все биты1в диапазонеsliceв 1.Эффективно соответствует операции bitor.
Пример:
var v = 0b0000_0011'u8 v.setMask(2 .. 3) doAssert v == 0b0000_1111'u8
Исходный код Изменить func setMasked[T: SomeInteger](v, mask: T): T {.inline.}-
Возвращает
v, устанавливая все биты1изmaskв 1.Эффективно соответствует операции bitor.
Пример:
let v = 0b0000_0011'u8 doAssert v.setMasked(0b0000_1010'u8) == 0b0000_1011'u8
Исходный код Изменить func setMasked[T: SomeInteger](v: T; slice: Slice[int]): T {.inline.}-
Возвращает
v, устанавливая все биты1в диапазонеsliceв 1.Эффективно соответствует операции bitor.
Пример:
let v = 0b0000_0011'u8 doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
Исходный код Изменить proc testBit[T: SomeInteger](v: T; bit: BitsRange[T]): bool {.inline.}- Возвращает true, если бит в
vв позицииbitравен 1.Пример:
let v = 0b0000_1111'u8 doAssert v.testBit(0) doAssert not v.testBit(7)
Исходный код Изменить func toMask[T: SomeInteger](slice: Slice[int]): T {.inline.}- Создаёт битовую маску на основе слайса битов.
Пример:
doAssert toMask[int32](1 .. 3) == 0b1110'i32 doAssert toMask[int32](0 .. 3) == 0b1111'i32
Исходный код Изменить
Макросы
macro bitand[T: SomeInteger](x, y: T; z: varargs[T]): T
- Вычисляет
bitwise andвсех аргументов коллективно. Исходный код Изменить macro bitor[T: SomeInteger](x, y: T; z: varargs[T]): T
- Вычисляет
bitwise orвсех аргументов коллективно. Исходный код Изменить macro bitxor[T: SomeInteger](x, y: T; z: varargs[T]): T
- Вычисляет
bitwise xorвсех аргументов коллективно. Исходный код Изменить macro clearBits(v: typed; bits: varargs[typed]): untyped
- Изменяет
v, устанавливая биты в позицияхbitsв 0.Пример:
var v = 0b1111_1111'u8 v.clearBits(1, 3, 5, 7) doAssert v == 0b0101_0101'u8
Исходный код Изменить macro flipBits(v: typed; bits: varargs[typed]): untyped
- Изменяет
v, устанавливая биты в позицияхbitsв 0.Пример:
var v = 0b0000_1111'u8 v.flipBits(1, 3, 5, 7) doAssert v == 0b1010_0101'u8
Исходный код Изменить macro setBits(v: typed; bits: varargs[typed]): untyped
- Изменяет
v, устанавливая биты в позицияхbitsв 1.Пример:
var v = 0b0000_0011'u8 v.setBits(3, 5, 7) doAssert v == 0b1010_1011'u8
Исходный код Изменить
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/bitops.html