From 15c32306eb82a81e2d251dc7f83943c3d5b541a9 Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Fri, 15 Apr 2022 14:46:58 +0200 Subject: [PATCH] 0.1.8 bitHelpers --- libraries/bitHelpers/CHANGELOG.md | 11 + libraries/bitHelpers/bitHelpers.cpp | 660 ++++++++++++++++++++++++ libraries/bitHelpers/bitHelpers.h | 591 +++------------------ libraries/bitHelpers/library.json | 2 +- libraries/bitHelpers/library.properties | 2 +- 5 files changed, 734 insertions(+), 532 deletions(-) create mode 100644 libraries/bitHelpers/bitHelpers.cpp diff --git a/libraries/bitHelpers/CHANGELOG.md b/libraries/bitHelpers/CHANGELOG.md index 7ed01ec3..3c8e366d 100644 --- a/libraries/bitHelpers/CHANGELOG.md +++ b/libraries/bitHelpers/CHANGELOG.md @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.1.8] - 2022-04-13 + +### Added + +### Changed +- split bitHelpers.h file into a .h and a .cpp file to prevent multiple declarations in some complexer projects. + + +### Fixed + + ## [0.1.7] - 2022-04-13 ### Added diff --git a/libraries/bitHelpers/bitHelpers.cpp b/libraries/bitHelpers/bitHelpers.cpp new file mode 100644 index 00000000..21496fd0 --- /dev/null +++ b/libraries/bitHelpers/bitHelpers.cpp @@ -0,0 +1,660 @@ +// +// FILE: bitHelpers.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.1.8 +// DATE: 2015-11-07 +// PURPOSE: Arduino library with functions on bit level +// URL: https://github.com/RobTillaart/bitHelpers +// +// HISTORY: See CHANGELOG.md + + +#include "bitHelpers.h" + + +//////////////////////////////////////////////// +// +// BIT COUNT TEST +// +uint8_t bitCountReference(uint32_t value) +{ + uint32_t v = value; + uint8_t count = 0; + while (v > 0) + { + if (v & 1) count++; + v >>= 1; + } + return count; +} + + +uint8_t bitCountKR(uint32_t value) +{ + // Kerningham & Ritchie + uint32_t v = value; + uint8_t count = 0; + while (v) + { + count++; + v &= (v - 1); + } + return count; +} + + +uint8_t bitCountArray(uint32_t value) +{ + uint8_t ar[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + uint32_t v = value; + uint8_t count = 0; + while (v) + { + count += ar[v & 0x0F]; + v >>= 4; + } + return count; +} + + +uint8_t bitCountF1(uint32_t value) +{ + // parallel adding in a register SWAG algorithm + uint32_t v = value; + v = v - ((v >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + v = (v + (v >> 4)) & 0x0F0F0F0F; + v = v + (v >> 8); + v = v + (v >> 16); + return v & 0x0000003F; +}; + + +uint8_t bitCountF2(uint32_t value) +{ + // parallel adding in a register SWAG algorithm + uint32_t v = value; + v = v - ((v >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + v = ((v + (v >> 4)) & 0x0F0F0F0F); + return ( v * 0x01010101) >> 24; +} + + +//////////////////////////////////////////////// +// +// BIT COUNT +// +uint8_t bitCount(uint8_t value) +{ + // parallel adding in a register SWAG algorithm + uint8_t v = value; + v = v - ((v >> 1) & 0x55); + v = (v & 0x33) + ((v >> 2) & 0x33); + v = (v + (v >> 4)) & 0x0F; + return v; +} + + +uint8_t bitCount(uint16_t value) +{ + // parallel adding in a register SWAG algorithm + uint16_t v = value; + v = v - ((v >> 1) & 0x5555); + v = (v & 0x3333) + ((v >> 2) & 0x3333); + v = (v + (v >> 4)) & 0x0F0F; + v = (v + (v >> 8)) & 0x1F; + return v; +} + + +uint8_t bitCount(uint32_t value) +{ + // parallel adding in a register SWAG algorithm + uint32_t v = value; + v = v - ((v >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + v = (v + (v >> 4)) & 0x0F0F0F0F; + v = v + (v >> 8); + v = (v + (v >> 16)) & 0x3F; + return v; +} + + +uint8_t bitCount(uint64_t value) +{ + // parallel adding in a register SWAG algorithm + uint64_t v = value; + v = v - ((v >> 1) & 0x5555555555555555); + v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); + v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0F; + v = v + (v >> 8); + v = v + (v >> 16); + v = (v + (v >> 32)) & 0x7F; + return v; +} + + +//////////////////////////////////////////////// +// +// BIT REVERSE +// +uint8_t bitReverse(uint8_t value) +{ + uint8_t x = value; + x = (((x & 0xAA) >> 1) | ((x & 0x55) << 1)); + x = (((x & 0xCC) >> 2) | ((x & 0x33) << 2)); + x = (x >> 4) | (x << 4); + return x; +} + + +uint16_t bitReverse(uint16_t value) +{ + uint16_t x = value; + x = (((x & 0xAAAA) >> 1) | ((x & 0x5555) << 1)); + x = (((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2)); + x = (((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4)); + x = (x >> 8) | (x << 8); + return x; +} + + +uint32_t bitReverse(uint32_t value) +{ + uint32_t x = value; + x = (((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1)); + x = (((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2)); + x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4)); + x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); + x = (x >> 16) | (x << 16); + return x; +} + + +uint64_t bitReverse(uint64_t value) +{ + uint64_t x = value; + x = (((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1)); + x = (((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2)); + x = (((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4)); + x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); + x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); + x = (x >> 32) | (x << 32); + return x; +} + + +//////////////////////////////////////////////// +// +// NYBBLE REVERSE +// +uint8_t nybbleReverse(uint8_t value) +{ + uint8_t x = value; + x = (x >> 4) | (x << 4); + return x; +} + + +uint16_t nybbleReverse(uint16_t value) +{ + uint16_t x = value; + x = (((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4)); + x = (x >> 8) | (x << 8); + return x; +} + + +uint32_t nybbleReverse(uint32_t value) +{ + uint32_t x = value; + x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4)); + x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); + x = (x >> 16) | (x << 16); + return x; +} + + +uint64_t nybbleReverse(uint64_t value) +{ + uint64_t x = value; + x = (((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4)); + x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); + x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); + x = (x >> 32) | (x << 32); + return x; +} + + +//////////////////////////////////////////////// +// +// BYTE REVERSE +// +uint16_t byteReverse(uint16_t value) +{ + uint16_t x = value; + x = (x >> 8) | (x << 8); + return x; +} + + +uint32_t byteReverse(uint32_t value) +{ + uint32_t x = value; + x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); + x = (x >> 16) | (x << 16); + return x; +} + + +uint64_t byteReverse(uint64_t value) +{ + uint64_t x = value; + x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); + x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); + x = (x >> 32) | (x << 32); + return x; +} + + +//////////////////////////////////////////////// +// +// WORD REVERSE +// +uint32_t wordReverse(uint32_t value) +{ + uint32_t x = value; + x = (x >> 16) | (x << 16); + return x; +} + + +uint64_t wordReverse(uint64_t value) +{ + uint64_t x = value; + x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); + x = (x >> 32) | (x << 32); + return x; +} + + +//////////////////////////////////////////////// +// +// SWAP HI LO +// +uint8_t swap(uint8_t value) +{ + return (value << 4) | (value >> 4); +} + + +uint16_t swap(uint16_t value) +{ + return (value << 8) | (value >> 8); +} + + +uint32_t swap(uint32_t value) +{ + return (value << 16) | (value >> 16); +} + + +uint64_t swap(uint64_t value) +{ + return (value << 32) | (value >> 32); +} + + +//////////////////////////////////////////////// +// +// BIT ROTATE LEFT +// +uint8_t bitRotateLeft(uint8_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 7) return value; + return (value << pos) | (value >> (8 - pos)); +} + + +uint16_t bitRotateLeft(uint16_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 15) return value; + return (value << pos) | (value >> (16 - pos)); +} + + +uint32_t bitRotateLeft(uint32_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 31) return value; + return (value << pos) | (value >> (32 - pos)); +} + + +uint64_t bitRotateLeft(uint64_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 63) return value; + return (value << pos) | (value >> (64 - pos)); +} + + +//////////////////////////////////////////////// +// +// BIT ROTATE RIGHT +// +uint8_t bitRotateRight(uint8_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 7) return value; + return (value << (8 - pos)) | (value >> pos); +} + + +uint16_t bitRotateRight(uint16_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 15) return value; + return (value << (16 - pos)) | (value >> pos); +} + + +uint32_t bitRotateRight(uint32_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 31) return value; + return (value << (32 - pos)) | (value >> pos); +} + + +uint64_t bitRotateRight(uint64_t value, uint8_t pos) +{ + if (pos == 0) return value; + if (pos > 63) return value; + return (value << (64 - pos)) | (value >> pos); +} + + +//////////////////////////////////////////////////// +// +// BIT FLIP +// +uint8_t bitFlip(uint8_t value, uint8_t pos) +{ + if (pos > 7) return value; + return value ^ (1 << pos); +} + + +uint16_t bitFlip(uint16_t value, uint8_t pos) +{ + if (pos > 15) return value; + return value ^ (1 << pos); +} + + +uint32_t bitFlip(uint32_t value, uint8_t pos) +{ + if (pos > 31) return value; + return value ^ (1UL << pos); +} + + +uint64_t bitFlip(uint64_t value, uint8_t pos) +{ + if (pos > 63) return value; + return value ^ (1ULL << pos); +} + + +//////////////////////////////////////////////////// +// +// BIT ROT +// +uint8_t bitRotRef(uint8_t value, float chance) +{ + if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; + return value ^ (1 << random(8)); +} + + +uint16_t bitRotRef(uint16_t value, float chance) +{ + if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; + return value ^ (1UL << random(16)); +} + + +uint32_t bitRotRef(uint32_t value, float chance) +{ + if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; + return value ^ (1UL << random(32)); +} + + +uint64_t bitRotRef(uint64_t value, float chance) +{ + if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; + return value ^ (1ULL << random(64)); +} + + +uint8_t bitRot(uint8_t value, float chance, uint16_t times) +{ + while(times--) + { + uint32_t r = random(BH_BIG_NR); + if ( r < chance * BH_BIG_NR) + { + value ^= (1 << (r & 7)); + } + } + return value; +} + + +uint16_t bitRot(uint16_t value, float chance, uint16_t times) +{ + while(times--) + { + uint32_t r = random(BH_BIG_NR); + if ( r < chance * BH_BIG_NR) + { + value ^= (1 << (r & 15)); + } + } + return value; +}; + + +uint32_t bitRot(uint32_t value, float chance, uint16_t times) +{ + while(times--) + { + uint32_t r = random(BH_BIG_NR); + if ( r < chance * BH_BIG_NR) + { + value ^= (1 << (r & 31)); + } + } + return value; +}; + + +uint64_t bitRot(uint64_t value, float chance, uint16_t times) +{ + while(times--) + { + uint32_t r = random(BH_BIG_NR); + if ( r < chance * BH_BIG_NR) + { + value ^= (1 << (r & 63)); + } + } + return value; +}; + + + + +//////////////////////////////////////////////////// +// +// BIT-SET64 -CLEAR64 -TOGGLE64 -READ64 -WRITE64 +// + +// FUNCTIONS +#if defined(__AVR__) +// optimized for performance + +void bitSet64(uint64_t & x, uint8_t n) +{ + if (n > 47) x |= (0x1000000000000 << (n - 48)); + else if (n > 31) x |= (0x100000000 << (n - 32)); + else if (n > 23) x |= (0x1000000 << (n - 24)); + else if (n > 15) x |= (0x10000 << (n - 16)); + else x |= (0x1 << n); +} + + +void bitClear64(uint64_t & x, uint8_t n) +{ + if (n > 47) x &= ~(0x1000000000000 << (n - 48)); + else if (n > 31) x &= ~(0x100000000 << (n - 32)); + else if (n > 23) x &= ~(0x1000000 << (n - 24)); + else if (n > 15) x &= ~(0x10000 << (n - 16)); + else x &= ~(0x1 << n); +} + + +void bitToggle64(uint64_t & x, uint8_t n) +{ + if (n > 47) x ^= (0x1000000000000 << (n - 48)); + else if (n > 31) x ^= (0x100000000 << (n - 32)); + else if (n > 23) x ^= (0x1000000 << (n - 24)); + else if (n > 15) x ^= (0x10000 << (n - 16)); + else x ^= (0x1 << n); +} + + +#elif defined(ESP32) +// optimized for performance + +void bitSet64(uint64_t & x, uint8_t n) +{ + if (n > 31) x |= (0x100000000 << (n - 32)); + else x |= (0x1 << n); +} + + +void bitClear64(uint64_t & x, uint8_t n) +{ + if (n > 31) x &= ~(0x100000000 << (n - 32)); + else x &= ~(0x1 << n); +} + + +void bitToggle64(uint64_t & x, uint8_t n) +{ + if (n > 31) x ^= (0x100000000 << (n - 32)); + else x ^= (0x1 << n); +} + + +#else +// slower reference implementation + +void bitSet64(uint64_t & x, uint8_t bit) +{ + x |= (1ULL << bit); +} + + +void bitClear64(uint64_t & x, uint8_t bit) +{ + x &= ~(1ULL << bit); +} + + +void bitToggle64(uint64_t & x, uint8_t bit) +{ + x ^= (1ULL << bit); +} + + +#endif + + +uint8_t bitRead64(uint64_t & x, uint8_t bit) +{ + return ((x & (1ULL << bit)) > 0); +} + + +void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value) +{ + if (value) bitSet64(x, bit); + else bitClear64(x, bit); +} + + +//////////////////////////////////////////////////// +// +// BITS NEEDED +// + +// reference +uint8_t bitsNeededRef(uint64_t x) +{ + uint8_t n = 0; + while (x) + { + x >>= 1; + n++; + } + return n; +} + + +// workers +uint8_t bitsNeeded(uint8_t x) +{ + uint8_t n = 0; + while (x) + { + x >>= 1; + n++; + } + return n; +} + + +uint8_t bitsNeeded(uint16_t x) +{ + uint8_t y = x >> 8; + if (y != 0) return bitsNeeded(y) + 8; + return bitsNeeded((uint8_t)x); +} + + +uint8_t bitsNeeded(uint32_t x) +{ + uint16_t y = x >> 16; + if (y != 0) return bitsNeeded(y) + 16; + return bitsNeeded((uint16_t)x); +} + + +uint8_t bitsNeeded(uint64_t x) +{ + uint32_t y = x >> 32; + if (x >> 32) return bitsNeeded(y) + 32; + return bitsNeeded((uint32_t)x); +} + + +// -- END OF FILE -- + diff --git a/libraries/bitHelpers/bitHelpers.h b/libraries/bitHelpers/bitHelpers.h index 6422907d..edb4f52e 100644 --- a/libraries/bitHelpers/bitHelpers.h +++ b/libraries/bitHelpers/bitHelpers.h @@ -2,7 +2,7 @@ // // FILE: bitHelpers.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.7 +// VERSION: 0.1.8 // DATE: 2015-11-07 // PURPOSE: Arduino library with functions on bit level // URL: https://github.com/RobTillaart/bitHelpers @@ -13,7 +13,7 @@ #include "Arduino.h" -#define BITHELPER_LIB_VERSION (F("0.1.7")) +#define BITHELPER_LIB_VERSION (F("0.1.8")) // used by bitRot() // power of 2 gives better uniform distribution in the last bits @@ -24,496 +24,154 @@ // // BIT COUNT TEST // -uint8_t bitCountReference(uint32_t value) -{ - uint32_t v = value; - uint8_t count = 0; - while (v > 0) - { - if (v & 1) count++; - v >>= 1; - } - return count; -}; +uint8_t bitCountReference(uint32_t value); +uint8_t bitCountKR(uint32_t value); -uint8_t bitCountKR(uint32_t value) -{ - // Kerningham & Ritchie - uint32_t v = value; - uint8_t count = 0; - while (v) - { - count++; - v &= (v - 1); - } - return count; -}; +uint8_t bitCountArray(uint32_t value); +uint8_t bitCountF1(uint32_t value); -uint8_t bitCountArray(uint32_t value) -{ - uint8_t ar[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - uint32_t v = value; - uint8_t count = 0; - while (v) - { - count += ar[v & 0x0F]; - v >>= 4; - } - return count; -}; - - -uint8_t bitCountF1(uint32_t value) -{ - // parallel adding in a register SWAG algorithm - uint32_t v = value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - v = (v + (v >> 4)) & 0x0F0F0F0F; - v = v + (v >> 8); - v = v + (v >> 16); - return v & 0x0000003F; -}; - - -uint8_t bitCountF2(uint32_t value) -{ - // parallel adding in a register SWAG algorithm - uint32_t v = value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - v = ((v + (v >> 4)) & 0x0F0F0F0F); - return ( v * 0x01010101) >> 24; -}; +uint8_t bitCountF2(uint32_t value); //////////////////////////////////////////////// // // BIT COUNT // -uint8_t bitCount(uint8_t value) -{ - // parallel adding in a register SWAG algorithm - uint8_t v = value; - v = v - ((v >> 1) & 0x55); - v = (v & 0x33) + ((v >> 2) & 0x33); - v = (v + (v >> 4)) & 0x0F; - return v; -}; +uint8_t bitCount(uint8_t value); +uint8_t bitCount(uint16_t value); -uint8_t bitCount(uint16_t value) -{ - // parallel adding in a register SWAG algorithm - uint16_t v = value; - v = v - ((v >> 1) & 0x5555); - v = (v & 0x3333) + ((v >> 2) & 0x3333); - v = (v + (v >> 4)) & 0x0F0F; - v = (v + (v >> 8)) & 0x1F; - return v; -}; +uint8_t bitCount(uint32_t value); - -uint8_t bitCount(uint32_t value) -{ - // parallel adding in a register SWAG algorithm - uint32_t v = value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - v = (v + (v >> 4)) & 0x0F0F0F0F; - v = v + (v >> 8); - v = (v + (v >> 16)) & 0x3F; - return v; -}; - - -uint8_t bitCount(uint64_t value) -{ - // parallel adding in a register SWAG algorithm - uint64_t v = value; - v = v - ((v >> 1) & 0x5555555555555555); - v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); - v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0F; - v = v + (v >> 8); - v = v + (v >> 16); - v = (v + (v >> 32)) & 0x7F; - return v; -}; +uint8_t bitCount(uint64_t value); //////////////////////////////////////////////// // // BIT REVERSE // -uint8_t bitReverse(uint8_t value) -{ - uint8_t x = value; - x = (((x & 0xAA) >> 1) | ((x & 0x55) << 1)); - x = (((x & 0xCC) >> 2) | ((x & 0x33) << 2)); - x = (x >> 4) | (x << 4); - return x; -} +uint8_t bitReverse(uint8_t value); +uint16_t bitReverse(uint16_t value); -uint16_t bitReverse(uint16_t value) -{ - uint16_t x = value; - x = (((x & 0xAAAA) >> 1) | ((x & 0x5555) << 1)); - x = (((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2)); - x = (((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4)); - x = (x >> 8) | (x << 8); - return x; -} +uint32_t bitReverse(uint32_t value); - -uint32_t bitReverse(uint32_t value) -{ - uint32_t x = value; - x = (((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1)); - x = (((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2)); - x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4)); - x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); - x = (x >> 16) | (x << 16); - return x; -} - - -uint64_t bitReverse(uint64_t value) -{ - uint64_t x = value; - x = (((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1)); - x = (((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2)); - x = (((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4)); - x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); - x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); - x = (x >> 32) | (x << 32); - return x; -} +uint64_t bitReverse(uint64_t value); //////////////////////////////////////////////// // // NYBBLE REVERSE // -uint8_t nybbleReverse(uint8_t value) -{ - uint8_t x = value; - x = (x >> 4) | (x << 4); - return x; -} +uint8_t nybbleReverse(uint8_t value); +uint16_t nybbleReverse(uint16_t value); -uint16_t nybbleReverse(uint16_t value) -{ - uint16_t x = value; - x = (((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4)); - x = (x >> 8) | (x << 8); - return x; -} +uint32_t nybbleReverse(uint32_t value); - -uint32_t nybbleReverse(uint32_t value) -{ - uint32_t x = value; - x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4)); - x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); - x = (x >> 16) | (x << 16); - return x; -} - - -uint64_t nybbleReverse(uint64_t value) -{ - uint64_t x = value; - x = (((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4)); - x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); - x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); - x = (x >> 32) | (x << 32); - return x; -} +uint64_t nybbleReverse(uint64_t value); //////////////////////////////////////////////// // // BYTE REVERSE // -uint16_t byteReverse(uint16_t value) -{ - uint16_t x = value; - x = (x >> 8) | (x << 8); - return x; -} +uint16_t byteReverse(uint16_t value); +uint32_t byteReverse(uint32_t value); -uint32_t byteReverse(uint32_t value) -{ - uint32_t x = value; - x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8)); - x = (x >> 16) | (x << 16); - return x; -} - - -uint64_t byteReverse(uint64_t value) -{ - uint64_t x = value; - x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8)); - x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); - x = (x >> 32) | (x << 32); - return x; -} +uint64_t byteReverse(uint64_t value); //////////////////////////////////////////////// // // WORD REVERSE // -uint32_t wordReverse(uint32_t value) -{ - uint32_t x = value; - x = (x >> 16) | (x << 16); - return x; -} +uint32_t wordReverse(uint32_t value); - -uint64_t wordReverse(uint64_t value) -{ - uint64_t x = value; - x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16)); - x = (x >> 32) | (x << 32); - return x; -} +uint64_t wordReverse(uint64_t value); //////////////////////////////////////////////// // // SWAP HI LO // -uint8_t swap(uint8_t value) -{ - return (value << 4) | (value >> 4); -} +uint8_t swap(uint8_t value); +uint16_t swap(uint16_t value); -uint16_t swap(uint16_t value) -{ - return (value << 8) | (value >> 8); -} +uint32_t swap(uint32_t value); - -uint32_t swap(uint32_t value) -{ - return (value << 16) | (value >> 16); -} - - -uint64_t swap(uint64_t value) -{ - return (value << 32) | (value >> 32); -} +uint64_t swap(uint64_t value); //////////////////////////////////////////////// // // BIT ROTATE LEFT // -uint8_t bitRotateLeft(uint8_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 7) return value; - return (value << pos) | (value >> (8 - pos)); -} +uint8_t bitRotateLeft(uint8_t value, uint8_t pos); +uint16_t bitRotateLeft(uint16_t value, uint8_t pos); -uint16_t bitRotateLeft(uint16_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 15) return value; - return (value << pos) | (value >> (16 - pos)); -} +uint32_t bitRotateLeft(uint32_t value, uint8_t pos); - -uint32_t bitRotateLeft(uint32_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 31) return value; - return (value << pos) | (value >> (32 - pos)); -} - - -uint64_t bitRotateLeft(uint64_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 63) return value; - return (value << pos) | (value >> (64 - pos)); -} +uint64_t bitRotateLeft(uint64_t value, uint8_t pos); //////////////////////////////////////////////// // // BIT ROTATE RIGHT // -uint8_t bitRotateRight(uint8_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 7) return value; - return (value << (8 - pos)) | (value >> pos); -} +uint8_t bitRotateRight(uint8_t value, uint8_t pos); +uint16_t bitRotateRight(uint16_t value, uint8_t pos); -uint16_t bitRotateRight(uint16_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 15) return value; - return (value << (16 - pos)) | (value >> pos); -} +uint32_t bitRotateRight(uint32_t value, uint8_t pos); - -uint32_t bitRotateRight(uint32_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 31) return value; - return (value << (32 - pos)) | (value >> pos); -} - - -uint64_t bitRotateRight(uint64_t value, uint8_t pos) -{ - if (pos == 0) return value; - if (pos > 63) return value; - return (value << (64 - pos)) | (value >> pos); -} +uint64_t bitRotateRight(uint64_t value, uint8_t pos); //////////////////////////////////////////////////// // // BIT FLIP // -uint8_t bitFlip(uint8_t value, uint8_t pos) -{ - if (pos > 7) return value; - return value ^ (1 << pos); -} +uint8_t bitFlip(uint8_t value, uint8_t pos); +uint16_t bitFlip(uint16_t value, uint8_t pos); -uint16_t bitFlip(uint16_t value, uint8_t pos) -{ - if (pos > 15) return value; - return value ^ (1 << pos); -} +uint32_t bitFlip(uint32_t value, uint8_t pos); - -uint32_t bitFlip(uint32_t value, uint8_t pos) -{ - if (pos > 31) return value; - return value ^ (1UL << pos); -} - - -uint64_t bitFlip(uint64_t value, uint8_t pos) -{ - if (pos > 63) return value; - return value ^ (1ULL << pos); -} +uint64_t bitFlip(uint64_t value, uint8_t pos); //////////////////////////////////////////////////// // // BIT ROT // -uint8_t bitRotRef(uint8_t value, float chance = 0.5) -{ - if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; - return value ^ (1 << random(8)); -} +uint8_t bitRotRef(uint8_t value, float chance = 0.5); + +uint16_t bitRotRef(uint16_t value, float chance = 0.5); + +uint32_t bitRotRef(uint32_t value, float chance = 0.5); + +uint64_t bitRotRef(uint64_t value, float chance = 0.5); -uint16_t bitRotRef(uint16_t value, float chance = 0.5) -{ - if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; - return value ^ (1UL << random(16)); -} +uint8_t bitRot(uint8_t value, float chance = 0.5, uint16_t times = 1); +uint16_t bitRot(uint16_t value, float chance = 0.5, uint16_t times = 1); -uint32_t bitRotRef(uint32_t value, float chance = 0.5) -{ - if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; - return value ^ (1UL << random(32)); -} - - -uint64_t bitRotRef(uint64_t value, float chance = 0.5) -{ - if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value; - return value ^ (1ULL << random(64)); -} - - -uint8_t bitRot(uint8_t value, float chance = 0.5, uint16_t times = 1) -{ - while(times--) - { - uint32_t r = random(BH_BIG_NR); - if ( r < chance * BH_BIG_NR) - { - value ^= (1 << (r & 7)); - } - } - return value; -} - - -uint16_t bitRot(uint16_t value, float chance = 0.5, uint16_t times = 1) -{ - while(times--) - { - uint32_t r = random(BH_BIG_NR); - if ( r < chance * BH_BIG_NR) - { - value ^= (1 << (r & 15)); - } - } - return value; -} - - -uint32_t bitRot(uint32_t value, float chance = 0.5, uint16_t times = 1) -{ - while(times--) - { - uint32_t r = random(BH_BIG_NR); - if ( r < chance * BH_BIG_NR) - { - value ^= (1 << (r & 31)); - } - } - return value; -} - - -uint64_t bitRot(uint64_t value, float chance = 0.5, uint16_t times = 1) -{ - while(times--) - { - uint32_t r = random(BH_BIG_NR); - if ( r < chance * BH_BIG_NR) - { - value ^= (1 << (r & 63)); - } - } - return value; -} - +uint32_t bitRot(uint32_t value, float chance = 0.5, uint16_t times = 1); +uint64_t bitRot(uint64_t value, float chance = 0.5, uint16_t times = 1); //////////////////////////////////////////////////// // // BIT-SET64 -CLEAR64 -TOGGLE64 -READ64 -WRITE64 // - // MACROS // only 64 bit data types are handled 64 bit. #define mbitSet64(value, bit) ((value) |= (sizeof(value)<5?1UL:1ULL) <<(bit)) @@ -525,98 +183,16 @@ uint64_t bitRot(uint64_t value, float chance = 0.5, uint16_t times = 1) // FUNCTIONS -#if defined(__AVR__) -// optimized for performance -void bitSet64(uint64_t & x, uint8_t n) -{ - if (n > 47) x |= (0x1000000000000 << (n - 48)); - else if (n > 31) x |= (0x100000000 << (n - 32)); - else if (n > 23) x |= (0x1000000 << (n - 24)); - else if (n > 15) x |= (0x10000 << (n - 16)); - else x |= (0x1 << n); -} +void bitSet64(uint64_t & x, uint8_t n); +void bitClear64(uint64_t & x, uint8_t n); -void bitClear64(uint64_t & x, uint8_t n) -{ - if (n > 47) x &= ~(0x1000000000000 << (n - 48)); - else if (n > 31) x &= ~(0x100000000 << (n - 32)); - else if (n > 23) x &= ~(0x1000000 << (n - 24)); - else if (n > 15) x &= ~(0x10000 << (n - 16)); - else x &= ~(0x1 << n); -} +void bitToggle64(uint64_t & x, uint8_t n); +uint8_t bitRead64(uint64_t & x, uint8_t bit); -void bitToggle64(uint64_t & x, uint8_t n) -{ - if (n > 47) x ^= (0x1000000000000 << (n - 48)); - else if (n > 31) x ^= (0x100000000 << (n - 32)); - else if (n > 23) x ^= (0x1000000 << (n - 24)); - else if (n > 15) x ^= (0x10000 << (n - 16)); - else x ^= (0x1 << n); -} - - -#elif defined(ESP32) -// optimized for performance - -void bitSet64(uint64_t & x, uint8_t n) -{ - if (n > 31) x |= (0x100000000 << (n - 32)); - else x |= (0x1 << n); -} - - -void bitClear64(uint64_t & x, uint8_t n) -{ - if (n > 31) x &= ~(0x100000000 << (n - 32)); - else x &= ~(0x1 << n); -} - - -void bitToggle64(uint64_t & x, uint8_t n) -{ - if (n > 31) x ^= (0x100000000 << (n - 32)); - else x ^= (0x1 << n); -} - - -#else -// slower reference implementation - -void bitSet64(uint64_t & x, uint8_t bit) -{ - x |= (1ULL << bit); -} - - -void bitClear64(uint64_t & x, uint8_t bit) -{ - x &= ~(1ULL << bit); -} - - -void bitToggle64(uint64_t & x, uint8_t bit) -{ - x ^= (1ULL << bit); -} - - -#endif - - -uint8_t bitRead64(uint64_t & x, uint8_t bit) -{ - return ((x & (1ULL << bit)) > 0); -} - - -void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value) -{ - if (value) bitSet64(x, bit); - else bitClear64(x, bit); -} +void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value); //////////////////////////////////////////////////// @@ -625,61 +201,16 @@ void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value) // // reference -uint8_t bitsNeededRef(uint64_t x) -{ - uint8_t n = 0; - while (x) - { - x >>= 1; - n++; - } - return n; -} - +uint8_t bitsNeededRef(uint64_t x); // workers -uint8_t bitsNeeded(uint8_t x) -{ - uint8_t n = 0; - while (x) - { - x >>= 1; - n++; - } - return n; -} +uint8_t bitsNeeded(uint8_t x); +uint8_t bitsNeeded(uint16_t x); -uint8_t bitsNeeded(uint16_t x) -{ - uint8_t y = x >> 8; - if (y != 0) return bitsNeeded(y) + 8; - return bitsNeeded((uint8_t)x); -} - - -uint8_t bitsNeeded(uint32_t x) -{ - uint16_t y = x >> 16; - if (y != 0) return bitsNeeded(y) + 16; - return bitsNeeded((uint16_t)x); -} - - -uint8_t bitsNeeded(uint64_t x) -{ - uint32_t y = x >> 32; - if (x >> 32) return bitsNeeded(y) + 32; - return bitsNeeded((uint32_t)x); -} - - -//////////////////////////////////////////////////// -// -// NEXT -// - +uint8_t bitsNeeded(uint32_t x); +uint8_t bitsNeeded(uint64_t x); // -- END OF FILE -- diff --git a/libraries/bitHelpers/library.json b/libraries/bitHelpers/library.json index 32cba830..bb239862 100644 --- a/libraries/bitHelpers/library.json +++ b/libraries/bitHelpers/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/bitHelpers.git" }, - "version": "0.1.7", + "version": "0.1.8", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/libraries/bitHelpers/library.properties b/libraries/bitHelpers/library.properties index b5aee054..137b3703 100644 --- a/libraries/bitHelpers/library.properties +++ b/libraries/bitHelpers/library.properties @@ -1,5 +1,5 @@ name=bitHelpers -version=0.1.7 +version=0.1.8 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library with functions on bit level