0.1.3 bitHelpers

This commit is contained in:
rob tillaart 2021-08-09 21:39:09 +02:00
parent 15924814e5
commit dcdc4b9c97
5 changed files with 74 additions and 41 deletions

View File

@ -10,7 +10,7 @@ Arduino library with functions on bit level
## Description
This library contains functions to manipulate bits and bitpatterns in an
This library contains functions to manipulate bits and bit patterns in an
efficient way.
For most functions a 8 - 64 bit optimized version exist.
@ -25,34 +25,36 @@ New bit functions can be added or investigated, please post an issue.
### 0.1.0
BitCount, several implementations to compare performance.
- **bitCountReference(uint32_t val)** returns nr of bits set in a value.
- **bitCountKR(uint32_t val)** Kerningham bitCount
- **bitCountArray(uint32_t val)** count per nybble with lookup table
- **bitCountF1(uint32_t val)** SWAG algorithm variant
- **bitCountF2(uint32_t val)** SWAG algorithm variant
- **uint8_t bitCountReference(uint32_t val)** returns nr of bits set in a value.
- **uint8_t bitCountKR(uint32_t val)** Kerningham Ritchie bitCount
- **uint8_t bitCountArray(uint32_t val)** count per nybble with lookup table
- **uint8_t bitCountF1(uint32_t val)** SWAG algorithm variant
- **uint8_t bitCountF2(uint32_t val)** SWAG algorithm variant
BitCount - fastest version: uint8_t .. uint64_t
- **bitCount(val)**
BitCount - fastest version, SWAG algorithm
- **uint8_t bitCount(uint8_t val)** available for 16, 32 and 64 bit.
Reverse: uint8_t .. uint64_t
- **bitReverse()** reverses bits in a uint8_t .. uint64_t
- **nybbleReverse()** reverses nybbles (4 bit) in a uint8_t .. uint64_t
- **byteReverse()** reverses bytes (8 bit) in a uint16_t .. uint64_t
- **wordReverse()** reverses words (16 bit) in uint32_t and uint64_t
- **T bitReverse(T val)** reverses bits in a uint8_t .. uint64_t
- **T nybbleReverse(T val)** reverses nibbles (4 bit) in a uint8_t .. uint64_t
- **T byteReverse(T val)** reverses bytes (8 bit) in a uint16_t .. uint64_t
- **T wordReverse(T val)** reverses words (16 bit) in uint32_t and uint64_t
Swap upper and lower half: uint8_t .. uint64_t
- **swap()** 0x12345678 ==> 0x56781234
- **T swap(T val)** 0x12345678 ==> 0x56781234
Rotate Left / Right: uint8_t .. uint64_t
- **bitRotateLeft(value, pos)**
- **bitRotateRight(value, pos)**
if pos larger than # bits original value is returned.
- **T bitRotateLeft(T value, uint8_t pos)**
- **T bitRotateRight(T value, uint8_t pos)**
BitFlip: uint8_t .. uint64_t a.k.a toggle
- **bitFlip(value, pos)** flips a single bit at pos
if pos larger than # bits original value is returned.
- **T bitFlip(T value, uint8_t pos)** flips a single bit at pos
BitRot: uint8_t .. uint64_t
- **bitRot(value, chance)** random damage to a single bit of a value, chance = float 0.0 .. 1.0
that one random bit is toggled.
- **T bitRot(T value, float chance = 0.5)** random damage to a single bit of a value,
chance = float 0.0 .. 1.0 that one random bit is toggled.
**bitRot()** is a function that can be used to mimic single bit errors in communication protocols.
*Note: a chance of 50% for 2 uint8_t is not equal to 50% chance for 1 uint16_t.*
@ -64,11 +66,11 @@ How many bits are needed to store / transmit a number?
The following functions are made as the normal **bitset()** etc do not work for 64 bit.
These functions are optimized for speed for **AVR**, **ESP32** and **ESP8266**.
- **bitSet64(x, bit)** set bit of uint64_t
- **bitClear64(x, bit)** clear bit of uint64_t
- **bitToggle64(x, bit)** toggle bit of uint64_t
- **bitWrite64(x, bit, value)** set bit of uint64_t to 0 or 1
- **bitRead64(x, bit)** reads bit from uint64_t
- **void bitSet64(uint64 & x, uint8_t bit)** set bit of uint64_t
- **void bitClear64(uint64 & x, uint8_t bit)** clear bit of uint64_t
- **void bitToggle64(uint64 & x, uint8_t bit)** toggle bit of uint64_t
- **void bitWrite64(uint64 & x, uint8_t bit, uint8_t value)** set bit of uint64_t to 0 or 1
- **void bitRead64(uint64 & x, uint8_t bit)** reads bit from uint64_t
Also added are macro versions of these five functions.
- **mbitSet64(x, bit)** set bit of uint64_t
@ -79,7 +81,13 @@ Also added are macro versions of these five functions.
### 0.1.2 added
Added arduino-ci and unit tests
Added Arduino-CI and unit tests
### 0.1.3 added
- update readme.md
- update unit tests
## Future

View File

