Spec-Zone.ru › Nim 1

bitops

Этот модуль реализует ряд методов низкого уровня для работы с битами.

По умолчанию этот модуль использует встроенные функции компилятора, где это возможно, для повышения производительности на поддерживаемых компиляторах: GCC, LLVM_GCC, CLANG, VCC, ICC.

Модуль переключится на чистые процедуры Nim, если бэкенд не поддерживается. Вы также можете использовать флаг noIntrinsicsBitOpts для отключения встроенных функций компилятора.

Этот модуль также совместим с другими бэкендами: Javascript, Nimscript а также с compiletime VM.

В результате использования оптимизированных функций/встроенных функций, некоторые функции могут возвращать неопределенные результаты, если входные данные некорректны. Вы можете использовать флаг noUndefinedBitOpts для принудительного обеспечения предсказуемого поведения для всех входных данных, что приведет к небольшой потере производительности.

В настоящее время только fastLog2, firstSetBit, `countLeadingZeroBits, countTrailingZeroBits могут возвращать неопределенные и/или зависящие от платформы значения, если на вход поданы некорректные данные.

Импорты

macros, since

Типы

BitsRange[T] = range[0 .. sizeof(T) * 8 - 1]
Диапазон со всеми позициями битов для типа T Исходный код Изменить

Процедуры

proc bitnot[T: SomeInteger](x: T): T {...}{.magic: "BitnotI", noSideEffect.}
Вычисляет 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
Исходный код Редактировать
proc masked[T: SomeInteger](v, mask: T): T {...}{.inline.}

Возвращает v, с установленными в 1 только 1 битами из mask, совпадающими с битами v.

Эффективно соответствует операции bitand.

Пример:

var v = 0b0000_0011'u8
doAssert v.masked(0b0000_1010'u8) == 0b0000_0010'u8
Исходный код Редактировать
proc mask[T: SomeInteger](v: var T; mask: T) {...}{.inline.}

Изменяет v, с установленными в 1 только 1 битами из mask, совпадающими с битами v.

Эффективно соответствует операции 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 только 1 битами в диапазоне slice, совпадающими с битами v.

Эффективно соответствует операции bitand.

Пример:

var v = 0b0000_1011'u8
v.mask(1 .. 3)
doAssert v == 0b0000_1010'u8
Исходный код Редактировать
proc setMask[T: SomeInteger](v: var T; mask: T) {...}{.inline.}

Изменяет v, с установленными в 1 всеми 1 битами из mask.

Эффективно соответствует операции 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 всеми 1 битами в диапазоне slice.

Эффективно соответствует операции bitor.

Пример:

var v = 0b0000_0011'u8
v.setMask(2 .. 3)
doAssert v == 0b0000_1111'u8
Исходный код Редактировать
proc clearMask[T: SomeInteger](v: var T; mask: T) {...}{.inline.}

Изменяет v, с установленными в 0 всеми 1 битами из mask.

Эффективно соответствует операции 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, с установленными в 0 всеми 1 битами в диапазоне slice.

Эффективно соответствует операции bitand с инвертированной маской.

Пример:

var v = 0b0000_0011'u8
v.clearMask(1 .. 3)
doAssert v == 0b0000_0001'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
Исходный код Редактировать
proc setBit[T: SomeInteger](v: var T; bit: BitsRange[T]) {...}{.inline.}
Изменяет v, с установленным в 1 битом на позиции bit

Пример:

var v = 0b0000_0011'u8
v.setBit(5'u8)
doAssert v == 0b0010_0011'u8
Исходный код Редактировать
proc clearBit[T: SomeInteger](v: var T; bit: BitsRange[T]) {...}{.inline.}
Изменяет v, с установленным в 0 битом на позиции bit

Пример:

var v = 0b0000_0011'u8
v.clearBit(1'u8)
doAssert v == 0b0000_0001'u8
Исходный код Редактировать
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 testBit[T: SomeInteger](v: T; bit: BitsRange[T]): bool {...}{.inline.}
Возвращает true, если бит в v на позициях bit равен 1

Пример:

var v = 0b0000_1111'u8
doAssert v.testBit(0)
doAssert not v.testBit(7)
Исходный код Редактировать
proc countSetBits(x: SomeInteger): int {...}{.inline, noSideEffect.}
Считает установленные биты в целое число. (также называется весом Хэмминга.)

Пример:

doAssert countSetBits(0b0000_0011'u8) == 2
doAssert countSetBits(0b1010_1010'u8) == 4
Исходный код Редактировать
proc popcount(x: SomeInteger): int {...}{.inline, noSideEffect.}
Псевдоним для countSetBits. (Вес Хэмминга.) Исходный код Редактировать
proc parityBits(x: SomeInteger): int {...}{.inline, noSideEffect.}
Вычисляет чётность бит в целом числе. Если количество 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
Исходный код Редактировать
proc firstSetBit(x: SomeInteger): int {...}{.inline, noSideEffect.}
Возвращает индекс (с учётом нумерации с 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 fastLog2(x: SomeInteger): int {...}{.inline, noSideEffect.}
Быстро находит логарифм по основанию 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
Исходный код Редактировать
proc countLeadingZeroBits(x: SomeInteger): int {...}{.inline, noSideEffect.}

Возвращает количество ведущих нулевых бит в целом числе. Если x равно нулю, когда noUndefinedBitOpts установлено, результат равен 0, иначе результат неопределён.

См. также:

  • countTrailingZeroBits proc

Пример:

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
Исходный код Редактировать
proc countTrailingZeroBits(x: SomeInteger): int {...}{.inline, noSideEffect.}

Возвращает количество концевых нулей в целом числе. Если x равно нулю, когда noUndefinedBitOpts установлено, результат равен 0, иначе результат неопределён.

См. также:

  • countLeadingZeroBits proc

Пример:

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
Исходный код Редактировать
proc rotateLeftBits(value: uint8; amount: range[0 .. 8]): uint8 {...}{.inline,
    noSideEffect, raises: [], tags: [].}
Циклический сдвиг влево бит в значении 8 бит.

Пример:

doAssert rotateLeftBits(0b0000_0001'u8, 1) == 0b0000_0010'u8
doAssert rotateLeftBits(0b0000_0001'u8, 2) == 0b0000_0100'u8
doAssert rotateLeftBits(0b0100_0001'u8, 1) == 0b1000_0010'u8
doAssert rotateLeftBits(0b0100_0001'u8, 2) == 0b0000_0101'u8
Исходный код Редактировать
proc rotateLeftBits(value: uint16; amount: range[0 .. 16]): uint16 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Циклический сдвиг влево бит в значении 16 бит.

См. также:

  • rotateLeftBits proc
Исходный код Редактировать
proc rotateLeftBits(value: uint32; amount: range[0 .. 32]): uint32 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Побитовое циклическое сдвиг влево на 32 бита.

См. также:

  • rotateLeftBits proc
Источник Изменить
proc rotateLeftBits(value: uint64; amount: range[0 .. 64]): uint64 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Побитовое циклическое сдвиг влево на 64 бита.

См. также:

  • rotateLeftBits proc
Источник Изменить
proc rotateRightBits(value: uint8; amount: range[0 .. 8]): uint8 {...}{.inline,
    noSideEffect, raises: [], tags: [].}
Побитовое циклическое сдвиг вправо на 8 бит.

Пример:

doAssert rotateRightBits(0b0000_0001'u8, 1) == 0b1000_0000'u8
doAssert rotateRightBits(0b0000_0001'u8, 2) == 0b0100_0000'u8
doAssert rotateRightBits(0b0100_0001'u8, 1) == 0b1010_0000'u8
doAssert rotateRightBits(0b0100_0001'u8, 2) == 0b0101_0000'u8
Источник Изменить
proc rotateRightBits(value: uint16; amount: range[0 .. 16]): uint16 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Побитовое циклическое сдвиг вправо на 16 бит.

См. также:

  • rotateRightBits proc
Источник Изменить
proc rotateRightBits(value: uint32; amount: range[0 .. 32]): uint32 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Побитовое циклическое сдвиг вправо на 32 бита.

См. также:

  • rotateRightBits proc
Источник Изменить
proc rotateRightBits(value: uint64; amount: range[0 .. 64]): uint64 {...}{.inline,
    noSideEffect, raises: [], tags: [].}

Побитовое циклическое сдвиг вправо на 64 бита.

См. также:

  • rotateRightBits proc
Источник Изменить
proc reverseBits[T: SomeUnsignedInt](x: T): T {...}{.noSideEffect.}
Возвращает инвертированный битовый порядок 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 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
Источник Изменить
func toMask[T: SomeInteger](slice: Slice[int]): T {...}{.inline.}
Создает битовую маску на основе фрагмента битов.

Пример:

doAssert toMask[int32](1 .. 3) == 0b1110'i32
doAssert toMask[int32](0 .. 3) == 0b1111'i32
Источник Изменить
func masked[T: SomeInteger](v: T; slice: Slice[int]): T {...}{.inline.}

Изменяет v, используя только биты 1 в диапазоне slice , сопоставляя их с v и устанавливая в 1.

Эффективно отображается как операция bitand.

Пример:

var v = 0b0000_1011'u8
doAssert v.masked(1 .. 3) == 0b0000_1010'u8
Источник Изменить
func setMasked[T: SomeInteger](v, mask: T): T {...}{.inline.}

Возвращает v, устанавливая все биты 1 из mask в 1.

Эффективно отображается как операция bitor.

Пример:

var 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.

Пример:

var v = 0b0000_0011'u8
doAssert v.setMasked(2 .. 3) == 0b0000_1111'u8
Источник Изменить
func clearMasked[T: SomeInteger](v, mask: T): T {...}{.inline.}

Возвращает v, сбрасывая все биты 1 из mask в 0.

Эффективно отображается как операция bitand с инвертированной маской.

Пример:

var 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 с инвертированной маской.

Пример:

var v = 0b0000_0011'u8
doAssert v.clearMasked(1 .. 3) == 0b0000_0001'u8
Источник Изменить
func flipMasked[T: SomeInteger](v, mask: T): T {...}{.inline.}

Возвращает v, инвертируя все биты из 1 из mask.

Эффективно отображается как операция bitxor.

Пример:

var 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.

Пример:

var v = 0b0000_0011'u8
doAssert v.flipMasked(1 .. 3) == 0b0000_1101'u8
Источник Изменить

Макросы

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 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
Источник Изменить
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
Источник Изменить

© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/bitops.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API