diff --git a/libraries/fast_math/CHANGELOG.md b/libraries/fast_math/CHANGELOG.md index 5e43700a..fd25f4c8 100644 --- a/libraries/fast_math/CHANGELOG.md +++ b/libraries/fast_math/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.2.1] - 2022-12 +- add divmod3() +- add divmod5() +- add divmod12(), divmod24(), divmod60() - time related. +- update ping2cm(), ping2mm() +- update ping2cm32(), ping2mm32() +- add ping2quarter(); +- add ping2inch_tempF(duration, Fahrenheit); + + ## [0.2.0] - 2022-10-29 - initial release as library - add examples diff --git a/libraries/fast_math/README.md b/libraries/fast_math/README.md index 1eb131fa..f6ec5715 100644 --- a/libraries/fast_math/README.md +++ b/libraries/fast_math/README.md @@ -53,10 +53,10 @@ Backgrounder - https://forum.arduino.cc/t/faster-dec2bcd-routine-especial-for-rt Indicative performance Arduino UNO. | function | us | factor | notes | -|:----------------|:------:|:-------:|:-------:| +|:----------------|:------:|:-------:|:--------| | dec2bcd (ref) | 5.88 | 1.0 | 100 iterations | dec2bcd | 1.04 | 4.8 | -| dec2bcdRTC | 0.88 | 5.7 | +| dec2bcdRTC | 0.88 | 5.7 | range 0..68 | | | | | bcd2dec (ref) | 5.96 | 1.0 | | bcd2dec | 2.20 | 2.7 | @@ -65,22 +65,39 @@ Indicative performance Arduino UNO. ### DIV - **void divmod10(uint32_t in, uint32_t \*div, uint8_t \*mod)** -function calculates both divide and modulo 10 faster than the default / 10 and % 10. + - calculates both divide and modulo 10 faster than the default / 10 and % 10. -This function is very useful for extracting the individual digits. -Typical use is print digits on a display, in a file or send them as ASCII. +The divmod10() function is very useful for extracting the individual digits. +Typical use is to print digits on a display, in a file or send them as ASCII over a network. Indicative performance Arduino UNO. | function | us | factor | notes | -|:-----------|:------:|:-------:|:-------:| +|:-----------|:------:|:-------:|:--------| | i % 10 | 38.2 | 1.0 | | i / 10 | 38.1 | 1.0 | -| divmod10 | 9.1 | 4.1 | +| divmod10 | 9.1 | 4.1 | + +Note that for printing the gain in time per digit is 65 us. +E.g. for a 4 digit number this adds up to ~quarter millisecond. + Backgrounder - https://forum.arduino.cc/t/divmod10-a-fast-replacement-for-10-and-10-unsigned/163586 -Note: For every element of N (natural numbers) one could develop a divmodN() function. + +- **void divmod3(uint32_t in, uint32_t \*div, uint8_t \*mod)** used by divmod12/24 +- **void divmod5(uint32_t in, uint32_t \*div, uint8_t \*mod)** +- **void divmod12(uint32_t in, uint32_t \*div, uint8_t \*mod)** for hours +- **void divmod24(uint32_t in, uint32_t \*div, uint8_t \*mod)** for hours +- **void divmod60(uint32_t in, uint32_t \*div, uint8_t \*mod)** for minutes seconds + + +For every element of N (natural numbers) one could develop a divmodN() function. +The idea is to split the fraction 1/N into a sum of selected 1/(2^n) so the division +becomes a series of adds and shifts. +Sometimes there are patterns that can be optimized even more. + +Furthermore for limited ranges a division can be replaced by a single multiply shift pair. ### PING @@ -102,34 +119,55 @@ The functions assume a speed of sound of 340 m/sec. 16 bit interface - **uint16_t ping2cm(uint16_t in)** - **uint16_t ping2mm(uint16_t in)** -- **uint16_t ping2inch(uint16_t in)** -- **uint16_t ping2sixteenths(uint16_t in)** 32 bit interface -- **uint32_t ping2cm32(uint32_t in)** -- **uint32_t ping2mm32(uint32_t in)** +- **uint32_t ping2cm32(uint32_t in)** for lengths > 10 meter +- **uint32_t ping2mm32(uint32_t in)** for lengths > 10 meter +Performance wise the 32 bit versions have a gain ~10%. - -#### temperature corrected - -- **float ping2cm_tempC(uint16_t duration, int Celsius)** temperature corrected speed of sound. - - duration in us, temperature in Celsius. - - this function is relative slow, a faster version is not tested. -- **float ping2inch_tempC(uint16_t duration, int Celsius)** temperature corrected speed of sound. +Imperial +- **uint16_t ping2inch(uint16_t in)** +- **uint16_t ping2quarter(uint16_t in)** +- **uint16_t ping2sixteenths(uint16_t in)** Indicative performance Arduino UNO. | function | us | factor | notes | -|:------------------|:------:|:-------:|:-------:| -| us / 29 (ref) | 38.1 | 1.0 | sos == 345 m/s (integer only) -| us \* 0.0345 | 18.5 | 2.0 | +|:------------------|:------:|:-------:|:--------| +| us / 29 (ref) | 38.3 | 1.0 | sos == 345 m/s (integer only) +| us \* 0.0345 | 18.5 | 2.0 | sos == 345 m/s | ping2cm | 3.08 | 12.4 | sos == 340 m/s | ping2mm | 5.66 | 6.7 | sos == 340 m/s -| ping2cm_tempC | 36.8 | 1.0 | adds temperature correction. | | | | -| ping2inch | 3.90 | 9.8 | not as exact as inches are rather large units -| ping2sixteenths | 8.11 | 4.8 | way more accurate than inches +| ping2inch | 4.34 | 8.8 | not precise as inches are rather large units +| ping2quarter | 7.55 | 5.0 | in between +| ping2sixteenths | 8.55 | 4.4 | way more accurate than inches + + +#### temperature corrected + +Instead of taking a fixed value a temperature corrected speed of sound will +be 0-5% more accurate. Of course this depends on the temperature. + +The temperature is in whole degrees C or F. + +- **float ping2cm_tempC(uint16_t duration, int Celsius)** + - duration in us, temperature in Celsius. + - this function is relative slow, a faster version is not tested. +- **float ping2inch_tempC(uint16_t duration, int Celsius)** +- **float ping2inch_tempF(uint16_t duration, int Fahrenheit)** + + +Indicative performance Arduino UNO. + +| function | us | factor | notes | +|:------------------|:------:|:-------:|:--------| +| normal division | 38.3 | 1.0 | not Temperature corrected +| ping2cm_tempC | 17.2 | 2.2 | +| ping2inch_tempC | 16.6 | 2.3 | +| ping2inch_tempF | 16.4 | 2.3 | + ### polynome @@ -158,33 +196,31 @@ can be tuned (runtime). - unit tests - or examples that test a lot. - examples + - check output examples. +- keep investigating faster versions. +- divmod performance table other versions + #### could - split up in multiple .h files, one per group. - fast_math.h includes all individual .h files. -- There are several divide functions to be included. - div3(), div5(), div7(), div10(), mod10() +- There are several divide functions to be included? + div3(), div5(), div7(), div10() depends on application. These need more testing (range) - constants? - GOLDEN_RATIO 1.61803398875 +- check temperature corrected float? + #### TODO Functions DIV -- **uint16_t divmod10()** 16 bit overload version -- **uint32_t div10(x, \*d)** would be a bit faster +- **uint16_t divmod10()** 16 bit overload version ? +- **uint32_t div10(x, \*d)** would be a bit faster than divmod10() - **uint32_t mod10(x, \*m)** would be a bit faster too -- clock - - **divmod24** == div3 >>3 (minutes to days) - - **divmod12** == div3 >>2 - - **divmod60** == div15 >>2 of div5 div3 >>2 (seconds to minutes + minutes to hours) -- **div7** days - weeks. - - -PING -- **float ping2inch_tempF(uint16_t in, int Fahrenheit)** -- **uint32_t ping2inch(uint32_t in)** + sixteenth -- **uint32_t ping2sixteenth(uint32_t in)** +- **div7()** days - weeks. +BCD +- **uint16_t dec2bcd()** + 32 bit + back? diff --git a/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.0.txt b/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.0.txt new file mode 100644 index 00000000..3b5922ad --- /dev/null +++ b/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.0.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod12_performance.ino +FASTMATH_LIB_VERSION: 0.2.0 + +div + mod: 48 16807 1400 7 +divmod12: 24 16807 1400 7 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +61147540 +done... diff --git a/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.1.txt b/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.1.txt new file mode 100644 index 00000000..13957f98 --- /dev/null +++ b/libraries/fast_math/examples/divmod12_performance/divmod12_0.2.1.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod12_performance.ino +FASTMATH_LIB_VERSION: 0.2.1 + +div + mod: 48 16807 1400 7 +divmod12: 24 16807 1400 7 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +61147540 +done... diff --git a/libraries/fast_math/examples/divmod12_performance/divmod12_performance.ino b/libraries/fast_math/examples/divmod12_performance/divmod12_performance.ino new file mode 100644 index 00000000..878fff33 --- /dev/null +++ b/libraries/fast_math/examples/divmod12_performance/divmod12_performance.ino @@ -0,0 +1,88 @@ +// +// FILE: divmod12_performance.ino +// AUTHOR: Rob Tillaart +// PURPOSE: divmod12 performance test +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +uint32_t x, d; +uint8_t m; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(1000); + + x = random(2000000000ULL); + start = micros(); + d = x / 12; + m = x % 12; + stop = micros(); + Serial.print("div + mod: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + start = micros(); + divmod12(x, &d, &m); + stop = micros(); + Serial.print("divmod12: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); + start = micros(); + for (uint32_t x = 0; x <= 1000000; x++) + { + if (x % 100000 == 0) Serial.println(x); + divmod12(x, &d, &m); + if ( (x != d*12 +m) || (m > 11)) + { + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + } + } + stop = micros(); + Serial.print(stop - start); + Serial.print("\n"); + + Serial.println("done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/divmod24_performance/divmod24_0.2.1.txt b/libraries/fast_math/examples/divmod24_performance/divmod24_0.2.1.txt new file mode 100644 index 00000000..d5a7f214 --- /dev/null +++ b/libraries/fast_math/examples/divmod24_performance/divmod24_0.2.1.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod24_performance.ino +FASTMATH_LIB_VERSION: 0.2.1 + +div + mod: 48 16807 700 7 +divmod24: 24 16807 700 7 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +61587648 +done... diff --git a/libraries/fast_math/examples/divmod24_performance/divmod24_performance.ino b/libraries/fast_math/examples/divmod24_performance/divmod24_performance.ino new file mode 100644 index 00000000..e0882384 --- /dev/null +++ b/libraries/fast_math/examples/divmod24_performance/divmod24_performance.ino @@ -0,0 +1,88 @@ +// +// FILE: divmod24_performance.ino +// AUTHOR: Rob Tillaart +// PURPOSE: divmod24 performance test +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +uint32_t x, d; +uint8_t m; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(1000); + + x = random(2000000000ULL); + start = micros(); + d = x / 24; + m = x % 24; + stop = micros(); + Serial.print("div + mod: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + start = micros(); + divmod24(x, &d, &m); + stop = micros(); + Serial.print("divmod24: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); + start = micros(); + for (uint32_t x = 0; x <= 1000000; x++) + { + if (x % 100000 == 0) Serial.println(x); + divmod24(x, &d, &m); + if ( (x != d*24 +m) || (m > 23)) + { + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + } + } + stop = micros(); + Serial.print(stop - start); + Serial.print("\n"); + + Serial.println("done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.0.txt b/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.0.txt new file mode 100644 index 00000000..b6de1f9a --- /dev/null +++ b/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.0.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod3_performance.ino +FASTMATH_LIB_VERSION: 0.2.0 + +div + mod: 44 16807 5602 1 +divmod3: 24 16807 5602 1 + +Test 0 .. 1 million (1 minute UNO, < 1second ESP32) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +61210540 +done... diff --git a/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.1.txt b/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.1.txt new file mode 100644 index 00000000..98406696 --- /dev/null +++ b/libraries/fast_math/examples/divmod3_performance/divmod3_0.2.1.txt @@ -0,0 +1,24 @@ +UNO +1.8.19 + +divmod3_performance.ino +FASTMATH_LIB_VERSION: 0.2.1 + +div + mod: 44 16807 5602 1 +divmod3: 20 16807 5602 1 + +Test 0 .. 1 million (1 minute UNO, < 1second ESP32) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +58255512 +done... + diff --git a/libraries/fast_math/examples/divmod3_performance/divmod3_performance.ino b/libraries/fast_math/examples/divmod3_performance/divmod3_performance.ino new file mode 100644 index 00000000..b0c8bfe2 --- /dev/null +++ b/libraries/fast_math/examples/divmod3_performance/divmod3_performance.ino @@ -0,0 +1,88 @@ +// +// FILE: divmod3_performance.ino +// AUTHOR: Rob Tillaart +// PURPOSE: divmod3 performance test +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +uint32_t x, d; +uint8_t m; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(1000); + + x = random(2000000000ULL); + start = micros(); + d = x / 3; + m = x % 3; + stop = micros(); + Serial.print("div + mod: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + start = micros(); + divmod3(x, &d, &m); + stop = micros(); + Serial.print("divmod3: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + Serial.println("\nTest 0 .. 1 million (1 minute UNO, < 1second ESP32)"); + start = micros(); + for (uint32_t x = 0; x <= 1000000; x++) + { + if (x % 100000 == 0) Serial.println(x); + divmod3(x, &d, &m); + if ( (x != d*3 +m) || (m > 2)) + { + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + } + } + stop = micros(); + Serial.print(stop - start); + Serial.print("\n"); + + Serial.println("done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.0.txt b/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.0.txt new file mode 100644 index 00000000..56f4c4e2 --- /dev/null +++ b/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.0.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod5_performance.ino +FASTMATH_LIB_VERSION: 0.2.0 + +div + mod: 40 16807 3361 2 +divmod5: 20 16807 3361 2 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +60581680 +done... diff --git a/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.1.txt b/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.1.txt new file mode 100644 index 00000000..25f2ac46 --- /dev/null +++ b/libraries/fast_math/examples/divmod5_performance/divmod5_0.2.1.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod5_performance.ino +FASTMATH_LIB_VERSION: 0.2.1 + +div + mod: 40 16807 3361 2 +divmod5: 20 16807 3361 2 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +58506880 +done... diff --git a/libraries/fast_math/examples/divmod5_performance/divmod5_performance.ino b/libraries/fast_math/examples/divmod5_performance/divmod5_performance.ino new file mode 100644 index 00000000..bf0d6768 --- /dev/null +++ b/libraries/fast_math/examples/divmod5_performance/divmod5_performance.ino @@ -0,0 +1,88 @@ +// +// FILE: divmod5_performance.ino +// AUTHOR: Rob Tillaart +// PURPOSE: divmod5 performance test +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +uint32_t x, d; +uint8_t m; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(1000); + + x = random(2000000000ULL); + start = micros(); + d = x / 5; + m = x % 5; + stop = micros(); + Serial.print("div + mod: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + start = micros(); + divmod5(x, &d, &m); + stop = micros(); + Serial.print("divmod5: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); + start = micros(); + for (uint32_t x = 0; x <= 1000000; x++) + { + if (x % 100000 == 0) Serial.println(x); + divmod5(x, &d, &m); + if ( (x != d*5 +m) || (m > 4)) + { + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + } + } + stop = micros(); + Serial.print(stop - start); + Serial.print("\n"); + + Serial.println("done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/divmod60_performance/divmod60_0.2.1.txt b/libraries/fast_math/examples/divmod60_performance/divmod60_0.2.1.txt new file mode 100644 index 00000000..12db1114 --- /dev/null +++ b/libraries/fast_math/examples/divmod60_performance/divmod60_0.2.1.txt @@ -0,0 +1,23 @@ +UNO +1.8.19 + +divmod60_performance.ino +FASTMATH_LIB_VERSION: 0.2.1 + +div + mod: 48 16807 280 7 +divmod60: 12 16807 280 7 + +Test 0 .. 1 million (1 minute UNO) +0 +100000 +200000 +300000 +400000 +500000 +600000 +700000 +800000 +900000 +1000000 +52168832 +done... diff --git a/libraries/fast_math/examples/divmod60_performance/divmod60_performance.ino b/libraries/fast_math/examples/divmod60_performance/divmod60_performance.ino new file mode 100644 index 00000000..d73f54ef --- /dev/null +++ b/libraries/fast_math/examples/divmod60_performance/divmod60_performance.ino @@ -0,0 +1,88 @@ +// +// FILE: divmod60_performance.ino +// AUTHOR: Rob Tillaart +// PURPOSE: divmod60 performance test +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +uint32_t x, d; +uint8_t m; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(1000); + + x = random(2000000000ULL); + start = micros(); + d = x / 60; + m = x % 60; + stop = micros(); + Serial.print("div + mod: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + start = micros(); + divmod60(x, &d, &m); + stop = micros(); + Serial.print("divmod60: "); + Serial.print("\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + delay(100); + + Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); + start = micros(); + for (uint32_t x = 0; x <= 1000000; x++) + { + if (x % 100000 == 0) Serial.println(x); + divmod60(x, &d, &m); + if ( (x != d*60 +m) || (m > 59)) + { + Serial.print(x); + Serial.print("\t"); + Serial.print(d); + Serial.print("\t"); + Serial.print(m); + Serial.print("\n"); + } + } + stop = micros(); + Serial.print(stop - start); + Serial.print("\n"); + + Serial.println("done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/ping2_temp_compensated/performance_0.2.1.txt b/libraries/fast_math/examples/ping2_temp_compensated/performance_0.2.1.txt new file mode 100644 index 00000000..38949f86 --- /dev/null +++ b/libraries/fast_math/examples/ping2_temp_compensated/performance_0.2.1.txt @@ -0,0 +1,79 @@ +ping2inch.ino +FASTMATH_LIB_VERSION: 0.2.1 + +ping2inch ref 38.1696 +ping2inch fast 4.3384 +ping2sixteenths ref 38.9048 +ping2sixteenths fast 8.5508 + +verify I +0 0.0 2 inf 0 2 inf +10 0.1 2 14.94 2 3 1.40 +20 0.3 2 7.47 4 5 1.17 +30 0.4 2 4.98 6 6 0.93 +40 0.5 2 3.74 9 9 1.05 +50 0.7 2 2.99 11 11 1.03 +60 0.8 2 2.49 13 12 0.93 +70 0.9 2 2.13 15 15 1.00 +80 1.1 2 1.87 17 18 1.05 +90 1.2 2 1.66 19 19 0.99 +100 1.3 2 1.49 21 21 0.98 +110 1.5 2 1.36 24 22 0.93 +120 1.6 2 1.25 26 25 0.97 +130 1.7 3 1.72 28 29 1.04 +140 1.9 3 1.60 30 30 1.00 +150 2.0 3 1.49 32 32 1.00 +160 2.1 3 1.40 34 35 1.02 +170 2.3 3 1.32 36 36 0.99 +180 2.4 3 1.25 39 38 0.99 +190 2.5 3 1.18 41 39 0.96 + +verify II +200 2.7 3 1.12 43 43 1.00 +250 3.3 3 0.90 54 52 0.97 +300 4.0 5 1.25 64 63 0.98 +350 4.7 5 1.07 75 73 0.97 +400 5.4 6 1.12 86 86 1.00 +450 6.0 6 1.00 96 96 1.00 +500 6.7 6 0.90 107 105 0.98 +550 7.4 8 1.09 118 117 0.99 +600 8.0 8 1.00 129 128 1.00 +650 8.7 9 1.03 139 139 1.00 +700 9.4 9 0.96 150 148 0.99 +750 10.0 9 0.90 161 158 0.98 +800 10.7 11 1.03 171 171 1.00 +850 11.4 11 0.97 182 181 0.99 +900 12.0 12 1.00 193 192 1.00 +950 12.7 12 0.94 203 201 0.99 + +verify III +1000 13.4 12 0.90 214 212 0.99 +2000 26.8 25 0.93 428 427 1.00 +3000 40.2 39 0.97 643 640 1.00 +4000 53.5 52 0.97 857 855 1.00 +5000 66.9 66 0.99 1071 1070 1.00 +6000 80.3 78 0.97 1285 1283 1.00 +7000 93.7 92 0.98 1499 1497 1.00 +8000 107.1 105 0.98 1713 1712 1.00 +9000 120.5 120 1.00 1928 1926 1.00 +10000 133.9 133 0.99 2142 2141 1.00 +11000 147.2 145 0.98 2356 2353 1.00 +12000 160.6 158 0.98 2570 2568 1.00 +13000 174.0 172 0.99 2784 2783 1.00 +14000 187.4 185 0.99 2998 2997 1.00 +15000 200.8 199 0.99 3213 3211 1.00 +16000 214.2 212 0.99 3427 3426 1.00 +17000 227.6 227 1.00 3641 3640 1.00 +18000 240.9 240 1.00 3855 3855 1.00 +19000 254.3 254 1.00 4069 4068 1.00 +20000 267.7 267 1.00 4283 4283 1.00 +21000 281.1 281 1.00 4498 4498 1.00 +22000 294.5 292 0.99 4712 4710 1.00 +23000 307.9 306 0.99 4926 4924 1.00 +24000 321.3 319 0.99 5140 5139 1.00 +25000 334.6 334 1.00 5354 5353 1.00 +26000 348.0 347 1.00 5569 5568 1.00 +27000 361.4 360 1.00 5783 5780 1.00 +28000 374.8 373 1.00 5997 5995 1.00 +29000 388.2 387 1.00 6211 6210 1.00 +30000 401.6 400 1.00 6425 6424 1.00 diff --git a/libraries/fast_math/examples/ping2_temp_compensated/ping2_temp_compensated.ino b/libraries/fast_math/examples/ping2_temp_compensated/ping2_temp_compensated.ino new file mode 100644 index 00000000..810c2fbe --- /dev/null +++ b/libraries/fast_math/examples/ping2_temp_compensated/ping2_temp_compensated.ino @@ -0,0 +1,134 @@ +// +// FILE: ping2_temp_compensated.ino +// AUTHOR: Rob Tillaart +// DATE: 2022-12-25 +// PUPROSE: test fast routines for PING))) sensor +// URL: https://github.com/RobTillaart/fast_math + + +#include "Arduino.h" +#include "fast_math.h" + + +uint32_t start, stop; +volatile uint32_t q = 0; + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("FASTMATH_LIB_VERSION: "); + Serial.println(FASTMATH_LIB_VERSION); + Serial.println(); + delay(10); + + Serial.print("ping2cm ref\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = i / 29.41176; + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + Serial.print("ping2cm_tempC\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2cm_tempC(i, 20); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + + + Serial.print("ping2inch ref\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = i / 74.70588235; + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + Serial.print("ping2inch_tempC\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2inch_tempC(i, 20); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + Serial.print("ping2inch_tempF\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2inch_tempC(i, 68); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + + Serial.println("\n=============================================="); + + Serial.println("\ndelta ping2cm_tempC"); + for (uint16_t temp = 0; temp < 40; temp++) + { + Serial.print(temp); + Serial.print("\t"); + Serial.print(15000 / 29.41176, 1); + Serial.print("\t"); + Serial.print(ping2cm_tempC(15000, temp)); + Serial.print("\t"); + Serial.print(ping2cm_tempC(15000, temp) / (15000 / 29.41176) ); + Serial.println(); + } + + Serial.println("\ndelta ping2inch_tempC"); + for (uint16_t temp = 0; temp < 40; temp++) + { + Serial.print(temp); + Serial.print("\t"); + Serial.print(15000 / 74.70588235, 1); + Serial.print("\t"); + Serial.print(ping2inch_tempC(15000, temp)); + Serial.print("\t"); + Serial.print(ping2inch_tempC(15000, temp) / (15000 / 74.70588235)); + Serial.println(); + } + + + Serial.println("\ndelta ping2inch_tempF"); + for (uint16_t temp = 32; temp < 100; temp += 2) + { + Serial.print(temp); + Serial.print("\t"); + Serial.print(15000 / 74.70588235, 1); + Serial.print("\t"); + Serial.print(ping2inch_tempF(15000, temp)); + Serial.print("\t"); + Serial.print(ping2inch_tempF(15000, temp) / (15000 / 74.70588235)); + Serial.println(); + } + +} + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/fast_math/examples/ping2cm/performance_0.2.1.txt b/libraries/fast_math/examples/ping2cm/performance_0.2.1.txt new file mode 100644 index 00000000..db5e7173 --- /dev/null +++ b/libraries/fast_math/examples/ping2cm/performance_0.2.1.txt @@ -0,0 +1,164 @@ +UNO +1.8.19 + + +ping2cm.ino +FASTMATH_LIB_VERSION: 0.2.1 + +pingRef 38.7176 +ping2cm 5.8472 +ping2mm 7.4188 +ping2cm32 35.7748 +ping2mm32 34.8948 + +======================================= + +verify - 16 bit +100 3.4 5 1.47 34.0 35 1.03 +110 3.7 5 1.34 37.4 37 0.99 +121 4.1 5 1.22 41.1 41 1.00 +133 4.5 6 1.33 45.2 47 1.04 +146 5.0 6 1.21 49.6 51 1.03 +160 5.4 7 1.29 54.4 56 1.03 +176 6.0 7 1.17 59.8 61 1.02 +193 6.6 8 1.22 65.6 67 1.02 +212 7.2 8 1.11 72.1 73 1.01 +233 7.9 9 1.14 79.2 79 1.00 +256 8.7 10 1.15 87.0 90 1.03 +281 9.6 10 1.05 95.5 97 1.02 +309 10.5 11 1.05 105.1 106 1.01 +339 11.5 12 1.04 115.3 116 1.01 +372 12.6 13 1.03 126.5 127 1.00 +409 13.9 14 1.01 139.1 140 1.01 +449 15.3 16 1.05 152.7 154 1.01 +493 16.8 17 1.01 167.6 167 1.00 +542 18.4 19 1.03 184.3 185 1.00 +596 20.3 21 1.04 202.6 204 1.01 +655 22.3 23 1.03 222.7 223 1.00 +720 24.5 25 1.02 244.8 246 1.00 +792 26.9 27 1.00 269.3 271 1.01 +871 29.6 30 1.01 296.1 296 1.00 +958 32.6 32 0.98 325.7 325 1.00 +1053 35.8 36 1.01 358.0 359 1.00 +1158 39.4 40 1.02 393.7 395 1.00 +1273 43.3 43 0.99 432.8 432 1.00 +1400 47.6 47 0.99 476.0 476 1.00 +1540 52.4 53 1.01 523.6 526 1.00 +1694 57.6 57 0.99 576.0 576 1.00 +1863 63.3 63 0.99 633.4 634 1.00 +2049 69.7 71 1.02 696.7 699 1.00 +2253 76.6 77 1.01 766.0 766 1.00 +2478 84.3 84 1.00 842.5 842 1.00 +2725 92.7 93 1.00 926.5 927 1.00 +2997 101.9 101 0.99 1019.0 1019 1.00 +3296 112.1 112 1.00 1120.6 1121 1.00 +3625 123.3 123 1.00 1232.5 1233 1.00 +3987 135.6 134 0.99 1355.6 1356 1.00 +4385 149.1 150 1.01 1490.9 1492 1.00 +4823 164.0 164 1.00 1639.8 1639 1.00 +5305 180.4 180 1.00 1803.7 1803 1.00 +5835 198.4 198 1.00 1983.9 1983 1.00 +6418 218.2 218 1.00 2182.1 2183 1.00 +7059 240.0 239 1.00 2400.1 2400 1.00 +7764 264.0 263 1.00 2639.8 2640 1.00 +8540 290.4 290 1.00 2903.6 2904 1.00 +9394 319.4 319 1.00 3194.0 3194 1.00 +10333 351.3 351 1.00 3513.2 3513 1.00 +11366 386.4 386 1.00 3864.4 3864 1.00 +12502 425.1 425 1.00 4250.7 4250 1.00 +13752 467.6 466 1.00 4675.7 4675 1.00 +15127 514.3 513 1.00 5143.2 5143 1.00 +16639 565.7 566 1.00 5657.3 5655 1.00 +18302 622.3 621 1.00 6222.7 6221 1.00 +20132 684.5 684 1.00 6844.9 6845 1.00 +22145 752.9 753 1.00 7529.3 7530 1.00 +24359 828.2 827 1.00 8282.1 8281 1.00 +26794 911.0 911 1.00 9110.0 9109 1.00 +29473 1002.1 1002 1.00 10020.8 10021 1.00 + +verify - 32 bit +100 3.4 6 1.76 34.0 35 1.03 +110 3.7 6 1.60 37.4 37 0.99 +121 4.1 6 1.46 41.1 41 1.00 +133 4.5 7 1.55 45.2 47 1.04 +146 5.0 7 1.41 49.6 51 1.03 +160 5.4 8 1.47 54.4 56 1.03 +176 6.0 8 1.34 59.8 61 1.02 +193 6.6 9 1.37 65.6 67 1.02 +212 7.2 9 1.25 72.1 73 1.01 +233 7.9 10 1.26 79.2 79 1.00 +256 8.7 11 1.26 87.0 90 1.03 +281 9.6 11 1.15 95.5 97 1.02 +309 10.5 12 1.14 105.1 106 1.01 +339 11.5 13 1.13 115.3 116 1.01 +372 12.6 14 1.11 126.5 127 1.00 +409 13.9 15 1.08 139.1 140 1.01 +449 15.3 17 1.11 152.7 154 1.01 +493 16.8 18 1.07 167.6 167 1.00 +542 18.4 20 1.09 184.3 185 1.00 +596 20.3 22 1.09 202.6 204 1.01 +655 22.3 24 1.08 222.7 223 1.00 +720 24.5 26 1.06 244.8 246 1.00 +792 26.9 28 1.04 269.3 271 1.01 +871 29.6 31 1.05 296.1 296 1.00 +958 32.6 33 1.01 325.7 325 1.00 +1053 35.8 37 1.03 358.0 359 1.00 +1158 39.4 41 1.04 393.7 395 1.00 +1273 43.3 44 1.02 432.8 432 1.00 +1400 47.6 48 1.01 476.0 476 1.00 +1540 52.4 54 1.03 523.6 526 1.00 +1694 57.6 58 1.01 576.0 576 1.00 +1863 63.3 64 1.01 633.4 634 1.00 +2049 69.7 72 1.03 696.7 699 1.00 +2253 76.6 78 1.02 766.0 766 1.00 +2478 84.3 85 1.01 842.5 842 1.00 +2725 92.7 94 1.01 926.5 927 1.00 +2997 101.9 102 1.00 1019.0 1019 1.00 +3296 112.1 113 1.01 1120.6 1121 1.00 +3625 123.3 124 1.01 1232.5 1233 1.00 +3987 135.6 135 1.00 1355.6 1356 1.00 +4385 149.1 151 1.01 1490.9 1492 1.00 +4823 164.0 165 1.01 1639.8 1639 1.00 +5305 180.4 181 1.00 1803.7 1803 1.00 +5835 198.4 199 1.00 1983.9 1983 1.00 +6418 218.2 219 1.00 2182.1 2183 1.00 +7059 240.0 240 1.00 2400.1 2400 1.00 +7764 264.0 264 1.00 2639.8 2640 1.00 +8540 290.4 291 1.00 2903.6 2904 1.00 +9394 319.4 320 1.00 3194.0 3194 1.00 +10333 351.3 352 1.00 3513.2 3513 1.00 +11366 386.4 387 1.00 3864.4 3864 1.00 +12502 425.1 426 1.00 4250.7 4250 1.00 +13752 467.6 467 1.00 4675.7 4675 1.00 +15127 514.3 514 1.00 5143.2 5143 1.00 +16639 565.7 567 1.00 5657.3 5655 1.00 +18302 622.3 622 1.00 6222.7 6221 1.00 +20132 684.5 685 1.00 6844.9 6845 1.00 +22145 752.9 754 1.00 7529.3 7530 1.00 +24359 828.2 828 1.00 8282.1 8281 1.00 +26794 911.0 912 1.00 9110.0 9109 1.00 +29473 1002.1 1003 1.00 10020.8 10021 1.00 +32420 1102.3 1102 1.00 11022.8 11022 1.00 +35662 1212.5 1213 1.00 12125.1 12125 1.00 +39228 1333.8 1334 1.00 13337.5 13337 1.00 +43150 1467.1 1468 1.00 14671.0 14671 1.00 +47465 1613.8 1614 1.00 16138.1 16137 1.00 +52211 1775.2 1775 1.00 17751.7 17750 1.00 +57432 1952.7 1954 1.00 19526.9 19527 1.00 +63175 2148.0 2148 1.00 21479.5 21478 1.00 +69492 2362.7 2362 1.00 23627.3 23627 1.00 +76441 2599.0 2599 1.00 25989.9 25990 1.00 +84085 2858.9 2860 1.00 28588.9 28588 1.00 +92493 3144.8 3145 1.00 31447.6 31447 1.00 +101742 3459.2 3459 1.00 34592.3 34591 1.00 +111916 3805.1 3805 1.00 38051.4 38051 1.00 +123107 4185.6 4187 1.00 41856.4 41855 1.00 +135417 4604.2 4605 1.00 46041.8 46040 1.00 +148958 5064.6 5064 1.00 50645.7 50644 1.00 +163853 5571.0 5573 1.00 55710.0 55711 1.00 +180238 6128.1 6130 1.00 61280.9 61281 1.00 +198261 6740.9 6741 1.00 67408.7 67408 1.00 +218087 7415.0 7415 1.00 74149.6 74147 1.00 +239895 8156.4 8156 1.00 81564.3 81564 1.00 +263884 8972.1 8972 1.00 89720.6 89720 1.00 +290272 9869.2 9868 1.00 98692.5 98691 1.00 diff --git a/libraries/fast_math/examples/ping2cm/ping2cm.ino b/libraries/fast_math/examples/ping2cm/ping2cm.ino index da511a5e..98f8bae7 100644 --- a/libraries/fast_math/examples/ping2cm/ping2cm.ino +++ b/libraries/fast_math/examples/ping2cm/ping2cm.ino @@ -57,8 +57,31 @@ void setup() Serial.println((stop - start) / 10000.0, 4); delay(100); - Serial.println("\nverify I"); - for (uint16_t i = 0; i < 200; i += 10) + Serial.print("ping2cm32\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2cm32(i); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + Serial.print("ping2mm32\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2mm32(i); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(100); + + Serial.println("\n======================================="); + Serial.println("\nverify - 16 bit - up to 10 meter"); + for (uint16_t i = 100; i < 30000; i *= 1.1) { Serial.print(i); Serial.print("\t"); @@ -73,47 +96,26 @@ void setup() Serial.print(ping2mm(i)); Serial.print("\t"); Serial.print((1.0 * ping2mm(i)) / (i * 0.34) ); - Serial.print("\t"); Serial.println(); } - Serial.println("\nverify II"); - for (uint16_t i = 200; i < 1000; i += 50) - { - Serial.print(i); - Serial.print("\t"); - Serial.print(i * 0.034, 1); - Serial.print("\t"); - Serial.print(ping2cm(i)); - Serial.print("\t"); - Serial.print((1.0 * ping2cm(i)) / (i * 0.034) ); - Serial.print("\t\t"); - Serial.print(i * 0.34, 1); - Serial.print("\t"); - Serial.print(ping2mm(i)); - Serial.print("\t"); - Serial.print((1.0 * ping2mm(i)) / (i * 0.34) ); - Serial.print("\t"); - Serial.println(); - } - Serial.println("\nverify III"); - for (uint16_t i = 1000; i <= 10000; i += 500) + Serial.println("\nverify - 32 bit - up to 100 meter"); + for (uint32_t i = 100; i <= 300000; i *= 1.1) { Serial.print(i); Serial.print("\t"); Serial.print(i * 0.034, 1); Serial.print("\t"); - Serial.print(ping2cm(i)); + Serial.print(ping2cm32(i)); Serial.print("\t"); - Serial.print((1.0 * ping2cm(i)) / (i * 0.034) ); + Serial.print((1.0 * ping2cm32(i)) / (i * 0.034) ); Serial.print("\t\t"); Serial.print(i * 0.34, 1); Serial.print("\t"); - Serial.print(ping2mm(i)); - Serial.print("\t"); - Serial.print((1.0 * ping2mm(i)) / (i * 0.34) ); + Serial.print(ping2mm32(i)); Serial.print("\t"); + Serial.print((1.0 * ping2mm32(i)) / (i * 0.34) ); Serial.println(); } diff --git a/libraries/fast_math/examples/ping2inch/performance_0.2.1.txt b/libraries/fast_math/examples/ping2inch/performance_0.2.1.txt new file mode 100644 index 00000000..38949f86 --- /dev/null +++ b/libraries/fast_math/examples/ping2inch/performance_0.2.1.txt @@ -0,0 +1,79 @@ +ping2inch.ino +FASTMATH_LIB_VERSION: 0.2.1 + +ping2inch ref 38.1696 +ping2inch fast 4.3384 +ping2sixteenths ref 38.9048 +ping2sixteenths fast 8.5508 + +verify I +0 0.0 2 inf 0 2 inf +10 0.1 2 14.94 2 3 1.40 +20 0.3 2 7.47 4 5 1.17 +30 0.4 2 4.98 6 6 0.93 +40 0.5 2 3.74 9 9 1.05 +50 0.7 2 2.99 11 11 1.03 +60 0.8 2 2.49 13 12 0.93 +70 0.9 2 2.13 15 15 1.00 +80 1.1 2 1.87 17 18 1.05 +90 1.2 2 1.66 19 19 0.99 +100 1.3 2 1.49 21 21 0.98 +110 1.5 2 1.36 24 22 0.93 +120 1.6 2 1.25 26 25 0.97 +130 1.7 3 1.72 28 29 1.04 +140 1.9 3 1.60 30 30 1.00 +150 2.0 3 1.49 32 32 1.00 +160 2.1 3 1.40 34 35 1.02 +170 2.3 3 1.32 36 36 0.99 +180 2.4 3 1.25 39 38 0.99 +190 2.5 3 1.18 41 39 0.96 + +verify II +200 2.7 3 1.12 43 43 1.00 +250 3.3 3 0.90 54 52 0.97 +300 4.0 5 1.25 64 63 0.98 +350 4.7 5 1.07 75 73 0.97 +400 5.4 6 1.12 86 86 1.00 +450 6.0 6 1.00 96 96 1.00 +500 6.7 6 0.90 107 105 0.98 +550 7.4 8 1.09 118 117 0.99 +600 8.0 8 1.00 129 128 1.00 +650 8.7 9 1.03 139 139 1.00 +700 9.4 9 0.96 150 148 0.99 +750 10.0 9 0.90 161 158 0.98 +800 10.7 11 1.03 171 171 1.00 +850 11.4 11 0.97 182 181 0.99 +900 12.0 12 1.00 193 192 1.00 +950 12.7 12 0.94 203 201 0.99 + +verify III +1000 13.4 12 0.90 214 212 0.99 +2000 26.8 25 0.93 428 427 1.00 +3000 40.2 39 0.97 643 640 1.00 +4000 53.5 52 0.97 857 855 1.00 +5000 66.9 66 0.99 1071 1070 1.00 +6000 80.3 78 0.97 1285 1283 1.00 +7000 93.7 92 0.98 1499 1497 1.00 +8000 107.1 105 0.98 1713 1712 1.00 +9000 120.5 120 1.00 1928 1926 1.00 +10000 133.9 133 0.99 2142 2141 1.00 +11000 147.2 145 0.98 2356 2353 1.00 +12000 160.6 158 0.98 2570 2568 1.00 +13000 174.0 172 0.99 2784 2783 1.00 +14000 187.4 185 0.99 2998 2997 1.00 +15000 200.8 199 0.99 3213 3211 1.00 +16000 214.2 212 0.99 3427 3426 1.00 +17000 227.6 227 1.00 3641 3640 1.00 +18000 240.9 240 1.00 3855 3855 1.00 +19000 254.3 254 1.00 4069 4068 1.00 +20000 267.7 267 1.00 4283 4283 1.00 +21000 281.1 281 1.00 4498 4498 1.00 +22000 294.5 292 0.99 4712 4710 1.00 +23000 307.9 306 0.99 4926 4924 1.00 +24000 321.3 319 0.99 5140 5139 1.00 +25000 334.6 334 1.00 5354 5353 1.00 +26000 348.0 347 1.00 5569 5568 1.00 +27000 361.4 360 1.00 5783 5780 1.00 +28000 374.8 373 1.00 5997 5995 1.00 +29000 388.2 387 1.00 6211 6210 1.00 +30000 401.6 400 1.00 6425 6424 1.00 diff --git a/libraries/fast_math/examples/ping2inch/ping2inch.ino b/libraries/fast_math/examples/ping2inch/ping2inch.ino index 79b089ea..66ec9121 100644 --- a/libraries/fast_math/examples/ping2inch/ping2inch.ino +++ b/libraries/fast_math/examples/ping2inch/ping2inch.ino @@ -48,6 +48,30 @@ void setup() delay(10); + Serial.print("ping2quarter ref\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = i / 18.6764705875; + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + + Serial.print("ping2quarter fast\t"); + delay(10); + start = micros(); + for (uint16_t i = 0; i < 10000; i++) + { + q = ping2quarter(i); + } + stop = micros(); + Serial.println((stop - start) / 10000.0, 4); + delay(10); + + Serial.print("ping2sixteenths ref\t"); delay(10); start = micros(); @@ -84,6 +108,12 @@ void setup() Serial.print("\t"); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print("\t\t"); + Serial.print(i / 18.6764705875, 0); + Serial.print("\t"); + Serial.print(ping2quarter(i)); + Serial.print("\t"); + Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); + Serial.print("\t\t"); Serial.print(i / 4.669117646875, 0); Serial.print("\t"); Serial.print(ping2sixteenths(i)); @@ -94,7 +124,7 @@ void setup() } Serial.println("\nverify II"); - for (uint16_t i = 200; i < 1000; i += 100) + for (uint16_t i = 200; i < 1000; i += 50) { Serial.print(i); Serial.print("\t"); @@ -105,6 +135,12 @@ void setup() Serial.print("\t"); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print("\t\t"); + Serial.print(i / 18.6764705875, 0); + Serial.print("\t"); + Serial.print(ping2quarter(i)); + Serial.print("\t"); + Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); + Serial.print("\t\t"); Serial.print(i / 4.669117646875, 0); Serial.print("\t"); Serial.print(ping2sixteenths(i)); @@ -113,9 +149,9 @@ void setup() Serial.print("\t"); Serial.println(); } - + Serial.println("\nverify III"); - for (uint16_t i = 1000; i <= 10000; i += 1000) + for (uint16_t i = 1000; i <= 30000; i += 1000) { Serial.print(i); Serial.print("\t"); @@ -126,6 +162,12 @@ void setup() Serial.print("\t"); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print("\t\t"); + Serial.print(i / 18.6764705875, 0); + Serial.print("\t"); + Serial.print(ping2quarter(i)); + Serial.print("\t"); + Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); + Serial.print("\t\t"); Serial.print(i / 4.669117646875, 0); Serial.print("\t"); Serial.print(ping2sixteenths(i)); diff --git a/libraries/fast_math/fast_math.cpp b/libraries/fast_math/fast_math.cpp index fdcc85ea..1ab19220 100644 --- a/libraries/fast_math/fast_math.cpp +++ b/libraries/fast_math/fast_math.cpp @@ -1,7 +1,7 @@ // // FILE: fast_math.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library for fast math algorithms // DATE: 27 October 2013 // URL: https://github.com/RobTillaart/fast_math @@ -30,6 +30,66 @@ void divmod10(uint32_t in, uint32_t *div, uint8_t *mod) } +void divmod3(uint32_t in, uint32_t *div, uint8_t *mod) +{ + uint32_t q = (in >> 1) + (in >> 3); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q = q >> 1; + uint32_t r = in - q * 3; + q = q + (r * 86 >> 8); + *div = q; + *mod = in - q * 3; +} + + +void divmod5(uint32_t in, uint32_t *div, uint8_t *mod) +{ + uint32_t q = (in >> 1) + (in >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q = q >> 2; + uint32_t r = in - q * 5; // remainder approx + q = q + (r * 56 >> 8); + *div = q; + *mod = in - q * 5; +} + + +void divmod12(uint32_t in, uint32_t *div, uint8_t *mod) +{ + uint32_t d; + uint8_t m; + divmod3(in, &d, &m); + *div = d >> 2; + *mod = m + (d & 0x03) * 3; +} + + +void divmod24(uint32_t in, uint32_t *div, uint8_t *mod) +{ + uint32_t d; + uint8_t m; + divmod3(in, &d, &m); + *div = d >> 3; + *mod = m + (d & 0x07) * 3; +} + + +void divmod60(uint32_t in, uint32_t *div, uint8_t *mod) +{ + uint32_t q = (in >> 1) + (in >> 5); + q = (q + (q >> 8) + (q >> 16) + (q >> 24) ) >> 5; + uint8_t r = in - q*60; + if (r > 59) { q++; r -= 60; }; // correction. + *div = q; + *mod = r; +} + + + /////////////////////////////////////////////////////////// // // BCD @@ -111,7 +171,7 @@ uint16_t ping2cm(uint16_t in) d >>= 1; // in >> 12 q += d; d >>= 2; // in >> 14 - q += d + 1; + q += d + 2; return q; } @@ -130,7 +190,7 @@ uint16_t ping2mm(uint16_t in) d >>= 1; // in >> 8 q += d; d >>= 5; // in >> 13 - q += d + 2; + q += d + 3; return q; } @@ -142,7 +202,7 @@ uint16_t ping2inch(uint16_t in) uint16_t q = d; d >>= 1; // in >> 8 q += d; - d >>= 2; // in >> 10; + d >>= 2; // in >> 10 q += d; d >>= 1; // in >> 11 q += d; @@ -153,6 +213,27 @@ uint16_t ping2inch(uint16_t in) return q; } +uint16_t ping2quarter(uint16_t in) +{ + // divide by 18.6764705875 == * 0.05354330709 + // uint16_t q = (in >> 5) + (in >> 6) + (in >> 8) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14) ; + uint16_t d = in >> 5; + uint16_t q = d; + d >>= 1; // in >> 6 + q += d; + d >>= 2; // in >> 8 + q += d; + d >>= 1; // in >> 9 + q += d; + d >>= 2; // in >> 11 + q += d; + d >>= 1; // in >> 12 + q += d; + d >>= 2; // in >> 14 + q += d + 3; // correction. + return q; +} + uint16_t ping2sixteenths(uint16_t in) { // divide by 4.669117646875 == * 0.214173228 @@ -161,7 +242,7 @@ uint16_t ping2sixteenths(uint16_t in) uint16_t q = d; d >>= 1; // in >> 4 q += d; - d >>= 2; // in >> 6; + d >>= 2; // in >> 6 q += d; d >>= 1; // in >> 7 q += d; @@ -172,15 +253,19 @@ uint16_t ping2sixteenths(uint16_t in) d >>= 2; // in >> 12 q += d; d >>= 2; // in >> 14 - q += d + 2; // correction. + q += d + 3; // correction. return q; } +///////////////////////////////////////////////////////////////////////////////////// + + uint32_t ping2cm32(uint32_t in) { // divide by 29.41176 == * 0.034 - // uint32_t q = (in >> 5) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14); + // uint32_t q = (in >> 5) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14) + // + (in >> 19) + (in >> 20) + (In >> 21) + (in >> 24) + (26, 28 29...; uint32_t d = in >> 5; uint32_t q = d; d >>= 4; // in >> 9 @@ -189,8 +274,22 @@ uint32_t ping2cm32(uint32_t in) q += d; d >>= 1; // in >> 12 q += d; - d >>= 2; // in >> 14 // TODO more decimals? + d >>= 2; // in >> 14 q += d; + d >>= 5; // in >> 19 + // q += d; + // d >>= 1; // in >> 20 + // q += d; + // d >>= 1; // in >> 21 + // q += d; + // d >>= 3; // in >> 24 + // q += d; + // d >>= 2; // in >> 26; + // q += d; + // d >>= 2; // in >> 28 + // q += d; + // d >>= 1; // in >> 29 + q += d + 3; // rounding correction return q; } @@ -199,22 +298,44 @@ uint32_t ping2mm32(uint32_t in) { // divide by 2.941176 == * 0.34; // uint32_t q = (in >> 2) + (in >> 4) + (in >> 6) + (in >> 7) + (in >> 8) + (in >> 13); + // 15, 19, 20, 21, 22, 24, 26, 27, 28 uint32_t d = in >> 2; uint32_t q = d; d >>= 2; // in >> 4 q += d; - d >>= 2; // in >> 6; + d >>= 2; // in >> 6 q += d; d >>= 1; // in >> 7 q += d; d >>= 1; // in >> 8 q += d; - d >>= 5; // in >> 13 // TODO more decimals? + d >>= 5; // in >> 13 q += d; + d >>= 2; // in >> 15 + q += d; + d >>= 4; // in >> 19 + // q += d; + // d >>= 1; // in >> 20 + // q += d; + // d >>= 1; // in >> 21 + // q += d; + // d >>= 1; // in >> 22 + // q += d; + // d >>= 2; // in >> 24 + // q += d; + // d >>= 2; // in >> 26 + // q += d; + // d >>= 1; // in >> 27 + // q += d; + // d >>= 1; // in >> 28 + q += d + 3; // rounding correction. return q; } +///////////////////////////////////////////////////////////////////////////////////// + + // temperature in Celsius float ping2cm_tempC(uint16_t duration, int Celsius ) { @@ -228,17 +349,26 @@ float ping2cm_tempC(uint16_t duration, int Celsius ) float ping2inch_tempC(uint16_t duration, int Celsius ) { - // - // return duration * 331.45 * sqrt(1 + temp / 273.0) / 10000; + // formula ping2cm_tempC converted + return duration * (0.013049 + Celsius * (0.013049 / 546.0)); +} + + +float ping2inch_tempF(uint16_t duration, int Fahrenheit ) +{ + // formula ping2inch_tempC converted // return duration * 331.45 * sqrt(1 + temp * (1.0 / 273.0)) * 0.0001; - // return duration * 331.45 * (1 + temp * (1.0 / 546.0)) * 0.0001; // little less accurate sqrt - return duration * (0.013049 + Celsius * (0.013049 / 546.0)); // minimized. + // inches + // return duration * 130.49 * (1 + temp * (1.0 / 546.0)) * 0.0001; // little less accurate sqrt + // Fahrenheit + // return duration * (0.013049 + (Fahrenheit - 32) * (5.0/9.0) * (0.013049 / 546.0)); + return duration * (0.013049 + (Fahrenheit - 32) * ((5.0/9.0) * (0.013049 / 546.0))); } /////////////////////////////////////////////////////////// // -// TODO +// TODO ... // diff --git a/libraries/fast_math/fast_math.h b/libraries/fast_math/fast_math.h index 6b4d8992..ce73bbe8 100644 --- a/libraries/fast_math/fast_math.h +++ b/libraries/fast_math/fast_math.h @@ -2,7 +2,7 @@ // // FILE: fast_math.h // AUTHOR: Rob Tillaart -// VERSION: 0.2.0 +// VERSION: 0.2.1 // PURPOSE: Arduino library for fast math algorithms // DATE: 27 October 2013 // URL: https://github.com/RobTillaart/fast_math @@ -16,7 +16,7 @@ #include "Arduino.h" #endif -#define FASTMATH_LIB_VERSION (F("0.2.0")) +#define FASTMATH_LIB_VERSION (F("0.2.1")) #ifdef __cplusplus @@ -28,12 +28,19 @@ extern "C" ////////////////////////////////////////////////////////////////////////// // // ROUTINE: divmod10 -// PURPOSE: fast routine that provides both /10 and %10 for integer math. +// PURPOSE: fast routine that provides both / 10 and % 10 for integer math. // URL: https://forum.arduino.cc/t/divmod10-a-fast-replacement-for-10-and-10-unsigned/163586 // AUTHORS: see URL // NOTE: assembler version for AVR exists (by Stimmer) - see URL // void divmod10(uint32_t in, uint32_t *div, uint8_t *mod); +void divmod3(uint32_t in, uint32_t *div, uint8_t *mod); +void divmod5(uint32_t in, uint32_t *div, uint8_t *mod); +// for clocks +void divmod12(uint32_t in, uint32_t *div, uint8_t *mod); +void divmod24(uint32_t in, uint32_t *div, uint8_t *mod); +void divmod60(uint32_t in, uint32_t *div, uint8_t *mod); + ////////////////////////////////////////////////////////////////////////// @@ -62,7 +69,7 @@ float polynome(float x, float ar[], uint8_t degree); ////////////////////////////////////////////////////////////////////////// // -// 16 BIT PING MATH - for distances up to ~20 meter +// 16 BIT PING MATH - for distances up to ~10 meter // ////////////////////////////////////////////////////////// // @@ -70,13 +77,16 @@ float polynome(float x, float ar[], uint8_t degree); // PURPOSE: fast routines to calculate the distance in cm / mm for a ping sensor // uint16_t ping2cm(uint16_t in); -uint16_t ping2mm(uint16_t in); +uint16_t ping2mm(uint16_t in); // smaller units are more accurate. + uint16_t ping2inch(uint16_t in); +uint16_t ping2quarter(uint16_t in); uint16_t ping2sixteenths(uint16_t in); + ////////////////////////////////////////////////////////// // -// 32 BIT PING MATH - for longer distances +// 32 BIT PING MATH - for distances > 10 meter (gaim ~10%) // uint32_t ping2cm32(uint32_t in); uint32_t ping2mm32(uint32_t in); @@ -85,7 +95,7 @@ uint32_t ping2mm32(uint32_t in); // temperature compensated speed of sound distance float ping2cm_tempC(uint16_t duration, int Celsius); float ping2inch_tempC(uint16_t duration, int Celsius); -// TODO ping2inch_tempF. +float ping2inch_tempF(uint16_t duration, int Fahrenheit); #ifdef __cplusplus diff --git a/libraries/fast_math/keywords.txt b/libraries/fast_math/keywords.txt index da2633c2..cf4efbe6 100644 --- a/libraries/fast_math/keywords.txt +++ b/libraries/fast_math/keywords.txt @@ -5,6 +5,12 @@ # Methods and Functions (KEYWORD2) divmod10 KEYWORD2 +divmod3 KEYWORD2 +divmod5 KEYWORD2 + +divmod12 KEYWORD2 +divmod24 KEYWORD2 +divmod60 KEYWORD2 dec2bcdRef KEYWORD2 dec2bcd KEYWORD2 @@ -16,7 +22,9 @@ polynome KEYWORD2 ping2cm KEYWORD2 ping2mm KEYWORD2 + ping2inch KEYWORD2 +ping2quarter KEYWORD2 ping2sixteenths KEYWORD2 ping2cm32 KEYWORD2 @@ -24,6 +32,7 @@ ping2mm32 KEYWORD2 ping2cm_tempC KEYWORD2 ping2inch_tempC KEYWORD2 +ping2inch_tempF KEYWORD2 # Constants (LITERAL1) diff --git a/libraries/fast_math/library.json b/libraries/fast_math/library.json index 85804f11..7f395351 100644 --- a/libraries/fast_math/library.json +++ b/libraries/fast_math/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/fast_math.git" }, - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "frameworks": "arduino", "platforms": "*", diff --git a/libraries/fast_math/library.properties b/libraries/fast_math/library.properties index 621cae55..dbb3a828 100644 --- a/libraries/fast_math/library.properties +++ b/libraries/fast_math/library.properties @@ -1,5 +1,5 @@ name=fast_math -version=0.2.0 +version=0.2.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for fast math algorithms