mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.1.5 bitHelpers
This commit is contained in:
parent
9e35d9b6bc
commit
9648c886cb
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015-2021 Rob Tillaart
|
||||
Copyright (c) 2015-2022 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
# bitHelpers
|
||||
|
||||
Arduino library with functions on bit level
|
||||
Arduino library with functions on bit level.
|
||||
|
||||
|
||||
## Description
|
||||
@ -19,9 +19,9 @@ For most functions a 8 - 64 bit optimized version exist.
|
||||
|
||||
The library is tested on ESP32 and Arduino UNO but not for all possible values.
|
||||
other platforms are expected to work without modification.
|
||||
If they don't please let me know.
|
||||
If they don't please file an issue on GitHub.
|
||||
|
||||
New bit functions can be added or investigated, please post an issue.
|
||||
New bit functions can be added or investigated, please file an issue on GitHub.
|
||||
|
||||
|
||||
## Interface
|
||||
@ -30,34 +30,41 @@ New bit functions can be added or investigated, please post an issue.
|
||||
### 0.1.0
|
||||
|
||||
BitCount, several implementations to compare performance.
|
||||
- **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
|
||||
|
||||
- **uint8_t bitCountReference(uint32_t value)** returns number of bits set in a value.
|
||||
- **uint8_t bitCountKR(uint32_t value)** Kerningham Ritchie bitCount.
|
||||
- **uint8_t bitCountArray(uint32_t value)** count per nybble with lookup table.
|
||||
- **uint8_t bitCountF1(uint32_t value)** SWAG algorithm variant.
|
||||
- **uint8_t bitCountF2(uint32_t value)** SWAG algorithm variant.
|
||||
|
||||
BitCount - fastest version, SWAG algorithm
|
||||
- **uint8_t bitCount(uint8_t val)** available for 16, 32 and 64 bit.
|
||||
|
||||
- **uint8_t bitCount(uint8_t value)** available for 16, 32 and 64 bit.
|
||||
|
||||
Reverse: uint8_t .. 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
|
||||
- **T swap(T val)** 0x12345678 ==> 0x56781234
|
||||
- **T bitReverse(T value)** reverses bits in a uint8_t .. uint64_t.
|
||||
- **T nybbleReverse(T value)** reverses nibbles (4 bit) in a uint8_t .. uint64_t.
|
||||
- **T byteReverse(T value)** reverses bytes (8 bit) in a uint16_t .. uint64_t.
|
||||
- **T wordReverse(T value)** reverses words (16 bit) in uint32_t and uint64_t.
|
||||
|
||||
Swap upper and lower half: uint8_t .. uint64_t.
|
||||
|
||||
- **T swap(T value)** 0x12345678 ==> 0x56781234.
|
||||
|
||||
Rotate Left / Right: uint8_t .. uint64_t
|
||||
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
|
||||
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
|
||||
|
||||
- **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.
|
||||
@ -67,18 +74,21 @@ chance = float 0.0 .. 1.0 that one random bit is toggled.
|
||||
### 0.1.1 added
|
||||
|
||||
How many bits are needed to store / transmit a number?
|
||||
- **bitsNeededReference(n)** reference implementation for uit to uint64_t.
|
||||
|
||||
- **bitsNeededReference(n)** reference implementation for uint8_t to uint64_t.
|
||||
- **bitsNeeded(n)** A 'recursive strategy' for uint8_t .. uint64_t provides a fast answer.
|
||||
|
||||
The following functions are made as the normal **bitset()** etc do not work for 64 bit.
|
||||
The following functions are made as the normal **bitset()** etcetera do not work for 64 bit.
|
||||
These functions are optimized for speed for **AVR**, **ESP32** and **ESP8266**.
|
||||
- **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
|
||||
|
||||
- **void bitSet64(uint64_t & x, uint8_t bit)** set bit of uint64_t
|
||||
- **void bitClear64(uint64_t & x, uint8_t bit)** clear bit of uint64_t
|
||||
- **void bitToggle64(uint64_t & x, uint8_t bit)** toggle bit of uint64_t
|
||||
- **void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value)** set bit of uint64_t to 0 or 1
|
||||
- **void bitRead64(uint64_t & 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
|
||||
- **mbitClear64(x, bit)** clear bit of uint64_t
|
||||
- **mbitToggle64(x, bit)** toggle bit of uint64_t
|
||||
@ -103,10 +113,15 @@ Added Arduino-CI and unit tests
|
||||
- update readme.md with badges
|
||||
|
||||
|
||||
### 0.1.5
|
||||
|
||||
- update library.json, minor edits
|
||||
|
||||
|
||||
## BitReverse n bit number
|
||||
|
||||
Trick to reverse a number of n bits ( 0 < n < 32 ).
|
||||
Could also be done similar with 64 bit and or byte / nybble reverse.
|
||||
Could also be done similar with 64 bit and or byte / nibble reverse.
|
||||
|
||||
not as fast as a dedicated version.
|
||||
```cpp
|
||||
@ -121,6 +136,8 @@ Could be added in next release...
|
||||
|
||||
## Future
|
||||
|
||||
- improve documentation
|
||||
- improve readability of code (val => value and pos => position)
|
||||
- besides **bitRot()** one can also have timing issues when clocking in bits.
|
||||
A function could be created to mimic such timing error, by shifting bits from a
|
||||
specific position. e.g.
|
||||
@ -135,6 +152,7 @@ specific position. e.g.
|
||||
- add **byteInverse(uint32_t x)** (a,b,c,d) => (255-a, 255-b, 255-c, 255-d)
|
||||
- performance tests
|
||||
|
||||
|
||||
## Operations
|
||||
|
||||
See examples.
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: bitHelpers.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.4
|
||||
// VERSION: 0.1.5
|
||||
// DATE: 2015-11-07
|
||||
// PURPOSE: Arduino library with functions on bit level
|
||||
// URL: https://github.com/RobTillaart/bitHelpers
|
||||
@ -14,11 +14,12 @@
|
||||
// 0.1.2 2020-12-14 add Arduino-CI + unit tests
|
||||
// 0.1.3 2021-08-09 update readme.md + unit tests
|
||||
// 0.1.4 2021-10-19 update Arduino-CI + badges
|
||||
// 0.1.5 2021-12-14 update library.json, license, minor edits
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define BITHELPER_LIB_VERSION (F("0.1.4"))
|
||||
#define BITHELPER_LIB_VERSION (F("0.1.5"))
|
||||
#define BH_BIG_NR 1000000000
|
||||
|
||||
|
||||
@ -149,9 +150,9 @@ uint8_t bitCount(uint64_t value)
|
||||
//
|
||||
// BIT REVERSE
|
||||
//
|
||||
uint8_t bitReverse(uint8_t val)
|
||||
uint8_t bitReverse(uint8_t value)
|
||||
{
|
||||
uint8_t x = val;
|
||||
uint8_t x = value;
|
||||
x = (((x & 0xAA) >> 1) | ((x & 0x55) << 1));
|
||||
x = (((x & 0xCC) >> 2) | ((x & 0x33) << 2));
|
||||
x = (x >> 4) | (x << 4);
|
||||
@ -159,9 +160,9 @@ uint8_t bitReverse(uint8_t val)
|
||||
}
|
||||
|
||||
|
||||
uint16_t bitReverse(uint16_t val)
|
||||
uint16_t bitReverse(uint16_t value)
|
||||
{
|
||||
uint16_t x = val;
|
||||
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));
|
||||
@ -170,9 +171,9 @@ uint16_t bitReverse(uint16_t val)
|
||||
}
|
||||
|
||||
|
||||
uint32_t bitReverse(uint32_t val)
|
||||
uint32_t bitReverse(uint32_t value)
|
||||
{
|
||||
uint32_t x = val;
|
||||
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));
|
||||
@ -182,9 +183,9 @@ uint32_t bitReverse(uint32_t val)
|
||||
}
|
||||
|
||||
|
||||
uint64_t bitReverse(uint64_t val)
|
||||
uint64_t bitReverse(uint64_t value)
|
||||
{
|
||||
uint64_t x = val;
|
||||
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));
|
||||
@ -199,26 +200,26 @@ uint64_t bitReverse(uint64_t val)
|
||||
//
|
||||
// NYBBLE REVERSE
|
||||
//
|
||||
uint8_t nybbleReverse(uint8_t val)
|
||||
uint8_t nybbleReverse(uint8_t value)
|
||||
{
|
||||
uint8_t x = val;
|
||||
uint8_t x = value;
|
||||
x = (x >> 4) | (x << 4);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint16_t nybbleReverse(uint16_t val)
|
||||
uint16_t nybbleReverse(uint16_t value)
|
||||
{
|
||||
uint16_t x = val;
|
||||
uint16_t x = value;
|
||||
x = (((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4));
|
||||
x = (x >> 8) | (x << 8);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint32_t nybbleReverse(uint32_t val)
|
||||
uint32_t nybbleReverse(uint32_t value)
|
||||
{
|
||||
uint32_t x = val;
|
||||
uint32_t x = value;
|
||||
x = (((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4));
|
||||
x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8));
|
||||
x = (x >> 16) | (x << 16);
|
||||
@ -226,9 +227,9 @@ uint32_t nybbleReverse(uint32_t val)
|
||||
}
|
||||
|
||||
|
||||
uint64_t nybbleReverse(uint64_t val)
|
||||
uint64_t nybbleReverse(uint64_t value)
|
||||
{
|
||||
uint64_t x = val;
|
||||
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));
|
||||
@ -241,26 +242,26 @@ uint64_t nybbleReverse(uint64_t val)
|
||||
//
|
||||
// BYTE REVERSE
|
||||
//
|
||||
uint16_t byteReverse(uint16_t val)
|
||||
uint16_t byteReverse(uint16_t value)
|
||||
{
|
||||
uint16_t x = val;
|
||||
uint16_t x = value;
|
||||
x = (x >> 8) | (x << 8);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint32_t byteReverse(uint32_t val)
|
||||
uint32_t byteReverse(uint32_t value)
|
||||
{
|
||||
uint32_t x = val;
|
||||
uint32_t x = value;
|
||||
x = (((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8));
|
||||
x = (x >> 16) | (x << 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint64_t byteReverse(uint64_t val)
|
||||
uint64_t byteReverse(uint64_t value)
|
||||
{
|
||||
uint64_t x = val;
|
||||
uint64_t x = value;
|
||||
x = (((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8));
|
||||
x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16));
|
||||
x = (x >> 32) | (x << 32);
|
||||
@ -272,17 +273,17 @@ uint64_t byteReverse(uint64_t val)
|
||||
//
|
||||
// WORD REVERSE
|
||||
//
|
||||
uint32_t wordReverse(uint32_t val)
|
||||
uint32_t wordReverse(uint32_t value)
|
||||
{
|
||||
uint32_t x = val;
|
||||
uint32_t x = value;
|
||||
x = (x >> 16) | (x << 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint64_t wordReverse(uint64_t val)
|
||||
uint64_t wordReverse(uint64_t value)
|
||||
{
|
||||
uint64_t x = val;
|
||||
uint64_t x = value;
|
||||
x = (((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16));
|
||||
x = (x >> 32) | (x << 32);
|
||||
return x;
|
||||
@ -293,27 +294,27 @@ uint64_t wordReverse(uint64_t val)
|
||||
//
|
||||
// SWAP HI LO
|
||||
//
|
||||
uint8_t swap(uint8_t val)
|
||||
uint8_t swap(uint8_t value)
|
||||
{
|
||||
return (val << 4) | (val >> 4);
|
||||
return (value << 4) | (value >> 4);
|
||||
}
|
||||
|
||||
|
||||
uint16_t swap(uint16_t val)
|
||||
uint16_t swap(uint16_t value)
|
||||
{
|
||||
return (val << 8) | (val >> 8);
|
||||
return (value << 8) | (value >> 8);
|
||||
}
|
||||
|
||||
|
||||
uint32_t swap(uint32_t val)
|
||||
uint32_t swap(uint32_t value)
|
||||
{
|
||||
return (val << 16) | (val >> 16);
|
||||
return (value << 16) | (value >> 16);
|
||||
}
|
||||
|
||||
|
||||
uint64_t swap(uint64_t val)
|
||||
uint64_t swap(uint64_t value)
|
||||
{
|
||||
return (val << 32) | (val >> 32);
|
||||
return (value << 32) | (value >> 32);
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,109 @@
|
||||
//
|
||||
// FILE: bitHelpers_test.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2021-08-04
|
||||
// URL: https://github.com/RobTillaart/bitHelpers
|
||||
|
||||
|
||||
#include "bitHelpers.h"
|
||||
|
||||
uint32_t start, stop;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.println();
|
||||
|
||||
test_32_bit();
|
||||
test_24_bit();
|
||||
|
||||
Serial.println("\nDone...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
void test_24_bit()
|
||||
{
|
||||
Serial.println();
|
||||
Serial.println(__FUNCTION__);
|
||||
|
||||
uint32_t x = 0x9B3FAA;
|
||||
uint32_t y = byteReverse(x);
|
||||
uint32_t z = byteReverse(x) >> 8;
|
||||
Serial.println(x, HEX);
|
||||
Serial.println(y, HEX);
|
||||
Serial.println(z, HEX);
|
||||
Serial.println();
|
||||
|
||||
printHex32(y);
|
||||
printHex32(z);
|
||||
Serial.println();
|
||||
|
||||
x = 0x5D9504;
|
||||
y = byteReverse(x);
|
||||
z = byteReverse(x) >> 8;
|
||||
Serial.println(x, HEX);
|
||||
Serial.println(y, HEX);
|
||||
Serial.println(z, HEX);
|
||||
Serial.println();
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void test_32_bit()
|
||||
{
|
||||
Serial.println();
|
||||
Serial.println(__FUNCTION__);
|
||||
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void printHex16(uint16_t x)
|
||||
{
|
||||
if (x < 0x1000) Serial.print('0');
|
||||
if (x < 0x100) Serial.print('0');
|
||||
if (x < 0x10) Serial.print('0');
|
||||
Serial.println(x, HEX);
|
||||
}
|
||||
|
||||
|
||||
void printHex24(uint32_t x)
|
||||
{
|
||||
if (x < 0x100000) Serial.print('0');
|
||||
if (x < 0x10000) Serial.print('0');
|
||||
if (x < 0x1000) Serial.print('0');
|
||||
if (x < 0x100) Serial.print('0');
|
||||
if (x < 0x10) Serial.print('0');
|
||||
Serial.println(x, HEX);
|
||||
}
|
||||
|
||||
|
||||
void printHex32(uint32_t x)
|
||||
{
|
||||
if (x < 0x10000000) Serial.print('0');
|
||||
if (x < 0x1000000) Serial.print('0');
|
||||
if (x < 0x100000) Serial.print('0');
|
||||
if (x < 0x10000) Serial.print('0');
|
||||
if (x < 0x1000) Serial.print('0');
|
||||
if (x < 0x100) Serial.print('0');
|
||||
if (x < 0x10) Serial.print('0');
|
||||
Serial.println(x, HEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -15,8 +15,9 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/bitHelpers.git"
|
||||
},
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*"
|
||||
"platforms": "*",
|
||||
"headers": "bitHelpers.h"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=bitHelpers
|
||||
version=0.1.4
|
||||
version=0.1.5
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library with functions on bit level
|
||||
|
Loading…
Reference in New Issue
Block a user