0.2.1 fast_math

This commit is contained in:
rob tillaart 2022-12-26 10:01:34 +01:00
parent dd4a0dbe71
commit a1971acf79
26 changed files with 1416 additions and 96 deletions

View File

@ -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/). 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 ## [0.2.0] - 2022-10-29
- initial release as library - initial release as library
- add examples - add examples

View File

@ -53,10 +53,10 @@ Backgrounder - https://forum.arduino.cc/t/faster-dec2bcd-routine-especial-for-rt
Indicative performance Arduino UNO. Indicative performance Arduino UNO.
| function | us | factor | notes | | function | us | factor | notes |
|:----------------|:------:|:-------:|:-------:| |:----------------|:------:|:-------:|:--------|
| dec2bcd (ref) | 5.88 | 1.0 | 100 iterations | dec2bcd (ref) | 5.88 | 1.0 | 100 iterations
| dec2bcd | 1.04 | 4.8 | | 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 (ref) | 5.96 | 1.0 |
| bcd2dec | 2.20 | 2.7 | | bcd2dec | 2.20 | 2.7 |
@ -65,22 +65,39 @@ Indicative performance Arduino UNO.
### DIV ### DIV
- **void divmod10(uint32_t in, uint32_t \*div, uint8_t \*mod)** - **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. The divmod10() 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. Typical use is to print digits on a display, in a file or send them as ASCII over a network.
Indicative performance Arduino UNO. Indicative performance Arduino UNO.
| function | us | factor | notes | | function | us | factor | notes |
|:-----------|:------:|:-------:|:-------:| |:-----------|:------:|:-------:|:--------|
| i % 10 | 38.2 | 1.0 | | i % 10 | 38.2 | 1.0 |
| i / 10 | 38.1 | 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 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 ### PING
@ -102,34 +119,55 @@ The functions assume a speed of sound of 340 m/sec.
16 bit interface 16 bit interface
- **uint16_t ping2cm(uint16_t in)** - **uint16_t ping2cm(uint16_t in)**
- **uint16_t ping2mm(uint16_t in)** - **uint16_t ping2mm(uint16_t in)**
- **uint16_t ping2inch(uint16_t in)**
- **uint16_t ping2sixteenths(uint16_t in)**
32 bit interface 32 bit interface
- **uint32_t ping2cm32(uint32_t in)** - **uint32_t ping2cm32(uint32_t in)** for lengths > 10 meter
- **uint32_t ping2mm32(uint32_t in)** - **uint32_t ping2mm32(uint32_t in)** for lengths > 10 meter
Performance wise the 32 bit versions have a gain ~10%.
Imperial
#### temperature corrected - **uint16_t ping2inch(uint16_t in)**
- **uint16_t ping2quarter(uint16_t in)**
- **float ping2cm_tempC(uint16_t duration, int Celsius)** temperature corrected speed of sound. - **uint16_t ping2sixteenths(uint16_t in)**
- 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.
Indicative performance Arduino UNO. Indicative performance Arduino UNO.
| function | us | factor | notes | | function | us | factor | notes |
|:------------------|:------:|:-------:|:-------:| |:------------------|:------:|:-------:|:--------|
| us / 29 (ref) | 38.1 | 1.0 | sos == 345 m/s (integer only) | us / 29 (ref) | 38.3 | 1.0 | sos == 345 m/s (integer only)
| us \* 0.0345 | 18.5 | 2.0 | | us \* 0.0345 | 18.5 | 2.0 | sos == 345 m/s
| ping2cm | 3.08 | 12.4 | sos == 340 m/s | ping2cm | 3.08 | 12.4 | sos == 340 m/s
| ping2mm | 5.66 | 6.7 | 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 | ping2inch | 4.34 | 8.8 | not precise as inches are rather large units
| ping2sixteenths | 8.11 | 4.8 | way more accurate than inches | 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 ### polynome
@ -158,33 +196,31 @@ can be tuned (runtime).
- unit tests - unit tests
- or examples that test a lot. - or examples that test a lot.
- examples - examples
- check output examples.
- keep investigating faster versions.
- divmod performance table other versions
#### could #### could
- split up in multiple .h files, one per group. - split up in multiple .h files, one per group.
- fast_math.h includes all individual .h files. - fast_math.h includes all individual .h files.
- There are several divide functions to be included. - There are several divide functions to be included?
div3(), div5(), div7(), div10(), mod10() div3(), div5(), div7(), div10() depends on application.
These need more testing (range) These need more testing (range)
- constants? - constants?
- GOLDEN_RATIO 1.61803398875 - GOLDEN_RATIO 1.61803398875
- check temperature corrected float?
#### TODO Functions #### TODO Functions
DIV DIV
- **uint16_t divmod10()** 16 bit overload version - **uint16_t divmod10()** 16 bit overload version ?
- **uint32_t div10(x, \*d)** would be a bit faster - **uint32_t div10(x, \*d)** would be a bit faster than divmod10()
- **uint32_t mod10(x, \*m)** would be a bit faster too - **uint32_t mod10(x, \*m)** would be a bit faster too
- clock - **div7()** days - weeks.
- **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)**
BCD
- **uint16_t dec2bcd()** + 32 bit + back?

