0.2.5 randomHelpers

This commit is contained in:
rob tillaart 2022-11-23 13:56:17 +01:00
parent f121659f29
commit 6547c372d2
9 changed files with 128 additions and 71 deletions

View File

@ -1,11 +1,28 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
# selected only those that work
platforms:
- uno
- due
- zero
- leonardo
# - due
# - zero
# - leonardo
- m4
- esp32
- esp8266
- mega2560
# - mega2560
- rpipico

View File

@ -0,0 +1,40 @@
# Change Log randomHelpers
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.5] - 2022-11-23
- add changelog.md
- add RP2040 to build-CI
- fix license (started 2015)
## [0.2.4] - 2022-04-15
- fix #4 split .h in .h and .cpp
## [0.2.3] - 2021-12-27
- update library.json, license,
- minor edits
## [0.2.2] - 2021-11-15
- update Arduino-CI, readme.md badges
- add seedMarsaglia(uint32_t a, uint32_t b)
- fix randomDice()
## [0.2.1] - 2021-01-07
- Arduino-CI
## [0.2.0] - 2020-07-01
- rewrite
----
## [0.1.01] - 2015-08-18
- bug fixes and further optimizations
## [0.1.00] - 2015-08-17
- initial version.

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2022 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

View File

@ -26,18 +26,21 @@ However above 16 bits the overhead is larger than the gain.
So to improve in that range too one could use a faster random function like the one
from Marsaglia (included).
Note the gains differ per platform and are more explicit on the Arduino UNO platform
than on an ESP32.
Note the gains differ per platform and are more explicit on the (slow) Arduino UNO
platform than on a much faster ESP32.
This library relates to https://github.com/RobTillaart/Prandom
## Interface
functions implemented are
#### generators (sort of)
- **uint32_t Marsaglia()** fast PRNG.
- **bool seedMarsaglia(uint32_t a, uint32_t b)** seed the Marsaglia PRNG. a and b should not be 0. returns true on success.
#### getters (sort of)
- **bool getRandom1()** returns 0 or 1, false or true.
- **bool flipCoin()** A wrapper around getRandom1().
- **uint8_t getRandom4()** returns 0 .. 15.
- **uint8_t getRandom5()** returns 0 .. 31.
- **uint8_t getRandom6()** returns 0 .. 63.
@ -47,11 +50,18 @@ functions implemented are
- **uint32_t getRandom32()** returns 0 .. 2^32 - 1 (4 bytes) this is the core random generator
- **uint64_t getRandom64()** returns 0.. 2^64 - 1 (8 bytes).
- **uint32_t getRandomBits(n)** returns 0.. 2^n - 1 This works well for 1..16 bits but above 16 it is slower than the standard way.
#### Typical wrappers.
- **bool flipCoin()** A wrapper around getRandom1().
- **uint8_t throwDice()** returns 1..6.
The examples show how to use these and how their performance gain relative to
calling **random()** for every random number.
## Performance
to elaborate
## Operation
@ -60,8 +70,20 @@ See examples
## Future
#### must
- improve/update documentation
- add performance figures
#### should
- wrap all up in a class.
- add JKISS? other RNG's
#### could
- improve performance getRandomBits(n) for n = 17..31
- investigate new tricks :)
- wrap all up in a class.
- test if the functions are uniform.
- rename getRandom64() ==> get64() etc.
- when it is part of a class.
- add **getRandom2(), getRandom3(), getRandom12()**?

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/randomHelpers.git"
},
"version": "0.2.4",
"version": "0.2.5",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=randomHelpers
version=0.2.4
version=0.2.5
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library with helper function for faster random bits

View File

