mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.3 bitHelpers
This commit is contained in:
parent
15924814e5
commit
dcdc4b9c97
@ -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
|
||||
|
@ -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
|
||||
|
@ -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": "*"
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user