View File

@ -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...

View File

@ -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...

View File

@ -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 --

View File

@ -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...

View File

@ -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 --

View File

@ -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...

View File

@ -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...

View File

@ -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 --

View File

@ -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...

View File

@ -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...

View File

@ -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 --

View File

@ -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...

View File

@ -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 --

View File

@ -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

View File

@ -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 --

View File

@ -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

View File

@ -57,8 +57,31 @@ void setup()
Serial.println((stop - start) / 10000.0, 4); Serial.println((stop - start) / 10000.0, 4);
delay(100); delay(100);
Serial.println("\nverify I"); Serial.print("ping2cm32\t");
for (uint16_t i = 0; i < 200; i += 10) 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(i);
Serial.print("\t"); Serial.print("\t");
@ -73,47 +96,26 @@ void setup()
Serial.print(ping2mm(i)); Serial.print(ping2mm(i));
Serial.print("\t"); Serial.print("\t");
Serial.print((1.0 * ping2mm(i)) / (i * 0.34) ); Serial.print((1.0 * ping2mm(i)) / (i * 0.34) );
Serial.print("\t");
Serial.println(); 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"); Serial.println("\nverify - 32 bit - up to 100 meter");
for (uint16_t i = 1000; i <= 10000; i += 500) for (uint32_t i = 100; i <= 300000; i *= 1.1)
{ {
Serial.print(i); Serial.print(i);
Serial.print("\t"); Serial.print("\t");
Serial.print(i * 0.034, 1); Serial.print(i * 0.034, 1);
Serial.print("\t"); Serial.print("\t");
Serial.print(ping2cm(i)); Serial.print(ping2cm32(i));
Serial.print("\t"); 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("\t\t");
Serial.print(i * 0.34, 1); Serial.print(i * 0.34, 1);
Serial.print("\t"); Serial.print("\t");
Serial.print(ping2mm(i)); Serial.print(ping2mm32(i));
Serial.print("\t");
Serial.print((1.0 * ping2mm(i)) / (i * 0.34) );
Serial.print("\t"); Serial.print("\t");
Serial.print((1.0 * ping2mm32(i)) / (i * 0.34) );
Serial.println(); Serial.println();
} }

View File

@ -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

View File

@ -48,6 +48,30 @@ void setup()
delay(10); 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"); Serial.print("ping2sixteenths ref\t");
delay(10); delay(10);
start = micros(); start = micros();
@ -84,6 +108,12 @@ void setup()
Serial.print("\t"); Serial.print("\t");
Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 );
Serial.print("\t\t"); 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(i / 4.669117646875, 0);
Serial.print("\t"); Serial.print("\t");
Serial.print(ping2sixteenths(i)); Serial.print(ping2sixteenths(i));
@ -94,7 +124,7 @@ void setup()
} }
Serial.println("\nverify II"); 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(i);
Serial.print("\t"); Serial.print("\t");
@ -105,6 +135,12 @@ void setup()
Serial.print("\t"); Serial.print("\t");
Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 );
Serial.print("\t\t"); 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(i / 4.669117646875, 0);
Serial.print("\t"); Serial.print("\t");
Serial.print(ping2sixteenths(i)); Serial.print(ping2sixteenths(i));
@ -115,7 +151,7 @@ void setup()
} }
Serial.println("\nverify III"); 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(i);
Serial.print("\t"); Serial.print("\t");
@ -126,6 +162,12 @@ void setup()
Serial.print("\t"); Serial.print("\t");
Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 );
Serial.print("\t\t"); 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(i / 4.669117646875, 0);
Serial.print("\t"); Serial.print("\t");
Serial.print(ping2sixteenths(i)); Serial.print(ping2sixteenths(i));