@ -2,32 +2,22 @@
//
// FILE: randomHelpers.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// VERSION: 0.2.5
// PURPOSE: Arduino library with helper function for faster random bits
// URL: https://github.com/RobTillaart/randomHelpers
//
// HISTORY:
// 0.2.4 2022-04-15 fix #4 split .h in .h and .cpp
// 0.2.3 2021-12-27 update library.json, license, minor edits
// 0.2.2 2021-11-15 update Arduino-CI, readme.md badges
// add seedMarsaglia(uint32_t a, uint32_t b)
// fix randomDice()
// 0.2.1 2021-01-07 Arduino-CI
// 0.2.0 2020-07-01 rewrite.
// 0.1.01 2015-08-18 bug fixes and further optimizations.
// 0.1.00 2015-08-17 initial version.
#include "randomHelpers.h"
// the idea is to have one buffer ( __randomBuffer) which holds 32 random bits.
// Every call fetches bits from that buffer and if it does not hold enough
// bits any more it fills the buffer first. This way the relative expensive
// calls to random() which produces a 32 bit number are minimized in an
// efficient way.
// the idea is to have one buffer ( __randomBuffer) which holds 32 random bits.
// Every call fetches bits from that buffer and if it does not hold enough
// bits any more it fills the buffer first. This way the relative expensive
// calls to random() which produces a 32 bit number are minimized in an
// efficient way.
//
// TBD: put it in a class ?
// TBD: put it in a class ?
uint32_t __randomBuffer = 0;
uint8_t __randomIdx = 0;
@ -35,10 +25,10 @@ uint8_t __randomIdx = 0;
///////////////////////////////////////////////////////////////////////////
//
// An example of a simple pseudo-random number generator is the
// Multiply-with-carry method invented by George Marsaglia.
// it has two initializers (not zero) which can be changed
// to seed the generator.
// An example of a simple pseudo-random number generator is the
// Multiply-with-carry method invented by George Marsaglia.
// it has two initializers (not zero) which can be changed
// to seed the generator.
//
uint32_t m_w = 1;
uint32_t m_z = 2;
@ -63,7 +53,7 @@ bool seedMarsaglia(uint32_t a, uint32_t b)
uint32_t getRandom32()
{
// return random(0xFFFFFFFF); // use the built in
// return random(0xFFFFFFFF); // use the built in
return Marsaglia();
}
@ -81,7 +71,7 @@ bool getRandom1()
return rv;
}
// typical use
// typical use
bool inline flipCoin()
{
return getRandom1();
@ -130,7 +120,7 @@ uint8_t getRandom6()
}
// typical use
// typical use
uint8_t throwDice()
{
if (__randomIdx < 16)
@ -188,7 +178,7 @@ uint64_t getRandom64()
}
/*
// works well for 1..16; but above it is worse
// works well for 1..16; but above it is worse
uint32_t getRandomBits(uint8_t n)
{
if (__randomIdx < n)
@ -204,13 +194,13 @@ uint32_t getRandomBits(uint8_t n)
*/
// n = 1..31
// TODO: performance gain too low for n > 16
// n = 1..31
// TODO: performance gain too low for n > 16
uint32_t getRandomBits(uint8_t n)
{
uint32_t rv = 0;
// for large values of n the more straightforward approach is faster (UNO).
// for large values of n the more straightforward approach is faster (UNO).
if (n > 32) n = 32;
if (n >= 20) return getRandom32() >> (32 - n);
@ -224,7 +214,7 @@ uint32_t getRandomBits(uint8_t n)
__randomBuffer = getRandom32();
__randomIdx = 32;
}
if (n > 0) // more bits needed?
if (n > 0) // more bits needed?
{
rv |= __randomBuffer & ((1UL << n) - 1);
__randomBuffer >>= n;
@ -234,5 +224,5 @@ uint32_t getRandomBits(uint8_t n)
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -2,31 +2,31 @@
//
// FILE: randomHelpers.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// VERSION: 0.2.5
// PURPOSE: Arduino library with helper function for faster random bits
// URL: https://github.com/RobTillaart/randomHelpers
#include "Arduino.h"
#define RANDOM_HELPERS_VERSION (F("0.2.4"))
#define RANDOM_HELPERS_VERSION (F("0.2.5"))
// the idea is to have one buffer ( __randomBuffer) which holds 32 random bits.
// Every call fetches bits from that buffer and if it does not hold enough
// bits any more it fills the buffer first. This way the relative expensive
// calls to random() which produces a 32 bit number are minimized in an
// efficient way.
// the idea is to have one buffer ( __randomBuffer) which holds 32 random bits.
// Every call fetches bits from that buffer and if it does not hold enough
// bits any more it fills the buffer first. This way the relative expensive
// calls to random() which produces a 32 bit number are minimized in an
// efficient way.
//
// TBD: put it in a class ?
// TBD: put it in a class ?
///////////////////////////////////////////////////////////////////////////
//
// An example of a simple pseudo-random number generator is the
// Multiply-with-carry method invented by George Marsaglia.
// it has two initializers (not zero) which can be changed
// to seed the generator.
// An example of a simple pseudo-random number generator is the
// Multiply-with-carry method invented by George Marsaglia.
// it has two initializers (not zero) which can be changed
// to seed the generator.
//
uint32_t Marsaglia();
@ -37,7 +37,7 @@ uint32_t getRandom32();
bool getRandom1();
// typical use
// typical use
bool inline flipCoin();
uint8_t getRandom4();
@ -46,7 +46,7 @@ uint8_t getRandom5();
uint8_t getRandom6();
// typical use
// typical use
uint8_t throwDice();
uint8_t getRandom8();

View File

@ -36,28 +36,16 @@
#include "randomHelpers.h"
unittest_setup()
{
fprintf(stderr, "RANDOM_HELPERS_VERSION: %s\n", (char *) RANDOM_HELPERS_VERSION);
}
unittest_teardown()
{
}
/*
unittest(test_new_operator)
{
assertEqualINF(exp(800));
assertEqualINF(0.0/0.0);
assertEqualINF(42);
assertEqualNAN(INFINITY - INFINITY);
assertEqualNAN(0.0/0.0);
assertEqualNAN(42);
}
*/
unittest(test_all)
{
@ -73,9 +61,9 @@ unittest(test_all)
assertMore(16777215, getRandom24());
assertMore(pow(2, 32), getRandom32());
}
}
unittest_main()
// --------