@ -2,20 +2,24 @@
//
// FILE: bitHelpers.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2015-11-07
// PURPOSE: Arduino library with functions on bit level
// URL: https://github.com/RobTillaart/bitHelpers
//
// 0.0.1 2015-11-07 initial version
// 0.1.0 2020-07-29 intial release
// 0.1.0 2020-07-29 initial release
// 0.1.1 2020-08-10 added BitsNeeded, bitSet64 family
// 0.1.2 2020-12-14 add Adruino-ci + unit tests
// 0.1.2 2020-12-14 add Arduino-CI + unit tests
// 0.1.3 2021-08-09 update readme.md + unit tests
#include "Arduino.h"
#define BH_BIG_NR 1000000000
////////////////////////////////////////////////
//
// BIT COUNT TEST
@ -130,6 +134,7 @@ uint8_t bitCount(uint64_t value)
return v & 0x7F;
};
////////////////////////////////////////////////
//
// BIT REVERSE
@ -176,6 +181,7 @@ uint64_t bitReverse(uint64_t val)
return x;
}
////////////////////////////////////////////////
//
// NYBBLE REVERSE
@ -242,6 +248,7 @@ uint64_t byteReverse(uint64_t val)
return x;
}
////////////////////////////////////////////////
//
// WORD REVERSE
@ -261,6 +268,7 @@ uint64_t wordReverse(uint64_t val)
return x;
}
////////////////////////////////////////////////
//
// SWAP HI LO
@ -285,11 +293,12 @@ uint64_t swap(uint64_t val)
return (val << 32) | (val >> 32);
}
////////////////////////////////////////////////
//
// BIT ROTATE LEFT
//
uint8_t bitRotateLeft(uint8_t value, uint8_t pos)
uint8_t bitRotateLeft(uint8_t value, uint8_t pos)
{
if (pos > 7) return value;
return (value << pos) | (value >> (8 - pos));
@ -313,6 +322,7 @@ uint64_t bitRotateLeft(uint64_t value, uint8_t pos)
return (value << pos) | (value >> (64 - pos));
}
////////////////////////////////////////////////
//
// BIT ROTATE RIGHT
@ -341,62 +351,65 @@ uint64_t bitRotateRight(uint64_t value, uint8_t pos)
return (value << (64 - pos)) | (value >> pos);
}
////////////////////////////////////////////////////
//
// BIT FLIP
//
uint8_t bitFlip(uint8_t value, uint8_t pos)
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)
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)
uint64_t bitFlip(uint64_t value, uint8_t pos)
{
if (pos > 63) return value;
return value ^ (1ULL << pos);
}
////////////////////////////////////////////////////
//
// BIT ROT
//
uint8_t bitRot(uint8_t value, float chance = 0.5)
uint8_t bitRot(uint8_t value, float chance = 0.5)
{
if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value;
return value ^ (1 << random(8));
}
uint16_t bitRot(uint16_t value, float chance = 0.5)
uint16_t bitRot(uint16_t value, float chance = 0.5)
{
if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value;
return value ^ (1UL << random(16));
}
uint32_t bitRot(uint32_t value, float chance = 0.5)
uint32_t bitRot(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 bitRot(uint64_t value, float chance = 0.5)
uint64_t bitRot(uint64_t value, float chance = 0.5)
{
if (random(BH_BIG_NR) > chance * BH_BIG_NR) return value;
return value ^ (1ULL << random(64));
}
////////////////////////////////////////////////////
//
// BIT-SET64 -CLEAR64 -TOGGLE64 -READ64 -WRITE64
@ -411,6 +424,7 @@ uint64_t bitRot(uint64_t value, float chance = 0.5)
#define mbitRead64(value, bit) ( ((value) & ((sizeof(value)<5?1UL:1ULL) <<(bit))) ? 1 : 0)
#define mbitWrite64(value, bit, bitvalue) (bitvalue ? mbitSet64(value, bit) : mbitClear64(value, bit))
// FUNCTIONS
#if defined(__AVR__)
@ -480,6 +494,7 @@ void bitToggle64(uint64_t & x, uint8_t bit)
#endif
uint8_t bitRead64(uint64_t & x, uint8_t bit)
{
return x & (1ULL << bit);
@ -542,6 +557,7 @@ uint8_t bitsNeeded(uint64_t x)
return bitsNeeded((uint32_t)x);
}
////////////////////////////////////////////////////
//
// NEXT

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/bitHelpers.git"
},
"version": "0.1.2",
"version": "0.1.3",
"license": "MIT",
"frameworks": "*",
"platforms": "*"

View File

@ -1,5 +1,5 @@
name=bitHelpers
version=0.1.2
version=0.1.3
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library with functions on bit level

View File

@ -75,17 +75,26 @@ unittest(test_swap)
unittest(test_bitRotateLeft)
{
// TODO
assertEqual(0x8A, bitRotateLeft((uint8_t)0x51, 3));
assertEqual(0x4682, bitRotateLeft((uint16_t)0x3412, 13));
assertEqual(0x1A2B3C09, bitRotateLeft((uint32_t)0x56781234, 23));
assertEqual(0x456789ABCDEF0123, bitRotateLeft((uint64_t)0x89ABCDEF01234567, 48));
}
unittest(test_bitRotateRight)
{
// TODO
assertEqual(0x2A, bitRotateRight((uint8_t)0x51, 3));
assertEqual(0xA091, bitRotateRight((uint16_t)0x3412, 13));
assertEqual(0xF02468AC, bitRotateRight((uint32_t)0x56781234, 23));
assertEqual(0x0123456789ABCDEF, bitRotateRight((uint64_t)0x89ABCDEF01234567, 32));
}
unittest(test_bitFlip)
{
// TODO
assertEqual(0x59, bitFlip((uint8_t)0x51, 3));
assertEqual(0x1412, bitFlip((uint16_t)0x3412, 13));
assertEqual(0x56F81234, bitFlip((uint32_t)0x56781234, 23));
assertEqual(0x89ABC5EF01234567, bitFlip((uint64_t)0x89ABCDEF01234567, 43));
}
unittest(test_bitsNeeded)