View File

@ -1,7 +1,7 @@
// //
// FILE: fast_math.cpp // FILE: fast_math.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.0 // VERSION: 0.2.1
// PURPOSE: Arduino library for fast math algorithms // PURPOSE: Arduino library for fast math algorithms
// DATE: 27 October 2013 // DATE: 27 October 2013
// URL: https://github.com/RobTillaart/fast_math // 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 // BCD
@ -111,7 +171,7 @@ uint16_t ping2cm(uint16_t in)
d >>= 1; // in >> 12 d >>= 1; // in >> 12
q += d; q += d;
d >>= 2; // in >> 14 d >>= 2; // in >> 14
q += d + 1; q += d + 2;
return q; return q;
} }
@ -130,7 +190,7 @@ uint16_t ping2mm(uint16_t in)
d >>= 1; // in >> 8 d >>= 1; // in >> 8
q += d; q += d;
d >>= 5; // in >> 13 d >>= 5; // in >> 13
q += d + 2; q += d + 3;
return q; return q;
} }
@ -142,7 +202,7 @@ uint16_t ping2inch(uint16_t in)
uint16_t q = d; uint16_t q = d;
d >>= 1; // in >> 8 d >>= 1; // in >> 8
q += d; q += d;
d >>= 2; // in >> 10; d >>= 2; // in >> 10
q += d; q += d;
d >>= 1; // in >> 11 d >>= 1; // in >> 11
q += d; q += d;
@ -153,6 +213,27 @@ uint16_t ping2inch(uint16_t in)
return q; 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) uint16_t ping2sixteenths(uint16_t in)
{ {
// divide by 4.669117646875 == * 0.214173228 // divide by 4.669117646875 == * 0.214173228
@ -161,7 +242,7 @@ uint16_t ping2sixteenths(uint16_t in)
uint16_t q = d; uint16_t q = d;
d >>= 1; // in >> 4 d >>= 1; // in >> 4
q += d; q += d;
d >>= 2; // in >> 6; d >>= 2; // in >> 6
q += d; q += d;
d >>= 1; // in >> 7 d >>= 1; // in >> 7
q += d; q += d;
@ -172,15 +253,19 @@ uint16_t ping2sixteenths(uint16_t in)
d >>= 2; // in >> 12 d >>= 2; // in >> 12
q += d; q += d;
d >>= 2; // in >> 14 d >>= 2; // in >> 14
q += d + 2; // correction. q += d + 3; // correction.
return q; return q;
} }
/////////////////////////////////////////////////////////////////////////////////////
uint32_t ping2cm32(uint32_t in) uint32_t ping2cm32(uint32_t in)
{ {
// divide by 29.41176 == * 0.034 // 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 d = in >> 5;
uint32_t q = d; uint32_t q = d;
d >>= 4; // in >> 9 d >>= 4; // in >> 9
@ -189,8 +274,22 @@ uint32_t ping2cm32(uint32_t in)
q += d; q += d;
d >>= 1; // in >> 12 d >>= 1; // in >> 12
q += d; q += d;
d >>= 2; // in >> 14 // TODO more decimals? d >>= 2; // in >> 14
q += d; 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; return q;
} }
@ -199,22 +298,44 @@ uint32_t ping2mm32(uint32_t in)
{ {
// divide by 2.941176 == * 0.34; // divide by 2.941176 == * 0.34;
// uint32_t q = (in >> 2) + (in >> 4) + (in >> 6) + (in >> 7) + (in >> 8) + (in >> 13); // 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 d = in >> 2;
uint32_t q = d; uint32_t q = d;
d >>= 2; // in >> 4 d >>= 2; // in >> 4
q += d; q += d;
d >>= 2; // in >> 6; d >>= 2; // in >> 6
q += d; q += d;
d >>= 1; // in >> 7 d >>= 1; // in >> 7
q += d; q += d;
d >>= 1; // in >> 8 d >>= 1; // in >> 8
q += d; q += d;
d >>= 5; // in >> 13 // TODO more decimals? d >>= 5; // in >> 13
q += d; 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; return q;
} }
/////////////////////////////////////////////////////////////////////////////////////
// temperature in Celsius // temperature in Celsius
float ping2cm_tempC(uint16_t duration, int 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 ) float ping2inch_tempC(uint16_t duration, int Celsius )
{ {
// // formula ping2cm_tempC converted
// return duration * 331.45 * sqrt(1 + temp / 273.0) / 10000; 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 * 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 // inches
return duration * (0.013049 + Celsius * (0.013049 / 546.0)); // minimized. // 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 ...
// //

View File

@ -2,7 +2,7 @@
// //
// FILE: fast_math.h // FILE: fast_math.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.2.0 // VERSION: 0.2.1
// PURPOSE: Arduino library for fast math algorithms // PURPOSE: Arduino library for fast math algorithms
// DATE: 27 October 2013 // DATE: 27 October 2013
// URL: https://github.com/RobTillaart/fast_math // URL: https://github.com/RobTillaart/fast_math
@ -16,7 +16,7 @@
#include "Arduino.h" #include "Arduino.h"
#endif #endif
#define FASTMATH_LIB_VERSION (F("0.2.0")) #define FASTMATH_LIB_VERSION (F("0.2.1"))
#ifdef __cplusplus #ifdef __cplusplus
@ -34,6 +34,13 @@ extern "C"
// NOTE: assembler version for AVR exists (by Stimmer) - see URL // NOTE: assembler version for AVR exists (by Stimmer) - see URL
// //
void divmod10(uint32_t in, uint32_t *div, uint8_t *mod); 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 // PURPOSE: fast routines to calculate the distance in cm / mm for a ping sensor
// //
uint16_t ping2cm(uint16_t in); 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 ping2inch(uint16_t in);
uint16_t ping2quarter(uint16_t in);
uint16_t ping2sixteenths(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 ping2cm32(uint32_t in);
uint32_t ping2mm32(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 // temperature compensated speed of sound distance
float ping2cm_tempC(uint16_t duration, int Celsius); float ping2cm_tempC(uint16_t duration, int Celsius);
float ping2inch_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 #ifdef __cplusplus

View File

@ -5,6 +5,12 @@
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
divmod10 KEYWORD2 divmod10 KEYWORD2
divmod3 KEYWORD2
divmod5 KEYWORD2
divmod12 KEYWORD2
divmod24 KEYWORD2
divmod60 KEYWORD2
dec2bcdRef KEYWORD2 dec2bcdRef KEYWORD2
dec2bcd KEYWORD2 dec2bcd KEYWORD2
@ -16,7 +22,9 @@ polynome KEYWORD2
ping2cm KEYWORD2 ping2cm KEYWORD2
ping2mm KEYWORD2 ping2mm KEYWORD2
ping2inch KEYWORD2 ping2inch KEYWORD2
ping2quarter KEYWORD2
ping2sixteenths KEYWORD2 ping2sixteenths KEYWORD2
ping2cm32 KEYWORD2 ping2cm32 KEYWORD2
@ -24,6 +32,7 @@ ping2mm32 KEYWORD2
ping2cm_tempC KEYWORD2 ping2cm_tempC KEYWORD2
ping2inch_tempC KEYWORD2 ping2inch_tempC KEYWORD2
ping2inch_tempF KEYWORD2
# Constants (LITERAL1) # Constants (LITERAL1)

View File

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

View File

@ -1,5 +1,5 @@
name=fast_math name=fast_math
version=0.2.0 version=0.2.1
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for fast math algorithms sentence=Arduino library for fast math algorithms