├── .github ├── FUNDING.yml └── workflows │ ├── arduino-lint.yml │ ├── jsoncheck.yml │ └── arduino_test_runner.yml ├── examples ├── bcd_performance │ ├── output_0.2.0.txt │ └── bcd_performance.ino ├── divmod5_performance │ ├── divmod5_0.2.0.txt │ ├── divmod5_0.2.1.txt │ └── divmod5_performance.ino ├── divmod12_performance │ ├── divmod12_0.2.0.txt │ ├── divmod12_0.2.1.txt │ └── divmod12_performance.ino ├── divmod24_performance │ ├── divmod24_0.2.1.txt │ └── divmod24_performance.ino ├── divmod60_performance │ ├── divmod60_0.2.1.txt │ └── divmod60_performance.ino ├── divmod3_performance │ ├── divmod3_0.2.0.txt │ ├── divmod3_0.2.1.txt │ └── divmod3_performance.ino ├── log10_performance │ ├── log10_0.2.4.txt │ └── log10_performance.ino ├── ping2inch │ ├── performance_0.2.0.txt │ ├── performance_0.2.1.txt │ └── ping2inch.ino ├── divmod10_performance │ └── divmod10_performance.ino ├── ping2cm │ ├── performance_0.2.0.txt │ ├── ping2cm.ino │ └── performance_0.2.1.txt ├── ping2_temp_compensated │ ├── performance_0.2.1.txt │ └── ping2_temp_compensated.ino └── polynome │ ├── polynome.ino │ └── output_0.2.0.txt ├── library.properties ├── library.json ├── .arduino-ci.yml ├── keywords.txt ├── CHANGELOG.md ├── test └── unit_test_001.cpp ├── LICENSE ├── fast_math.h ├── README.md └── fast_math.cpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: RobTillaart 4 | custom: "https://www.paypal.me/robtillaart" 5 | -------------------------------------------------------------------------------- /examples/bcd_performance/output_0.2.0.txt: -------------------------------------------------------------------------------- 1 | UNO 1.8.19 2 | 3 | bcd_performance.ino 4 | FASTMATH_LIB_VERSION: 0.2.0 5 | 6 | dec2bcdRef: 592 153 7 | dec2bcd: 116 153 8 | dec2bcdRTC: 88 159 9 | bcd2dec: 220 63 10 | 11 | compare bcd2dec <-> dec2bcd (0..100) 12 | 320 153 13 | compare bcd2dec <-> dec2bcdRTC (0..60) 14 | 228 89 15 | 16 | done... 17 | -------------------------------------------------------------------------------- /.github/workflows/arduino-lint.yml: -------------------------------------------------------------------------------- 1 | name: Arduino-lint 2 | 3 | on: [push, pull_request] 4 | jobs: 5 | lint: 6 | runs-on: ubuntu-latest 7 | timeout-minutes: 5 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: arduino/arduino-lint-action@v1 11 | with: 12 | library-manager: update 13 | compliance: strict -------------------------------------------------------------------------------- /examples/divmod5_performance/divmod5_0.2.0.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod5_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.0 6 | 7 | div + mod: 40 16807 3361 2 8 | divmod5: 20 16807 3361 2 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 60581680 23 | done... 24 | -------------------------------------------------------------------------------- /examples/divmod5_performance/divmod5_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod5_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.1 6 | 7 | div + mod: 40 16807 3361 2 8 | divmod5: 20 16807 3361 2 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 58506880 23 | done... 24 | -------------------------------------------------------------------------------- /examples/divmod12_performance/divmod12_0.2.0.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod12_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.0 6 | 7 | div + mod: 48 16807 1400 7 8 | divmod12: 24 16807 1400 7 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 61147540 23 | done... 24 | -------------------------------------------------------------------------------- /examples/divmod12_performance/divmod12_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod12_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.1 6 | 7 | div + mod: 48 16807 1400 7 8 | divmod12: 24 16807 1400 7 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 61147540 23 | done... 24 | -------------------------------------------------------------------------------- /examples/divmod24_performance/divmod24_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod24_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.1 6 | 7 | div + mod: 48 16807 700 7 8 | divmod24: 24 16807 700 7 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 61587648 23 | done... 24 | -------------------------------------------------------------------------------- /examples/divmod60_performance/divmod60_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod60_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.1 6 | 7 | div + mod: 48 16807 280 7 8 | divmod60: 12 16807 280 7 9 | 10 | Test 0 .. 1 million (1 minute UNO) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 52168832 23 | done... 24 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=fast_math 2 | version=0.2.4 3 | author=Rob Tillaart 4 | maintainer=Rob Tillaart 5 | sentence=Arduino library for fast math algorithms 6 | paragraph=divmod10,bcd2dec,dec2bcd,ping,log10,log2,log 7 | category=Data Processing 8 | url=https://github.com/RobTillaart/fast_math 9 | architectures=* 10 | includes=fast_math.h 11 | depends= 12 | -------------------------------------------------------------------------------- /.github/workflows/jsoncheck.yml: -------------------------------------------------------------------------------- 1 | name: JSON check 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**.json' 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | timeout-minutes: 5 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: json-syntax-check 16 | uses: limitusus/json-syntax-check@v2 17 | with: 18 | pattern: "\\.json$" -------------------------------------------------------------------------------- /examples/divmod3_performance/divmod3_0.2.0.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod3_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.0 6 | 7 | div + mod: 44 16807 5602 1 8 | divmod3: 24 16807 5602 1 9 | 10 | Test 0 .. 1 million (1 minute UNO, < 1second ESP32) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 61210540 23 | done... 24 | -------------------------------------------------------------------------------- /.github/workflows/arduino_test_runner.yml: -------------------------------------------------------------------------------- 1 | name: Arduino CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | runTest: 7 | runs-on: ubuntu-latest 8 | timeout-minutes: 20 9 | 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: ruby/setup-ruby@v1 13 | with: 14 | ruby-version: 2.6 15 | - run: | 16 | gem install arduino_ci 17 | arduino_ci.rb 18 | -------------------------------------------------------------------------------- /examples/divmod3_performance/divmod3_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | divmod3_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.1 6 | 7 | div + mod: 44 16807 5602 1 8 | divmod3: 20 16807 5602 1 9 | 10 | Test 0 .. 1 million (1 minute UNO, < 1second ESP32) 11 | 0 12 | 100000 13 | 200000 14 | 300000 15 | 400000 16 | 500000 17 | 600000 18 | 700000 19 | 800000 20 | 900000 21 | 1000000 22 | 58255512 23 | done... 24 | 25 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fast_math", 3 | "keywords": "divmod10,bcd2dec,dec2bcd,ping,log10,log2,log", 4 | "description": "Arduino library for fast math algorithms.", 5 | "authors": 6 | [ 7 | { 8 | "name": "Rob Tillaart", 9 | "email": "Rob.Tillaart@gmail.com", 10 | "maintainer": true 11 | } 12 | ], 13 | "repository": 14 | { 15 | "type": "git", 16 | "url": "https://github.com/RobTillaart/fast_math.git" 17 | }, 18 | "version": "0.2.4", 19 | "license": "MIT", 20 | "frameworks": "*", 21 | "platforms": "*", 22 | "headers": "fast_math.h" 23 | } 24 | -------------------------------------------------------------------------------- /.arduino-ci.yml: -------------------------------------------------------------------------------- 1 | platforms: 2 | rpipico: 3 | board: rp2040:rp2040:rpipico 4 | package: rp2040:rp2040 5 | gcc: 6 | features: 7 | defines: 8 | - ARDUINO_ARCH_RP2040 9 | warnings: 10 | flags: 11 | 12 | packages: 13 | rp2040:rp2040: 14 | url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json 15 | 16 | compile: 17 | # Choosing to run compilation tests on 2 different Arduino platforms 18 | platforms: 19 | - uno 20 | # - due 21 | # - zero 22 | # - leonardo 23 | - m4 24 | - esp32 25 | # - esp8266 26 | # - mega2560 27 | - rpipico 28 | -------------------------------------------------------------------------------- /examples/log10_performance/log10_0.2.4.txt: -------------------------------------------------------------------------------- 1 | BOARD: UNO 2 | IDE: 1.8.19 3 | 4 | log10_performance.ino 5 | FASTMATH_LIB_VERSION: 0.2.4 6 | 7 | Function time X Y 8 | 9 | log2: 220 16.807 4.070990 10 | fast2: 68 16.807 4.071197 11 | log10: 168 16.807 1.225490 12 | fast10: 80 16.807 1.225552 13 | log: 160 16.807 2.821795 14 | fastLog: 80 16.807 2.821939 15 | 16 | done... 17 | 18 | ================================ 19 | 20 | BOARD: ESP32 21 | IDE: 1.8.19 22 | 23 | log10_performance.ino 24 | FASTMATH_LIB_VERSION: 0.2.4 25 | 26 | Function time X Y 27 | 28 | log2: 74 884.537 9.788778 29 | fast2: 14 884.537 9.788513 30 | log10: 16 884.537 2.946716 31 | fast10: 6 884.537 2.946636 32 | log: 16 884.537 6.785064 33 | fastLog: 5 884.537 6.784880 34 | 35 | done... 36 | 37 | 38 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | # Syntax Colouring Map For fast_math 2 | 3 | # Data types (KEYWORD1) 4 | 5 | 6 | # Methods and Functions (KEYWORD2) 7 | divmod10 KEYWORD2 8 | divmod3 KEYWORD2 9 | divmod5 KEYWORD2 10 | 11 | divmod12 KEYWORD2 12 | divmod24 KEYWORD2 13 | divmod60 KEYWORD2 14 | 15 | dec2bcdRef KEYWORD2 16 | dec2bcd KEYWORD2 17 | dec2bcdRTC KEYWORD2 18 | bcd2decRef KEYWORD2 19 | bcd2dec KEYWORD2 20 | 21 | polynome KEYWORD2 22 | 23 | ping2cm KEYWORD2 24 | ping2mm KEYWORD2 25 | 26 | ping2inch KEYWORD2 27 | ping2quarter KEYWORD2 28 | ping2sixteenths KEYWORD2 29 | 30 | ping2cm32 KEYWORD2 31 | ping2mm32 KEYWORD2 32 | 33 | ping2cm_tempC KEYWORD2 34 | ping2inch_tempC KEYWORD2 35 | ping2inch_tempF KEYWORD2 36 | 37 | fastLog2 KEYWORD2 38 | fastLog10 KEYWORD2 39 | fastLog KEYWORD2 40 | 41 | 42 | # Constants (LITERAL1) 43 | FASTMATH_LIB_VERSION LITERAL1 44 | 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log fast_math 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | 9 | ## [0.2.4] - 2025-03-25 10 | - add fastLog2(), fastLog10(), fastLog() 11 | - add example 12 | - update readme.md 13 | - minor edits 14 | 15 | 16 | ## [0.2.3] - 2024-01-03 17 | - fix typos examples 18 | - minor edits 19 | 20 | ## [0.2.2] - 2023-10-26 21 | - update readme.md 22 | 23 | ## [0.2.1] - 2022-12-25 24 | - add divmod3() 25 | - add divmod5() 26 | - add divmod12(), divmod24(), divmod60() - time related. 27 | - update ping2cm(), ping2mm() 28 | - update ping2cm32(), ping2mm32() 29 | - add ping2quarter(); 30 | - add ping2inch_tempF(duration, Fahrenheit); 31 | 32 | 33 | ## [0.2.0] - 2022-10-29 34 | - initial release as library 35 | - add examples 36 | - redo a lot of testing 37 | - add readme.md 38 | - renamed to fast_math (ESP32 conflict) 39 | 40 | ---- 41 | 42 | ## [0.1.0] - 27 October 2013 43 | - initial version fastMath 44 | -------------------------------------------------------------------------------- /test/unit_test_001.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: unit_test_001.cpp 3 | // AUTHOR: Rob Tillaart 4 | // DATE: 2022-11-29 5 | // PURPOSE: unit tests for the fast_math library 6 | // https://github.com/RobTillaart/fast_math 7 | // https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md 8 | // 9 | 10 | // supported assertions 11 | // ---------------------------- 12 | // assertEqual(expected, actual) 13 | // assertNotEqual(expected, actual) 14 | // assertLess(expected, actual) 15 | // assertMore(expected, actual) 16 | // assertLessOrEqual(expected, actual) 17 | // assertMoreOrEqual(expected, actual) 18 | // assertTrue(actual) 19 | // assertFalse(actual) 20 | // assertNull(actual) 21 | 22 | 23 | #include 24 | 25 | #include "Arduino.h" 26 | #include "fast_math.h" 27 | 28 | 29 | unittest_setup() 30 | { 31 | fprintf(stderr, "FASTMATH_LIB_VERSION: %s\n", (char *) FASTMATH_LIB_VERSION); 32 | } 33 | 34 | unittest_teardown() 35 | { 36 | } 37 | 38 | 39 | unittest(test_I) 40 | { 41 | assertEqual(1, 1); 42 | } 43 | 44 | 45 | unittest_main() 46 | 47 | 48 | // -- END OF FILE -- 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2025 Rob Tillaart 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/ping2inch/performance_0.2.0.txt: -------------------------------------------------------------------------------- 1 | FASTMATH_LIB_VERSION: 0.2.0 2 | 3 | ping2inch ref 38.1696 4 | ping2inch fast 3.7728 5 | ping2sixteenths ref 38.9052 6 | ping2sixteenths fast 7.9852 7 | 8 | verify I 9 | 0 0.0 2 inf 0 2 inf 10 | 10 0.1 2 14.94 2 3 1.40 11 | 20 0.3 2 7.47 4 5 1.17 12 | 30 0.4 2 4.98 6 6 0.93 13 | 40 0.5 2 3.74 9 9 1.05 14 | 50 0.7 2 2.99 11 11 1.03 15 | 60 0.8 2 2.49 13 12 0.93 16 | 70 0.9 2 2.13 15 15 1.00 17 | 80 1.1 2 1.87 17 18 1.05 18 | 90 1.2 2 1.66 19 19 0.99 19 | 100 1.3 2 1.49 21 21 0.98 20 | 110 1.5 2 1.36 24 22 0.93 21 | 120 1.6 2 1.25 26 25 0.97 22 | 130 1.7 3 1.72 28 29 1.04 23 | 140 1.9 3 1.60 30 30 1.00 24 | 150 2.0 3 1.49 32 32 1.00 25 | 160 2.1 3 1.40 34 35 1.02 26 | 170 2.3 3 1.32 36 36 0.99 27 | 180 2.4 3 1.25 39 38 0.99 28 | 190 2.5 3 1.18 41 39 0.96 29 | 30 | verify II 31 | 200 2.7 3 1.12 43 43 1.00 32 | 300 4.0 5 1.25 64 63 0.98 33 | 400 5.4 6 1.12 86 86 1.00 34 | 500 6.7 6 0.90 107 105 0.98 35 | 600 8.0 8 1.00 129 128 1.00 36 | 700 9.4 9 0.96 150 148 0.99 37 | 800 10.7 11 1.03 171 171 1.00 38 | 900 12.0 12 1.00 193 192 1.00 39 | 40 | verify III 41 | 1000 13.4 12 0.90 214 212 0.99 42 | 2000 26.8 25 0.93 428 427 1.00 43 | 3000 40.2 39 0.97 643 640 1.00 44 | 4000 53.5 52 0.97 857 855 1.00 45 | 5000 66.9 66 0.99 1071 1070 1.00 46 | 6000 80.3 78 0.97 1285 1283 1.00 47 | 7000 93.7 92 0.98 1499 1497 1.00 48 | 8000 107.1 105 0.98 1713 1712 1.00 49 | 9000 120.5 120 1.00 1928 1926 1.00 50 | 10000 133.9 133 0.99 2142 2141 1.00 51 | -------------------------------------------------------------------------------- /examples/divmod5_performance/divmod5_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod5_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod5 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 5; 30 | m = x % 5; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod5(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod5: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod5(x, &d, &m); 65 | if ( (x != d*5 +m) || (m > 4)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/divmod12_performance/divmod12_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod12_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod12 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 12; 30 | m = x % 12; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod12(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod12: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod12(x, &d, &m); 65 | if ( (x != d*12 +m) || (m > 11)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/divmod24_performance/divmod24_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod24_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod24 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 24; 30 | m = x % 24; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod24(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod24: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod24(x, &d, &m); 65 | if ( (x != d*24 +m) || (m > 23)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/divmod60_performance/divmod60_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod60_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod60 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 60; 30 | m = x % 60; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod60(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod60: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod60(x, &d, &m); 65 | if ( (x != d*60 +m) || (m > 59)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/divmod10_performance/divmod10_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod10_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod10 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 10; 30 | m = x % 10; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod10(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod10: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO, < 1second ESP32)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod10(x, &d, &m); 65 | if (x != (d * 10 + m)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/divmod3_performance/divmod3_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: divmod3_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: divmod3 performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | uint32_t x, d; 14 | uint8_t m; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(1000); 26 | 27 | x = random(2000000000ULL); 28 | start = micros(); 29 | d = x / 3; 30 | m = x % 3; 31 | stop = micros(); 32 | Serial.print("div + mod: "); 33 | Serial.print("\t"); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(x); 37 | Serial.print("\t"); 38 | Serial.print(d); 39 | Serial.print("\t"); 40 | Serial.print(m); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | divmod3(x, &d, &m); 46 | stop = micros(); 47 | Serial.print("divmod3: "); 48 | Serial.print("\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x); 52 | Serial.print("\t"); 53 | Serial.print(d); 54 | Serial.print("\t"); 55 | Serial.print(m); 56 | Serial.print("\n"); 57 | delay(100); 58 | 59 | Serial.println("\nTest 0 .. 1 million (1 minute UNO, < 1second ESP32)"); 60 | start = micros(); 61 | for (uint32_t x = 0; x <= 1000000; x++) 62 | { 63 | if (x % 100000 == 0) Serial.println(x); 64 | divmod3(x, &d, &m); 65 | if ( (x != d*3 +m) || (m > 2)) 66 | { 67 | Serial.print(x); 68 | Serial.print("\t"); 69 | Serial.print(d); 70 | Serial.print("\t"); 71 | Serial.print(m); 72 | Serial.print("\n"); 73 | } 74 | } 75 | stop = micros(); 76 | Serial.print(stop - start); 77 | Serial.print("\n"); 78 | 79 | Serial.println("done..."); 80 | } 81 | 82 | 83 | void loop() 84 | { 85 | } 86 | 87 | 88 | // -- END OF FILE -- 89 | -------------------------------------------------------------------------------- /examples/ping2cm/performance_0.2.0.txt: -------------------------------------------------------------------------------- 1 | FASTMATH_LIB_VERSION: 0.2.0 2 | 3 | pingRef 38.0260 4 | ping2cm 4.6528 5 | ping2mm 6.7912 6 | 7 | verify I 8 | 0 0.0 1 inf 0.0 2 inf 9 | 10 0.3 1 2.94 3.4 4 1.18 10 | 20 0.7 1 1.47 6.8 8 1.18 11 | 30 1.0 1 0.98 10.2 10 0.98 12 | 40 1.4 2 1.47 13.6 14 1.03 13 | 50 1.7 2 1.18 17.0 17 1.00 14 | 60 2.0 2 0.98 20.4 20 0.98 15 | 70 2.4 3 1.26 23.8 24 1.01 16 | 80 2.7 3 1.10 27.2 28 1.03 17 | 90 3.1 3 0.98 30.6 30 0.98 18 | 100 3.4 4 1.18 34.0 34 1.00 19 | 110 3.7 4 1.07 37.4 36 0.96 20 | 120 4.1 4 0.98 40.8 40 0.98 21 | 130 4.4 5 1.13 44.2 45 1.02 22 | 140 4.8 5 1.05 47.6 48 1.01 23 | 150 5.1 5 0.98 51.0 51 1.00 24 | 160 5.4 6 1.10 54.4 55 1.01 25 | 170 5.8 6 1.04 57.8 57 0.99 26 | 180 6.1 6 0.98 61.2 61 1.00 27 | 190 6.5 6 0.93 64.6 63 0.98 28 | 29 | verify II 30 | 200 6.8 7 1.03 68.0 68 1.00 31 | 250 8.5 8 0.94 85.0 83 0.98 32 | 300 10.2 10 0.98 102.0 102 1.00 33 | 350 11.9 11 0.92 119.0 118 0.99 34 | 400 13.6 13 0.96 136.0 137 1.01 35 | 450 15.3 15 0.98 153.0 153 1.00 36 | 500 17.0 16 0.94 170.0 169 0.99 37 | 550 18.7 19 1.02 187.0 187 1.00 38 | 600 20.4 20 0.98 204.0 204 1.00 39 | 650 22.1 22 1.00 221.0 221 1.00 40 | 700 23.8 23 0.97 238.0 237 1.00 41 | 750 25.5 25 0.98 255.0 253 0.99 42 | 800 27.2 27 0.99 272.0 273 1.00 43 | 850 28.9 28 0.97 289.0 289 1.00 44 | 900 30.6 30 0.98 306.0 307 1.00 45 | 950 32.3 31 0.96 323.0 322 1.00 46 | 47 | verify III 48 | 1000 34.0 33 0.97 340.0 339 1.00 49 | 1500 51.0 49 0.96 510.0 509 1.00 50 | 2000 68.0 66 0.97 680.0 680 1.00 51 | 2500 85.0 84 0.99 850.0 850 1.00 52 | 3000 102.0 100 0.98 1020.0 1019 1.00 53 | 3500 119.0 117 0.98 1190.0 1189 1.00 54 | 4000 136.0 134 0.99 1360.0 1360 1.00 55 | 4500 153.0 152 0.99 1530.0 1530 1.00 56 | 5000 170.0 169 0.99 1700.0 1700 1.00 57 | 5500 187.0 185 0.99 1870.0 1868 1.00 58 | 6000 204.0 202 0.99 2040.0 2039 1.00 59 | 6500 221.0 220 1.00 2210.0 2209 1.00 60 | 7000 238.0 236 0.99 2380.0 2379 1.00 61 | 7500 255.0 253 0.99 2550.0 2549 1.00 62 | 8000 272.0 270 0.99 2720.0 2720 1.00 63 | 8500 289.0 288 1.00 2890.0 2890 1.00 64 | 9000 306.0 305 1.00 3060.0 3060 1.00 65 | 9500 323.0 321 0.99 3230.0 3230 1.00 66 | 10000 340.0 338 0.99 3400.0 3401 1.00 67 | -------------------------------------------------------------------------------- /examples/ping2inch/performance_0.2.1.txt: -------------------------------------------------------------------------------- 1 | ping2inch.ino 2 | FASTMATH_LIB_VERSION: 0.2.1 3 | 4 | ping2inch ref 38.1696 5 | ping2inch fast 4.3384 6 | ping2sixteenths ref 38.9048 7 | ping2sixteenths fast 8.5508 8 | 9 | verify I 10 | 0 0.0 2 inf 0 2 inf 11 | 10 0.1 2 14.94 2 3 1.40 12 | 20 0.3 2 7.47 4 5 1.17 13 | 30 0.4 2 4.98 6 6 0.93 14 | 40 0.5 2 3.74 9 9 1.05 15 | 50 0.7 2 2.99 11 11 1.03 16 | 60 0.8 2 2.49 13 12 0.93 17 | 70 0.9 2 2.13 15 15 1.00 18 | 80 1.1 2 1.87 17 18 1.05 19 | 90 1.2 2 1.66 19 19 0.99 20 | 100 1.3 2 1.49 21 21 0.98 21 | 110 1.5 2 1.36 24 22 0.93 22 | 120 1.6 2 1.25 26 25 0.97 23 | 130 1.7 3 1.72 28 29 1.04 24 | 140 1.9 3 1.60 30 30 1.00 25 | 150 2.0 3 1.49 32 32 1.00 26 | 160 2.1 3 1.40 34 35 1.02 27 | 170 2.3 3 1.32 36 36 0.99 28 | 180 2.4 3 1.25 39 38 0.99 29 | 190 2.5 3 1.18 41 39 0.96 30 | 31 | verify II 32 | 200 2.7 3 1.12 43 43 1.00 33 | 250 3.3 3 0.90 54 52 0.97 34 | 300 4.0 5 1.25 64 63 0.98 35 | 350 4.7 5 1.07 75 73 0.97 36 | 400 5.4 6 1.12 86 86 1.00 37 | 450 6.0 6 1.00 96 96 1.00 38 | 500 6.7 6 0.90 107 105 0.98 39 | 550 7.4 8 1.09 118 117 0.99 40 | 600 8.0 8 1.00 129 128 1.00 41 | 650 8.7 9 1.03 139 139 1.00 42 | 700 9.4 9 0.96 150 148 0.99 43 | 750 10.0 9 0.90 161 158 0.98 44 | 800 10.7 11 1.03 171 171 1.00 45 | 850 11.4 11 0.97 182 181 0.99 46 | 900 12.0 12 1.00 193 192 1.00 47 | 950 12.7 12 0.94 203 201 0.99 48 | 49 | verify III 50 | 1000 13.4 12 0.90 214 212 0.99 51 | 2000 26.8 25 0.93 428 427 1.00 52 | 3000 40.2 39 0.97 643 640 1.00 53 | 4000 53.5 52 0.97 857 855 1.00 54 | 5000 66.9 66 0.99 1071 1070 1.00 55 | 6000 80.3 78 0.97 1285 1283 1.00 56 | 7000 93.7 92 0.98 1499 1497 1.00 57 | 8000 107.1 105 0.98 1713 1712 1.00 58 | 9000 120.5 120 1.00 1928 1926 1.00 59 | 10000 133.9 133 0.99 2142 2141 1.00 60 | 11000 147.2 145 0.98 2356 2353 1.00 61 | 12000 160.6 158 0.98 2570 2568 1.00 62 | 13000 174.0 172 0.99 2784 2783 1.00 63 | 14000 187.4 185 0.99 2998 2997 1.00 64 | 15000 200.8 199 0.99 3213 3211 1.00 65 | 16000 214.2 212 0.99 3427 3426 1.00 66 | 17000 227.6 227 1.00 3641 3640 1.00 67 | 18000 240.9 240 1.00 3855 3855 1.00 68 | 19000 254.3 254 1.00 4069 4068 1.00 69 | 20000 267.7 267 1.00 4283 4283 1.00 70 | 21000 281.1 281 1.00 4498 4498 1.00 71 | 22000 294.5 292 0.99 4712 4710 1.00 72 | 23000 307.9 306 0.99 4926 4924 1.00 73 | 24000 321.3 319 0.99 5140 5139 1.00 74 | 25000 334.6 334 1.00 5354 5353 1.00 75 | 26000 348.0 347 1.00 5569 5568 1.00 76 | 27000 361.4 360 1.00 5783 5780 1.00 77 | 28000 374.8 373 1.00 5997 5995 1.00 78 | 29000 388.2 387 1.00 6211 6210 1.00 79 | 30000 401.6 400 1.00 6425 6424 1.00 80 | -------------------------------------------------------------------------------- /examples/ping2_temp_compensated/performance_0.2.1.txt: -------------------------------------------------------------------------------- 1 | ping2inch.ino 2 | FASTMATH_LIB_VERSION: 0.2.1 3 | 4 | ping2inch ref 38.1696 5 | ping2inch fast 4.3384 6 | ping2sixteenths ref 38.9048 7 | ping2sixteenths fast 8.5508 8 | 9 | verify I 10 | 0 0.0 2 inf 0 2 inf 11 | 10 0.1 2 14.94 2 3 1.40 12 | 20 0.3 2 7.47 4 5 1.17 13 | 30 0.4 2 4.98 6 6 0.93 14 | 40 0.5 2 3.74 9 9 1.05 15 | 50 0.7 2 2.99 11 11 1.03 16 | 60 0.8 2 2.49 13 12 0.93 17 | 70 0.9 2 2.13 15 15 1.00 18 | 80 1.1 2 1.87 17 18 1.05 19 | 90 1.2 2 1.66 19 19 0.99 20 | 100 1.3 2 1.49 21 21 0.98 21 | 110 1.5 2 1.36 24 22 0.93 22 | 120 1.6 2 1.25 26 25 0.97 23 | 130 1.7 3 1.72 28 29 1.04 24 | 140 1.9 3 1.60 30 30 1.00 25 | 150 2.0 3 1.49 32 32 1.00 26 | 160 2.1 3 1.40 34 35 1.02 27 | 170 2.3 3 1.32 36 36 0.99 28 | 180 2.4 3 1.25 39 38 0.99 29 | 190 2.5 3 1.18 41 39 0.96 30 | 31 | verify II 32 | 200 2.7 3 1.12 43 43 1.00 33 | 250 3.3 3 0.90 54 52 0.97 34 | 300 4.0 5 1.25 64 63 0.98 35 | 350 4.7 5 1.07 75 73 0.97 36 | 400 5.4 6 1.12 86 86 1.00 37 | 450 6.0 6 1.00 96 96 1.00 38 | 500 6.7 6 0.90 107 105 0.98 39 | 550 7.4 8 1.09 118 117 0.99 40 | 600 8.0 8 1.00 129 128 1.00 41 | 650 8.7 9 1.03 139 139 1.00 42 | 700 9.4 9 0.96 150 148 0.99 43 | 750 10.0 9 0.90 161 158 0.98 44 | 800 10.7 11 1.03 171 171 1.00 45 | 850 11.4 11 0.97 182 181 0.99 46 | 900 12.0 12 1.00 193 192 1.00 47 | 950 12.7 12 0.94 203 201 0.99 48 | 49 | verify III 50 | 1000 13.4 12 0.90 214 212 0.99 51 | 2000 26.8 25 0.93 428 427 1.00 52 | 3000 40.2 39 0.97 643 640 1.00 53 | 4000 53.5 52 0.97 857 855 1.00 54 | 5000 66.9 66 0.99 1071 1070 1.00 55 | 6000 80.3 78 0.97 1285 1283 1.00 56 | 7000 93.7 92 0.98 1499 1497 1.00 57 | 8000 107.1 105 0.98 1713 1712 1.00 58 | 9000 120.5 120 1.00 1928 1926 1.00 59 | 10000 133.9 133 0.99 2142 2141 1.00 60 | 11000 147.2 145 0.98 2356 2353 1.00 61 | 12000 160.6 158 0.98 2570 2568 1.00 62 | 13000 174.0 172 0.99 2784 2783 1.00 63 | 14000 187.4 185 0.99 2998 2997 1.00 64 | 15000 200.8 199 0.99 3213 3211 1.00 65 | 16000 214.2 212 0.99 3427 3426 1.00 66 | 17000 227.6 227 1.00 3641 3640 1.00 67 | 18000 240.9 240 1.00 3855 3855 1.00 68 | 19000 254.3 254 1.00 4069 4068 1.00 69 | 20000 267.7 267 1.00 4283 4283 1.00 70 | 21000 281.1 281 1.00 4498 4498 1.00 71 | 22000 294.5 292 0.99 4712 4710 1.00 72 | 23000 307.9 306 0.99 4926 4924 1.00 73 | 24000 321.3 319 0.99 5140 5139 1.00 74 | 25000 334.6 334 1.00 5354 5353 1.00 75 | 26000 348.0 347 1.00 5569 5568 1.00 76 | 27000 361.4 360 1.00 5783 5780 1.00 77 | 28000 374.8 373 1.00 5997 5995 1.00 78 | 29000 388.2 387 1.00 6211 6210 1.00 79 | 30000 401.6 400 1.00 6425 6424 1.00 80 | -------------------------------------------------------------------------------- /examples/log10_performance/log10_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: log10_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: log performance test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | float x, y; 14 | 15 | 16 | void setup() 17 | { 18 | Serial.begin(115200); 19 | Serial.println(); 20 | Serial.println(__FILE__); 21 | Serial.print("FASTMATH_LIB_VERSION: "); 22 | Serial.println(FASTMATH_LIB_VERSION); 23 | Serial.println(); 24 | delay(1000); 25 | 26 | Serial.println("Function\ttime\tX\tY\n"); 27 | x = random(1000000) * 0.001; 28 | 29 | float inverseLog10_2 = 1.0 / log10(2); 30 | 31 | start = micros(); 32 | y = log10(x) * inverseLog10_2; // mul is faster than div log10(2) 33 | stop = micros(); 34 | Serial.print("log2: "); 35 | Serial.print("\t\t"); 36 | Serial.print(stop - start); 37 | Serial.print("\t"); 38 | Serial.print(x, 3); 39 | Serial.print("\t"); 40 | Serial.print(y, 6); 41 | Serial.print("\n"); 42 | delay(100); 43 | 44 | start = micros(); 45 | y = fastLog2(x); 46 | stop = micros(); 47 | Serial.print("fast2: "); 48 | Serial.print("\t\t"); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(x, 3); 52 | Serial.print("\t"); 53 | Serial.print(y, 6); 54 | Serial.print("\n"); 55 | delay(100); 56 | 57 | start = micros(); 58 | y = log10(x); 59 | stop = micros(); 60 | Serial.print("log10: "); 61 | Serial.print("\t\t"); 62 | Serial.print(stop - start); 63 | Serial.print("\t"); 64 | Serial.print(x, 3); 65 | Serial.print("\t"); 66 | Serial.print(y, 6); 67 | Serial.print("\n"); 68 | delay(100); 69 | 70 | start = micros(); 71 | y = fastLog10(x); 72 | stop = micros(); 73 | Serial.print("fast10: "); 74 | Serial.print("\t"); 75 | Serial.print(stop - start); 76 | Serial.print("\t"); 77 | Serial.print(x, 3); 78 | Serial.print("\t"); 79 | Serial.print(y, 6); 80 | Serial.print("\n"); 81 | delay(100); 82 | 83 | start = micros(); 84 | y = log(x); 85 | stop = micros(); 86 | Serial.print("log: "); 87 | Serial.print("\t\t"); 88 | Serial.print(stop - start); 89 | Serial.print("\t"); 90 | Serial.print(x, 3); 91 | Serial.print("\t"); 92 | Serial.print(y, 6); 93 | Serial.print("\n"); 94 | delay(100); 95 | 96 | start = micros(); 97 | y = fastLog(x); 98 | stop = micros(); 99 | Serial.print("fastLog: "); 100 | Serial.print("\t"); 101 | Serial.print(stop - start); 102 | Serial.print("\t"); 103 | Serial.print(x, 3); 104 | Serial.print("\t"); 105 | Serial.print(y, 6); 106 | Serial.print("\n"); 107 | delay(100); 108 | 109 | Serial.println("\ndone..."); 110 | } 111 | 112 | 113 | void loop() 114 | { 115 | } 116 | 117 | 118 | // -- END OF FILE -- 119 | -------------------------------------------------------------------------------- /examples/bcd_performance/bcd_performance.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: bcd_performance.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: bcd test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | volatile uint8_t z; 14 | 15 | 16 | void setup() 17 | { 18 | Serial.begin(115200); 19 | Serial.println(); 20 | Serial.println(__FILE__); 21 | Serial.print("FASTMATH_LIB_VERSION: "); 22 | Serial.println(FASTMATH_LIB_VERSION); 23 | Serial.println(); 24 | delay(100); 25 | 26 | Serial.print("dec2bcdRef:\t"); 27 | delay(10); 28 | start = micros(); 29 | for (uint8_t x = 0; x < 100; x++) 30 | { 31 | z = dec2bcdRef(x); 32 | } 33 | stop = micros(); 34 | Serial.print(stop - start); 35 | Serial.print("\t"); 36 | Serial.print(z); 37 | Serial.print("\n"); 38 | delay(100); 39 | 40 | 41 | Serial.print("dec2bcd:\t"); 42 | delay(10); 43 | start = micros(); 44 | for (uint8_t x = 0; x < 100; x++) 45 | { 46 | z = dec2bcd(x); 47 | } 48 | stop = micros(); 49 | Serial.print(stop - start); 50 | Serial.print("\t"); 51 | Serial.print(z); 52 | Serial.print("\n"); 53 | delay(100); 54 | 55 | 56 | Serial.print("dec2bcdRTC:\t"); 57 | delay(10); 58 | start = micros(); 59 | for (uint8_t x = 0; x < 100; x++) 60 | { 61 | z = dec2bcdRTC(x); 62 | } 63 | stop = micros(); 64 | Serial.print(stop - start); 65 | Serial.print("\t"); 66 | Serial.print(z); 67 | Serial.print("\n"); 68 | delay(100); 69 | 70 | // not 100% correct but it measures performance 71 | Serial.print("bcd2decRef:\t"); 72 | delay(10); 73 | start = micros(); 74 | for (uint8_t x = 0; x < 100; x++) 75 | { 76 | z = bcd2decRef(x); 77 | } 78 | stop = micros(); 79 | Serial.print(stop - start); 80 | Serial.print("\t"); 81 | Serial.print(z); 82 | Serial.print("\n"); 83 | delay(100); 84 | 85 | // not 100% correct but it measures performance 86 | Serial.print("bcd2dec:\t"); 87 | delay(10); 88 | start = micros(); 89 | for (uint8_t x = 0; x < 100; x++) 90 | { 91 | z = bcd2dec(x); 92 | } 93 | stop = micros(); 94 | Serial.print(stop - start); 95 | Serial.print("\t"); 96 | Serial.print(z); 97 | Serial.print("\n"); 98 | delay(100); 99 | 100 | Serial.println(); 101 | Serial.println("compare bcd2dec <-> dec2bcd (0..100)"); 102 | delay(10); 103 | start = micros(); 104 | for (uint8_t x = 0; x < 100; x++) 105 | { 106 | z = dec2bcd(x); 107 | if (x != bcd2dec(z)) 108 | { 109 | Serial.print("."); 110 | } 111 | } 112 | stop = micros(); 113 | Serial.print(stop - start); 114 | Serial.print("\t"); 115 | Serial.print(z); 116 | Serial.print("\n"); 117 | delay(100); 118 | 119 | 120 | Serial.println("compare bcd2dec <-> dec2bcdRTC (0..60)"); 121 | start = micros(); 122 | for (uint8_t x = 0; x < 60; x++) 123 | { 124 | z = dec2bcdRTC(x); 125 | if (x != bcd2dec(z)) 126 | { 127 | Serial.print(z, HEX); 128 | Serial.print(" "); 129 | Serial.print(x); 130 | Serial.print(" "); 131 | } 132 | } 133 | stop = micros(); 134 | Serial.print(stop - start); 135 | Serial.print("\t"); 136 | Serial.print(z); 137 | Serial.print("\n"); 138 | delay(100); 139 | 140 | Serial.println("\ndone..."); 141 | } 142 | 143 | 144 | void loop() 145 | { 146 | } 147 | 148 | 149 | // -- END OF FILE -- 150 | -------------------------------------------------------------------------------- /examples/ping2_temp_compensated/ping2_temp_compensated.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: ping2_temp_compensated.ino 3 | // AUTHOR: Rob Tillaart 4 | // DATE: 2022-12-25 5 | // PURPOSE: test fast routines for PING))) sensor 6 | // URL: https://github.com/RobTillaart/fast_math 7 | 8 | 9 | #include "Arduino.h" 10 | #include "fast_math.h" 11 | 12 | 13 | uint32_t start, stop; 14 | volatile uint32_t q = 0; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(10); 26 | 27 | Serial.print("ping2cm ref\t"); 28 | delay(10); 29 | start = micros(); 30 | for (uint16_t i = 0; i < 10000; i++) 31 | { 32 | q = i / 29.41176; 33 | } 34 | stop = micros(); 35 | Serial.println((stop - start) / 10000.0, 4); 36 | delay(10); 37 | 38 | Serial.print("ping2cm_tempC\t"); 39 | delay(10); 40 | start = micros(); 41 | for (uint16_t i = 0; i < 10000; i++) 42 | { 43 | q = ping2cm_tempC(i, 20); 44 | } 45 | stop = micros(); 46 | Serial.println((stop - start) / 10000.0, 4); 47 | delay(10); 48 | 49 | 50 | 51 | Serial.print("ping2inch ref\t"); 52 | delay(10); 53 | start = micros(); 54 | for (uint16_t i = 0; i < 10000; i++) 55 | { 56 | q = i / 74.70588235; 57 | } 58 | stop = micros(); 59 | Serial.println((stop - start) / 10000.0, 4); 60 | delay(10); 61 | 62 | Serial.print("ping2inch_tempC\t"); 63 | delay(10); 64 | start = micros(); 65 | for (uint16_t i = 0; i < 10000; i++) 66 | { 67 | q = ping2inch_tempC(i, 20); 68 | } 69 | stop = micros(); 70 | Serial.println((stop - start) / 10000.0, 4); 71 | delay(10); 72 | 73 | Serial.print("ping2inch_tempF\t"); 74 | delay(10); 75 | start = micros(); 76 | for (uint16_t i = 0; i < 10000; i++) 77 | { 78 | q = ping2inch_tempC(i, 68); 79 | } 80 | stop = micros(); 81 | Serial.println((stop - start) / 10000.0, 4); 82 | delay(10); 83 | 84 | 85 | Serial.println("\n=============================================="); 86 | 87 | Serial.println("\ndelta ping2cm_tempC"); 88 | for (uint16_t temp = 0; temp < 40; temp++) 89 | { 90 | Serial.print(temp); 91 | Serial.print("\t"); 92 | Serial.print(15000 / 29.41176, 1); 93 | Serial.print("\t"); 94 | Serial.print(ping2cm_tempC(15000, temp)); 95 | Serial.print("\t"); 96 | Serial.print(ping2cm_tempC(15000, temp) / (15000 / 29.41176) ); 97 | Serial.println(); 98 | } 99 | 100 | Serial.println("\ndelta ping2inch_tempC"); 101 | for (uint16_t temp = 0; temp < 40; temp++) 102 | { 103 | Serial.print(temp); 104 | Serial.print("\t"); 105 | Serial.print(15000 / 74.70588235, 1); 106 | Serial.print("\t"); 107 | Serial.print(ping2inch_tempC(15000, temp)); 108 | Serial.print("\t"); 109 | Serial.print(ping2inch_tempC(15000, temp) / (15000 / 74.70588235)); 110 | Serial.println(); 111 | } 112 | 113 | 114 | Serial.println("\ndelta ping2inch_tempF"); 115 | for (uint16_t temp = 32; temp < 100; temp += 2) 116 | { 117 | Serial.print(temp); 118 | Serial.print("\t"); 119 | Serial.print(15000 / 74.70588235, 1); 120 | Serial.print("\t"); 121 | Serial.print(ping2inch_tempF(15000, temp)); 122 | Serial.print("\t"); 123 | Serial.print(ping2inch_tempF(15000, temp) / (15000 / 74.70588235)); 124 | Serial.println(); 125 | } 126 | 127 | } 128 | 129 | void loop() 130 | { 131 | } 132 | 133 | 134 | // -- END OF FILE -- 135 | -------------------------------------------------------------------------------- /examples/ping2cm/ping2cm.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: ping2cm.ino 3 | // AUTHOR: Rob Tillaart 4 | // DATE: 2013-05-11 5 | // PURPOSE: test fast routines for PING))) sensor 6 | // URL: https://github.com/RobTillaart/fast_math 7 | 8 | 9 | #include "Arduino.h" 10 | #include "fast_math.h" 11 | 12 | 13 | uint32_t start, stop; 14 | volatile uint32_t q = 0; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(10); 26 | 27 | Serial.print("pingRef\t"); 28 | delay(10); 29 | start = micros(); 30 | for (uint16_t i = 0; i < 10000; i++) 31 | { 32 | q = i / 29.41176; 33 | } 34 | stop = micros(); 35 | Serial.println((stop - start) / 10000.0, 4); 36 | delay(10); 37 | 38 | Serial.print("pingRef\t"); 39 | delay(10); 40 | start = micros(); 41 | for (uint16_t i = 0; i < 10000; i++) 42 | { 43 | q = i * (1 / 29.41176); 44 | } 45 | stop = micros(); 46 | Serial.println((stop - start) / 10000.0, 4); 47 | delay(10); 48 | 49 | Serial.print("ping2cm\t"); 50 | delay(10); 51 | start = micros(); 52 | for (uint16_t i = 0; i < 10000; i++) 53 | { 54 | q = ping2cm(i); 55 | } 56 | stop = micros(); 57 | Serial.println((stop - start) / 10000.0, 4); 58 | delay(10); 59 | 60 | Serial.print("ping2mm\t"); 61 | delay(10); 62 | start = micros(); 63 | for (uint16_t i = 0; i < 10000; i++) 64 | { 65 | q = ping2mm(i); 66 | } 67 | stop = micros(); 68 | Serial.println((stop - start) / 10000.0, 4); 69 | delay(100); 70 | 71 | Serial.print("ping2cm32\t"); 72 | delay(10); 73 | start = micros(); 74 | for (uint16_t i = 0; i < 10000; i++) 75 | { 76 | q = ping2cm32(i); 77 | } 78 | stop = micros(); 79 | Serial.println((stop - start) / 10000.0, 4); 80 | delay(10); 81 | 82 | Serial.print("ping2mm32\t"); 83 | delay(10); 84 | start = micros(); 85 | for (uint16_t i = 0; i < 10000; i++) 86 | { 87 | q = ping2mm32(i); 88 | } 89 | stop = micros(); 90 | Serial.println((stop - start) / 10000.0, 4); 91 | delay(100); 92 | 93 | Serial.println("\n======================================="); 94 | Serial.println("\nverify - 16 bit - up to 10 meter"); 95 | for (uint16_t i = 100; i < 30000; i *= 1.1) 96 | { 97 | Serial.print(i); 98 | Serial.print("\t"); 99 | Serial.print(i * 0.034, 1); 100 | Serial.print("\t"); 101 | Serial.print(ping2cm(i)); 102 | Serial.print("\t"); 103 | Serial.print((1.0 * ping2cm(i)) / (i * 0.034) ); 104 | Serial.print("\t\t"); 105 | Serial.print(i * 0.34, 1); 106 | Serial.print("\t"); 107 | Serial.print(ping2mm(i)); 108 | Serial.print("\t"); 109 | Serial.print((1.0 * ping2mm(i)) / (i * 0.34) ); 110 | Serial.println(); 111 | } 112 | 113 | 114 | Serial.println("\nverify - 32 bit - up to 100 meter"); 115 | for (uint32_t i = 100; i <= 300000; i *= 1.1) 116 | { 117 | Serial.print(i); 118 | Serial.print("\t"); 119 | Serial.print(i * 0.034, 1); 120 | Serial.print("\t"); 121 | Serial.print(ping2cm32(i)); 122 | Serial.print("\t"); 123 | Serial.print((1.0 * ping2cm32(i)) / (i * 0.034) ); 124 | Serial.print("\t\t"); 125 | Serial.print(i * 0.34, 1); 126 | Serial.print("\t"); 127 | Serial.print(ping2mm32(i)); 128 | Serial.print("\t"); 129 | Serial.print((1.0 * ping2mm32(i)) / (i * 0.34) ); 130 | Serial.println(); 131 | } 132 | 133 | } 134 | 135 | void loop() 136 | { 137 | } 138 | 139 | 140 | // -- END OF FILE -- 141 | -------------------------------------------------------------------------------- /fast_math.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // 3 | // FILE: fast_math.h 4 | // AUTHOR: Rob Tillaart 5 | // VERSION: 0.2.4 6 | // PURPOSE: Arduino library for fast math algorithms 7 | // DATE: 27 October 2013 8 | // URL: https://github.com/RobTillaart/fast_math 9 | 10 | 11 | #ifdef ESP_PLATFORM 12 | #include 13 | #include 14 | #include 15 | #else 16 | #include "Arduino.h" 17 | #endif 18 | 19 | #define FASTMATH_LIB_VERSION (F("0.2.4")) 20 | 21 | 22 | #ifdef __cplusplus 23 | extern "C" 24 | { 25 | #endif 26 | 27 | 28 | ////////////////////////////////////////////////////////////////////////// 29 | // 30 | // ROUTINE: divmod10 31 | // PURPOSE: fast routine that provides both / 10 and % 10 for integer math. 32 | // URL: https://forum.arduino.cc/t/divmod10-a-fast-replacement-for-10-and-10-unsigned/163586 33 | // AUTHORS: see URL 34 | // NOTE: assembler version for AVR exists (by Stimmer) - see URL 35 | // 36 | void divmod10(uint32_t in, uint32_t *div, uint8_t *mod); 37 | void divmod3(uint32_t in, uint32_t *div, uint8_t *mod); 38 | void divmod5(uint32_t in, uint32_t *div, uint8_t *mod); 39 | 40 | // for clocks 41 | void divmod12(uint32_t in, uint32_t *div, uint8_t *mod); 42 | void divmod24(uint32_t in, uint32_t *div, uint8_t *mod); 43 | void divmod60(uint32_t in, uint32_t *div, uint8_t *mod); 44 | 45 | 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | // 49 | // ROUTINE: dec2bcd and bcd2dec 50 | // PURPOSE: conversion 51 | // 52 | uint8_t dec2bcdRef(uint8_t value); // reference implementation. 53 | uint8_t dec2bcd(uint8_t value); 54 | uint8_t dec2bcdRTC(uint8_t value); 55 | uint8_t bcd2decRef(uint8_t value); 56 | uint8_t bcd2dec(uint8_t value); 57 | 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | // 61 | // ROUTINE: polynome 62 | // PURPOSE: routine to evaluate a polynome and be able to change weights runtime. 63 | // 64 | // assumes degree >= 1, and ar[0] exists, and could be 0. 65 | // 66 | // e.g y = 3x^2 + 5x + 7 ==> ar[] = { 7, 5, 3 }; degree = 2; 67 | // index is exponent of x 68 | // 7x^0 + 5x^1 + 3x^2 69 | // 70 | float polynome(float x, float ar[], uint8_t degree); 71 | 72 | 73 | ////////////////////////////////////////////////////////////////////////// 74 | // 75 | // 16 BIT PING MATH - for distances up to ~10 meter 76 | // 77 | ////////////////////////////////////////////////////////// 78 | // 79 | // ROUTINE: ping2cm 80 | // PURPOSE: fast routines to calculate the distance in cm / mm for a ping sensor 81 | // 82 | uint16_t ping2cm(uint16_t in); 83 | uint16_t ping2mm(uint16_t in); // smaller units are more accurate. 84 | 85 | uint16_t ping2inch(uint16_t in); 86 | uint16_t ping2quarter(uint16_t in); 87 | uint16_t ping2sixteenths(uint16_t in); 88 | 89 | 90 | ////////////////////////////////////////////////////////// 91 | // 92 | // 32 BIT PING MATH - for distances > 10 meter (gaim ~10%) 93 | // 94 | uint32_t ping2cm32(uint32_t in); 95 | uint32_t ping2mm32(uint32_t in); 96 | 97 | 98 | // temperature compensated speed of sound distance 99 | float ping2cm_tempC(uint16_t duration, int Celsius); 100 | float ping2inch_tempC(uint16_t duration, int Celsius); 101 | float ping2inch_tempF(uint16_t duration, int Fahrenheit); 102 | 103 | 104 | ////////////////////////////////////////////////////////// 105 | // 106 | // FAST LOG2 + LOG10 + LOG 107 | // 108 | // from: https://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html 109 | // and several other places. 110 | // fast approximation for log2() with 3rd degree polynome 111 | // y = C[0]*f*f*f + C[1]*f*f + C[2]*f + C[3] + exponent; 112 | float fastLog2(float x); 113 | 114 | // log10(x) = log2(x) * 0.3010299956639812f // log10(2) 115 | float fastLog10(float x); 116 | 117 | // log(x) = log2(x) * 0.6931471805599453f // log(2) 118 | float fastLog(float x); 119 | 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif 124 | 125 | 126 | // -- END OF FILE -- 127 | 128 | -------------------------------------------------------------------------------- /examples/polynome/polynome.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: polynome.ino 3 | // AUTHOR: Rob Tillaart 4 | // PURPOSE: polynome test 5 | // URL: https://github.com/RobTillaart/fast_math 6 | 7 | 8 | #include "Arduino.h" 9 | #include "fast_math.h" 10 | 11 | 12 | uint32_t start, stop; 13 | float x, y, z, sum, error; 14 | float YY1, YY2, YY3; 15 | float ar[3]; 16 | 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); 21 | Serial.println(); 22 | Serial.println(__FILE__); 23 | Serial.print("FASTMATH_LIB_VERSION: "); 24 | Serial.println(FASTMATH_LIB_VERSION); 25 | Serial.println(); 26 | delay(1000); 27 | 28 | sum = 0; 29 | start = micros(); 30 | for (x = 0; x < 10; x++) 31 | { 32 | sum += polynome(x, ar, 2); 33 | } 34 | stop = micros(); 35 | Serial.print(stop - start); 36 | Serial.print("\t"); 37 | Serial.print(sum); 38 | Serial.print("\n"); 39 | delay(100); 40 | 41 | // ax^2 + bx + c == 42 for x = 10. 42 | // ax^2 + bx + c == 3 for x = 5. 43 | // ax^2 + bx + c == 3 for x = 3. 44 | Serial.println("\nFind the minimum a,b,c"); 45 | 46 | search_heat(); 47 | Serial.println(); 48 | // search_linear(); // takes forever 49 | 50 | Serial.println("done..."); 51 | } 52 | 53 | 54 | void loop() 55 | { 56 | } 57 | 58 | 59 | // brute force search takes forever 60 | void search_linear() 61 | { 62 | float minimum = 1000000000; 63 | uint32_t start = millis(); 64 | for (float c = -20; c <= 20; c += 0.1) 65 | { 66 | for (float b = -20; b <= 20; b += 0.1) 67 | { 68 | for (float a = -20; a <= 20; a += 0.1) 69 | { 70 | ar[0] = a; 71 | ar[1] = b; 72 | ar[2] = c; 73 | YY1 = polynome(10, ar, 2); 74 | YY2 = polynome(5, ar, 2); 75 | YY3 = polynome(3, ar, 2); 76 | error = 0; 77 | error += (YY1 - 42) * (YY1 - 42); 78 | error += (YY2 - 3) * (YY2 - 3); 79 | error += (YY3 - 3) * (YY3 - 3); 80 | if (error < minimum) 81 | { 82 | minimum = error; 83 | Serial.print(millis() - start); 84 | Serial.print("\t"); 85 | Serial.print(a); 86 | Serial.print("\t"); 87 | Serial.print(b); 88 | Serial.print("\t"); 89 | Serial.print(c); 90 | Serial.print("\t"); 91 | Serial.print(YY1, 3); 92 | Serial.print("\t"); 93 | Serial.print(YY2, 3); 94 | Serial.print("\t"); 95 | Serial.print(YY3, 3); 96 | Serial.print("\t"); 97 | Serial.print(error, 6); 98 | Serial.print("\n"); 99 | } 100 | } 101 | } 102 | } 103 | } 104 | 105 | 106 | // search and improve stepwise goes way faster 107 | void search_heat() 108 | { 109 | float error; 110 | float minimum = 1E9; 111 | float a, b, c; 112 | a = b = c = 0; // arbitrary start 113 | uint32_t start = millis(); 114 | while (millis() - start < 60000) // search for 1 minute 115 | { 116 | // look random around for a better fit 117 | ar[0] = a - 0.5 + random(10000) * 0.0001; 118 | ar[1] = b - 0.5 + random(10000) * 0.0001; 119 | ar[2] = c - 0.5 + random(10000) * 0.0001; 120 | 121 | // calculate the points. 122 | YY1 = polynome(10, ar, 2); 123 | YY2 = polynome(5, ar, 2); 124 | YY3 = polynome(3, ar, 2); 125 | 126 | // determine error squared 127 | error = 0; 128 | error += (YY1 - 42) * (YY1 - 42); 129 | error += (YY2 - 3) * (YY2 - 3); 130 | error += (YY3 - 3) * (YY3 - 3); 131 | 132 | // if new values is a better fit 133 | if (error < minimum) 134 | { 135 | // remember the new values 136 | minimum = error; 137 | a = ar[0]; 138 | b = ar[1]; 139 | c = ar[2]; 140 | // output them. 141 | Serial.print(millis() - start); 142 | Serial.print("\t"); 143 | Serial.print(ar[0], 2); 144 | Serial.print("\t"); 145 | Serial.print(ar[1], 2); 146 | Serial.print("\t"); 147 | Serial.print(ar[2], 2); 148 | Serial.print("\t"); 149 | Serial.print(YY1, 3); 150 | Serial.print("\t"); 151 | Serial.print(YY2, 3); 152 | Serial.print("\t"); 153 | Serial.print(YY3, 3); 154 | Serial.print("\t"); 155 | Serial.print(error, 6); 156 | Serial.print("\n"); 157 | } 158 | } 159 | } 160 | 161 | 162 | // -- END OF FILE -- 163 | -------------------------------------------------------------------------------- /examples/polynome/output_0.2.0.txt: -------------------------------------------------------------------------------- 1 | Arduino IDE 1.8.19 2 | PLATFORM: UNO 3 | 4 | polynome.ino 5 | FASTMATH_LIB_VERSION: 0.2.0 6 | 7 | 304 0.00 8 | 9 | Find the minimum a,b,c 10 | 1 0.18 0.02 -0.49 -48.840 -12.012 -4.179 8528.865234 11 | 7 0.44 -0.39 -0.20 -23.478 -6.511 -2.530 4408.407226 12 | 11 0.71 -0.44 0.12 7.883 1.392 0.421 1173.206665 13 | 15 0.66 -0.64 0.41 35.744 7.830 2.471 62.740795 14 | 22 0.18 -0.96 0.45 35.438 6.603 1.345 58.779823 15 | 29 -0.18 -0.52 0.50 44.263 9.623 2.722 49.061378 16 | 41 -0.64 -0.08 0.43 41.235 9.634 2.966 44.592815 17 | 59 -0.61 -0.23 0.45 41.951 9.450 2.734 41.676723 18 | 65 -0.87 -0.68 0.47 39.481 7.519 1.335 29.536233 19 | 75 -0.90 -0.76 0.50 41.041 7.673 1.268 25.753192 20 | 129 -1.00 -1.11 0.53 40.732 6.658 0.425 21.621555 21 | 156 -0.76 -1.41 0.55 40.061 5.917 -0.050 21.572322 22 | 173 -0.66 -1.41 0.57 42.545 6.621 0.271 20.858274 23 | 207 -0.93 -1.30 0.55 40.977 6.304 0.117 20.276332 24 | 292 -0.86 -1.54 0.58 42.155 6.039 -0.225 19.663860 25 | 352 -0.78 -1.79 0.60 41.802 5.396 -0.701 19.475742 26 | 400 -0.67 -1.57 0.58 41.371 5.914 -0.185 19.033185 27 | 734 -0.29 -1.87 0.61 41.755 5.553 -0.427 18.321043 28 | 784 0.04 -1.95 0.61 41.515 5.543 -0.316 17.696878 29 | 917 0.39 -1.84 0.59 40.936 5.932 0.181 17.677108 30 | 1008 0.27 -1.89 0.60 41.541 5.853 0.007 17.307504 31 | 1271 0.42 -2.01 0.62 42.084 5.814 -0.049 17.220645 32 | 1761 0.77 -2.44 0.66 42.101 5.006 -0.631 17.219539 33 | 1852 1.19 -2.14 0.61 40.649 5.717 0.257 16.729187 34 | 2007 1.40 -2.30 0.63 41.508 5.665 0.169 15.359593 35 | 2154 1.50 -2.53 0.65 41.519 5.188 -0.203 15.281855 36 | 2542 1.86 -2.42 0.64 42.079 5.876 0.407 14.996947 37 | 2851 2.07 -2.49 0.64 40.905 5.549 0.332 14.816337 38 | 2968 2.42 -2.78 0.67 41.211 5.165 0.071 13.890233 39 | 3047 2.88 -2.86 0.67 41.691 5.425 0.360 12.945708 40 | 3612 3.26 -3.24 0.71 41.773 4.796 -0.070 12.701381 41 | 3705 3.57 -2.93 0.67 41.372 5.694 0.816 12.418461 42 | 3815 3.38 -2.96 0.68 41.700 5.555 0.609 12.336068 43 | 3882 3.79 -3.36 0.71 41.251 4.758 0.107 12.022620 44 | 4176 4.13 -3.57 0.73 41.655 4.600 0.023 11.541920 45 | 4240 4.37 -3.47 0.72 41.453 4.976 0.430 10.807682 46 | 4767 4.63 -3.50 0.72 41.711 5.149 0.616 10.387719 47 | 4856 5.13 -3.66 0.74 42.091 5.229 0.777 9.918427 48 | 4924 5.26 -3.78 0.74 41.377 4.846 0.578 9.661588 49 | 4932 5.64 -3.82 0.75 42.103 5.198 0.894 9.277114 50 | 5188 6.08 -3.98 0.75 41.593 5.008 0.918 8.534039 51 | 5238 6.58 -4.15 0.76 41.230 4.853 0.970 8.147265 52 | 5292 6.45 -4.16 0.77 41.419 4.797 0.866 8.119215 53 | 5892 6.67 -4.14 0.76 41.332 4.990 1.099 8.021018 54 | 6025 7.12 -4.31 0.78 41.790 5.021 1.197 7.378822 55 | 6182 7.52 -4.52 0.79 41.516 4.726 1.092 6.852169 56 | 6777 7.98 -4.60 0.80 42.077 5.006 1.389 6.625437 57 | 7150 8.35 -4.79 0.82 42.004 4.775 1.308 6.014825 58 | 7306 8.74 -5.03 0.84 42.315 4.566 1.204 5.778129 59 | 7381 9.08 -5.15 0.84 41.849 4.388 1.207 5.164866 60 | 7400 9.35 -5.09 0.83 41.649 4.703 1.570 5.068828 61 | 7490 9.54 -5.31 0.85 41.948 4.377 1.314 4.740281 62 | 9266 9.97 -5.31 0.84 41.318 4.538 1.645 4.667236 63 | 9405 10.42 -5.55 0.87 41.859 4.413 1.603 3.970294 64 | 9815 10.68 -5.68 0.88 42.064 4.337 1.586 3.790945 65 | 10068 10.87 -5.87 0.90 42.147 4.010 1.355 3.748238 66 | 10534 11.21 -5.96 0.91 42.477 4.115 1.497 3.727776 67 | 10558 11.43 -6.18 0.93 42.286 3.703 1.238 3.681064 68 | 10618 11.87 -5.99 0.90 42.322 4.505 2.030 3.309999 69 | 11035 11.98 -6.23 0.92 42.007 3.908 1.597 2.792747 70 | 11461 12.29 -6.33 0.93 41.960 3.889 1.672 2.555352 71 | 11713 12.42 -6.31 0.92 41.593 3.938 1.795 2.497574 72 | 12039 12.44 -6.28 0.92 41.736 4.069 1.893 2.437219 73 | 12246 12.94 -6.45 0.94 42.101 4.113 2.026 2.197643 74 | 12309 13.39 -6.49 0.93 41.651 4.230 2.305 2.117220 75 | 12433 13.83 -6.93 0.98 42.199 3.594 1.828 1.764798 76 | 12596 14.17 -6.98 0.97 41.819 3.618 1.987 1.439888 77 | 12812 14.21 -6.96 0.97 42.028 3.773 2.104 1.400704 78 | 12881 14.31 -6.95 0.97 41.682 3.775 2.177 1.379361 79 | 13553 14.73 -7.22 1.00 42.189 3.554 2.047 1.250527 80 | 13586 15.14 -7.24 0.99 41.497 3.622 2.303 1.126335 81 | 14875 15.44 -7.49 1.01 41.753 3.295 2.081 0.992971 82 | 14926 15.74 -7.54 1.02 41.895 3.441 2.271 0.736985 83 | 14987 16.10 -7.63 1.02 41.614 3.400 2.370 0.705319 84 | 16340 16.18 -7.72 1.03 42.014 3.329 2.285 0.619421 85 | 16997 16.61 -7.80 1.04 42.084 3.467 2.513 0.462233 86 | 21850 16.80 -7.86 1.04 42.165 3.480 2.568 0.444942 87 | 22193 17.24 -7.98 1.04 41.700 3.399 2.679 0.351980 88 | 22370 17.60 -8.09 1.05 42.124 3.513 2.825 0.309363 89 | 22438 17.88 -8.22 1.06 42.065 3.383 2.801 0.190800 90 | 23087 18.21 -8.37 1.08 42.076 3.259 2.787 0.118578 91 | 28586 18.67 -8.62 1.10 42.008 2.958 2.671 0.110208 92 | 29143 19.02 -8.63 1.09 42.128 3.221 2.976 0.065784 93 | 30337 19.18 -8.75 1.10 41.908 2.990 2.852 0.030430 94 | 34336 19.05 -8.70 1.10 41.971 3.028 2.842 0.026631 95 | 34686 19.27 -8.74 1.10 41.963 3.087 2.953 0.011266 96 | 41977 19.70 -8.90 1.11 42.048 3.027 3.013 0.003143 97 | 98 | done... 99 | -------------------------------------------------------------------------------- /examples/ping2inch/ping2inch.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: ping2inch.ino 3 | // AUTHOR: Rob Tillaart 4 | // DATE: 2022-12-09 5 | // PURPOSE: test fast routines for PING))) sensor 6 | // URL: https://github.com/RobTillaart/fast_math 7 | 8 | 9 | #include "Arduino.h" 10 | #include "fast_math.h" 11 | 12 | 13 | uint32_t start, stop; 14 | volatile uint32_t q = 0; 15 | 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | Serial.println(); 21 | Serial.println(__FILE__); 22 | Serial.print("FASTMATH_LIB_VERSION: "); 23 | Serial.println(FASTMATH_LIB_VERSION); 24 | Serial.println(); 25 | delay(10); 26 | 27 | Serial.print("ping2inch ref\t"); 28 | delay(10); 29 | start = micros(); 30 | for (uint16_t i = 0; i < 10000; i++) 31 | { 32 | q = i / 74.70588235; 33 | } 34 | stop = micros(); 35 | Serial.println((stop - start) / 10000.0, 4); 36 | delay(10); 37 | 38 | 39 | Serial.print("ping2inch fast\t"); 40 | delay(10); 41 | start = micros(); 42 | for (uint16_t i = 0; i < 10000; i++) 43 | { 44 | q = ping2inch(i); 45 | } 46 | stop = micros(); 47 | Serial.println((stop - start) / 10000.0, 4); 48 | delay(10); 49 | 50 | 51 | Serial.print("ping2quarter ref\t"); 52 | delay(10); 53 | start = micros(); 54 | for (uint16_t i = 0; i < 10000; i++) 55 | { 56 | q = i / 18.6764705875; 57 | } 58 | stop = micros(); 59 | Serial.println((stop - start) / 10000.0, 4); 60 | delay(10); 61 | 62 | 63 | Serial.print("ping2quarter fast\t"); 64 | delay(10); 65 | start = micros(); 66 | for (uint16_t i = 0; i < 10000; i++) 67 | { 68 | q = ping2quarter(i); 69 | } 70 | stop = micros(); 71 | Serial.println((stop - start) / 10000.0, 4); 72 | delay(10); 73 | 74 | 75 | Serial.print("ping2sixteenths ref\t"); 76 | delay(10); 77 | start = micros(); 78 | for (uint16_t i = 0; i < 10000; i++) 79 | { 80 | q = i / 4.669117646875; 81 | } 82 | stop = micros(); 83 | Serial.println((stop - start) / 10000.0, 4); 84 | delay(10); 85 | 86 | 87 | Serial.print("ping2sixteenths fast\t"); 88 | delay(10); 89 | start = micros(); 90 | for (uint16_t i = 0; i < 10000; i++) 91 | { 92 | q = ping2sixteenths(i); 93 | } 94 | stop = micros(); 95 | Serial.println((stop - start) / 10000.0, 4); 96 | delay(10); 97 | 98 | 99 | Serial.println("\nverify I"); 100 | for (uint16_t i = 0; i < 200; i += 10) 101 | { 102 | Serial.print(i); 103 | Serial.print("\t"); 104 | // Serial.print(i / 75); 105 | Serial.print(i / 74.70588235, 1); 106 | Serial.print("\t"); 107 | Serial.print(ping2inch(i)); 108 | Serial.print("\t"); 109 | Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); 110 | Serial.print("\t\t"); 111 | Serial.print(i / 18.6764705875, 0); 112 | Serial.print("\t"); 113 | Serial.print(ping2quarter(i)); 114 | Serial.print("\t"); 115 | Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); 116 | Serial.print("\t\t"); 117 | Serial.print(i / 4.669117646875, 0); 118 | Serial.print("\t"); 119 | Serial.print(ping2sixteenths(i)); 120 | Serial.print("\t"); 121 | Serial.print((1.0 * ping2sixteenths(i)) / (i / 4.669117646875), 2 ); 122 | Serial.print("\t"); 123 | Serial.println(); 124 | } 125 | 126 | Serial.println("\nverify II"); 127 | for (uint16_t i = 200; i < 1000; i += 50) 128 | { 129 | Serial.print(i); 130 | Serial.print("\t"); 131 | // Serial.print(i / 75); 132 | Serial.print(i / 74.70588235, 1); 133 | Serial.print("\t"); 134 | Serial.print(ping2inch(i)); 135 | Serial.print("\t"); 136 | Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); 137 | Serial.print("\t\t"); 138 | Serial.print(i / 18.6764705875, 0); 139 | Serial.print("\t"); 140 | Serial.print(ping2quarter(i)); 141 | Serial.print("\t"); 142 | Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); 143 | Serial.print("\t\t"); 144 | Serial.print(i / 4.669117646875, 0); 145 | Serial.print("\t"); 146 | Serial.print(ping2sixteenths(i)); 147 | Serial.print("\t"); 148 | Serial.print((1.0 * ping2sixteenths(i)) / (i / 4.669117646875), 2 ); 149 | Serial.print("\t"); 150 | Serial.println(); 151 | } 152 | 153 | Serial.println("\nverify III"); 154 | for (uint16_t i = 1000; i <= 30000; i += 1000) 155 | { 156 | Serial.print(i); 157 | Serial.print("\t"); 158 | // Serial.print(i / 75); 159 | Serial.print(i / 74.70588235, 1); 160 | Serial.print("\t"); 161 | Serial.print(ping2inch(i)); 162 | Serial.print("\t"); 163 | Serial.print((1.0 * ping2inch(i)) / (i / 74.70588235), 2 ); 164 | Serial.print("\t\t"); 165 | Serial.print(i / 18.6764705875, 0); 166 | Serial.print("\t"); 167 | Serial.print(ping2quarter(i)); 168 | Serial.print("\t"); 169 | Serial.print((1.0 * ping2quarter(i)) / (i / 18.6764705875), 2 ); 170 | Serial.print("\t\t"); 171 | Serial.print(i / 4.669117646875, 0); 172 | Serial.print("\t"); 173 | Serial.print(ping2sixteenths(i)); 174 | Serial.print("\t"); 175 | Serial.print((1.0 * ping2sixteenths(i)) / (i / 4.669117646875), 2 ); 176 | Serial.print("\t"); 177 | Serial.println(); 178 | } 179 | } 180 | 181 | void loop() 182 | { 183 | } 184 | 185 | 186 | // -- END OF FILE -- 187 | -------------------------------------------------------------------------------- /examples/ping2cm/performance_0.2.1.txt: -------------------------------------------------------------------------------- 1 | UNO 2 | 1.8.19 3 | 4 | 5 | ping2cm.ino 6 | FASTMATH_LIB_VERSION: 0.2.1 7 | 8 | pingRef 38.7176 9 | ping2cm 5.8472 10 | ping2mm 7.4188 11 | ping2cm32 35.7748 12 | ping2mm32 34.8948 13 | 14 | ======================================= 15 | 16 | verify - 16 bit 17 | 100 3.4 5 1.47 34.0 35 1.03 18 | 110 3.7 5 1.34 37.4 37 0.99 19 | 121 4.1 5 1.22 41.1 41 1.00 20 | 133 4.5 6 1.33 45.2 47 1.04 21 | 146 5.0 6 1.21 49.6 51 1.03 22 | 160 5.4 7 1.29 54.4 56 1.03 23 | 176 6.0 7 1.17 59.8 61 1.02 24 | 193 6.6 8 1.22 65.6 67 1.02 25 | 212 7.2 8 1.11 72.1 73 1.01 26 | 233 7.9 9 1.14 79.2 79 1.00 27 | 256 8.7 10 1.15 87.0 90 1.03 28 | 281 9.6 10 1.05 95.5 97 1.02 29 | 309 10.5 11 1.05 105.1 106 1.01 30 | 339 11.5 12 1.04 115.3 116 1.01 31 | 372 12.6 13 1.03 126.5 127 1.00 32 | 409 13.9 14 1.01 139.1 140 1.01 33 | 449 15.3 16 1.05 152.7 154 1.01 34 | 493 16.8 17 1.01 167.6 167 1.00 35 | 542 18.4 19 1.03 184.3 185 1.00 36 | 596 20.3 21 1.04 202.6 204 1.01 37 | 655 22.3 23 1.03 222.7 223 1.00 38 | 720 24.5 25 1.02 244.8 246 1.00 39 | 792 26.9 27 1.00 269.3 271 1.01 40 | 871 29.6 30 1.01 296.1 296 1.00 41 | 958 32.6 32 0.98 325.7 325 1.00 42 | 1053 35.8 36 1.01 358.0 359 1.00 43 | 1158 39.4 40 1.02 393.7 395 1.00 44 | 1273 43.3 43 0.99 432.8 432 1.00 45 | 1400 47.6 47 0.99 476.0 476 1.00 46 | 1540 52.4 53 1.01 523.6 526 1.00 47 | 1694 57.6 57 0.99 576.0 576 1.00 48 | 1863 63.3 63 0.99 633.4 634 1.00 49 | 2049 69.7 71 1.02 696.7 699 1.00 50 | 2253 76.6 77 1.01 766.0 766 1.00 51 | 2478 84.3 84 1.00 842.5 842 1.00 52 | 2725 92.7 93 1.00 926.5 927 1.00 53 | 2997 101.9 101 0.99 1019.0 1019 1.00 54 | 3296 112.1 112 1.00 1120.6 1121 1.00 55 | 3625 123.3 123 1.00 1232.5 1233 1.00 56 | 3987 135.6 134 0.99 1355.6 1356 1.00 57 | 4385 149.1 150 1.01 1490.9 1492 1.00 58 | 4823 164.0 164 1.00 1639.8 1639 1.00 59 | 5305 180.4 180 1.00 1803.7 1803 1.00 60 | 5835 198.4 198 1.00 1983.9 1983 1.00 61 | 6418 218.2 218 1.00 2182.1 2183 1.00 62 | 7059 240.0 239 1.00 2400.1 2400 1.00 63 | 7764 264.0 263 1.00 2639.8 2640 1.00 64 | 8540 290.4 290 1.00 2903.6 2904 1.00 65 | 9394 319.4 319 1.00 3194.0 3194 1.00 66 | 10333 351.3 351 1.00 3513.2 3513 1.00 67 | 11366 386.4 386 1.00 3864.4 3864 1.00 68 | 12502 425.1 425 1.00 4250.7 4250 1.00 69 | 13752 467.6 466 1.00 4675.7 4675 1.00 70 | 15127 514.3 513 1.00 5143.2 5143 1.00 71 | 16639 565.7 566 1.00 5657.3 5655 1.00 72 | 18302 622.3 621 1.00 6222.7 6221 1.00 73 | 20132 684.5 684 1.00 6844.9 6845 1.00 74 | 22145 752.9 753 1.00 7529.3 7530 1.00 75 | 24359 828.2 827 1.00 8282.1 8281 1.00 76 | 26794 911.0 911 1.00 9110.0 9109 1.00 77 | 29473 1002.1 1002 1.00 10020.8 10021 1.00 78 | 79 | verify - 32 bit 80 | 100 3.4 6 1.76 34.0 35 1.03 81 | 110 3.7 6 1.60 37.4 37 0.99 82 | 121 4.1 6 1.46 41.1 41 1.00 83 | 133 4.5 7 1.55 45.2 47 1.04 84 | 146 5.0 7 1.41 49.6 51 1.03 85 | 160 5.4 8 1.47 54.4 56 1.03 86 | 176 6.0 8 1.34 59.8 61 1.02 87 | 193 6.6 9 1.37 65.6 67 1.02 88 | 212 7.2 9 1.25 72.1 73 1.01 89 | 233 7.9 10 1.26 79.2 79 1.00 90 | 256 8.7 11 1.26 87.0 90 1.03 91 | 281 9.6 11 1.15 95.5 97 1.02 92 | 309 10.5 12 1.14 105.1 106 1.01 93 | 339 11.5 13 1.13 115.3 116 1.01 94 | 372 12.6 14 1.11 126.5 127 1.00 95 | 409 13.9 15 1.08 139.1 140 1.01 96 | 449 15.3 17 1.11 152.7 154 1.01 97 | 493 16.8 18 1.07 167.6 167 1.00 98 | 542 18.4 20 1.09 184.3 185 1.00 99 | 596 20.3 22 1.09 202.6 204 1.01 100 | 655 22.3 24 1.08 222.7 223 1.00 101 | 720 24.5 26 1.06 244.8 246 1.00 102 | 792 26.9 28 1.04 269.3 271 1.01 103 | 871 29.6 31 1.05 296.1 296 1.00 104 | 958 32.6 33 1.01 325.7 325 1.00 105 | 1053 35.8 37 1.03 358.0 359 1.00 106 | 1158 39.4 41 1.04 393.7 395 1.00 107 | 1273 43.3 44 1.02 432.8 432 1.00 108 | 1400 47.6 48 1.01 476.0 476 1.00 109 | 1540 52.4 54 1.03 523.6 526 1.00 110 | 1694 57.6 58 1.01 576.0 576 1.00 111 | 1863 63.3 64 1.01 633.4 634 1.00 112 | 2049 69.7 72 1.03 696.7 699 1.00 113 | 2253 76.6 78 1.02 766.0 766 1.00 114 | 2478 84.3 85 1.01 842.5 842 1.00 115 | 2725 92.7 94 1.01 926.5 927 1.00 116 | 2997 101.9 102 1.00 1019.0 1019 1.00 117 | 3296 112.1 113 1.01 1120.6 1121 1.00 118 | 3625 123.3 124 1.01 1232.5 1233 1.00 119 | 3987 135.6 135 1.00 1355.6 1356 1.00 120 | 4385 149.1 151 1.01 1490.9 1492 1.00 121 | 4823 164.0 165 1.01 1639.8 1639 1.00 122 | 5305 180.4 181 1.00 1803.7 1803 1.00 123 | 5835 198.4 199 1.00 1983.9 1983 1.00 124 | 6418 218.2 219 1.00 2182.1 2183 1.00 125 | 7059 240.0 240 1.00 2400.1 2400 1.00 126 | 7764 264.0 264 1.00 2639.8 2640 1.00 127 | 8540 290.4 291 1.00 2903.6 2904 1.00 128 | 9394 319.4 320 1.00 3194.0 3194 1.00 129 | 10333 351.3 352 1.00 3513.2 3513 1.00 130 | 11366 386.4 387 1.00 3864.4 3864 1.00 131 | 12502 425.1 426 1.00 4250.7 4250 1.00 132 | 13752 467.6 467 1.00 4675.7 4675 1.00 133 | 15127 514.3 514 1.00 5143.2 5143 1.00 134 | 16639 565.7 567 1.00 5657.3 5655 1.00 135 | 18302 622.3 622 1.00 6222.7 6221 1.00 136 | 20132 684.5 685 1.00 6844.9 6845 1.00 137 | 22145 752.9 754 1.00 7529.3 7530 1.00 138 | 24359 828.2 828 1.00 8282.1 8281 1.00 139 | 26794 911.0 912 1.00 9110.0 9109 1.00 140 | 29473 1002.1 1003 1.00 10020.8 10021 1.00 141 | 32420 1102.3 1102 1.00 11022.8 11022 1.00 142 | 35662 1212.5 1213 1.00 12125.1 12125 1.00 143 | 39228 1333.8 1334 1.00 13337.5 13337 1.00 144 | 43150 1467.1 1468 1.00 14671.0 14671 1.00 145 | 47465 1613.8 1614 1.00 16138.1 16137 1.00 146 | 52211 1775.2 1775 1.00 17751.7 17750 1.00 147 | 57432 1952.7 1954 1.00 19526.9 19527 1.00 148 | 63175 2148.0 2148 1.00 21479.5 21478 1.00 149 | 69492 2362.7 2362 1.00 23627.3 23627 1.00 150 | 76441 2599.0 2599 1.00 25989.9 25990 1.00 151 | 84085 2858.9 2860 1.00 28588.9 28588 1.00 152 | 92493 3144.8 3145 1.00 31447.6 31447 1.00 153 | 101742 3459.2 3459 1.00 34592.3 34591 1.00 154 | 111916 3805.1 3805 1.00 38051.4 38051 1.00 155 | 123107 4185.6 4187 1.00 41856.4 41855 1.00 156 | 135417 4604.2 4605 1.00 46041.8 46040 1.00 157 | 148958 5064.6 5064 1.00 50645.7 50644 1.00 158 | 163853 5571.0 5573 1.00 55710.0 55711 1.00 159 | 180238 6128.1 6130 1.00 61280.9 61281 1.00 160 | 198261 6740.9 6741 1.00 67408.7 67408 1.00 161 | 218087 7415.0 7415 1.00 74149.6 74147 1.00 162 | 239895 8156.4 8156 1.00 81564.3 81564 1.00 163 | 263884 8972.1 8972 1.00 89720.6 89720 1.00 164 | 290272 9869.2 9868 1.00 98692.5 98691 1.00 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Arduino CI](https://github.com/RobTillaart/fast_math/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) 3 | [![Arduino-lint](https://github.com/RobTillaart/fast_math/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/fast_math/actions/workflows/arduino-lint.yml) 4 | [![JSON check](https://github.com/RobTillaart/fast_math/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/fast_math/actions/workflows/jsoncheck.yml) 5 | [![GitHub issues](https://img.shields.io/github/issues/RobTillaart/fast_math.svg)](https://github.com/RobTillaart/fast_math/issues) 6 | 7 | [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/fast_math/blob/master/LICENSE) 8 | [![GitHub release](https://img.shields.io/github/release/RobTillaart/fast_math.svg?maxAge=3600)](https://github.com/RobTillaart/fast_math/releases) 9 | [![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/fast_math.svg)](https://registry.platformio.org/libraries/robtillaart/fast_math) 10 | 11 | 12 | # fast_math 13 | 14 | Arduino library for fast math algorithms. 15 | 16 | 17 | ## Description 18 | 19 | The fast_math library is a collection of algorithms that are faster 20 | than the default code. 21 | These algorithms are to be used when you are in a need for speed. 22 | Only tested on Arduino UNO as one of the "slower" boards. 23 | 24 | **Warning:** verify if the algorithms works for your project. (no warranty). 25 | 26 | These algorithms are collected and improved over a long time, and started 27 | with improving decades ago when computers were slower than an Arduino UNO. 28 | 29 | Note: I am interested in your feedback e.g. results on other platforms. 30 | Also improvements or other fast code is welcome. Please open an issue. 31 | 32 | 33 | #### Related 34 | 35 | - https://github.com/RobTillaart/fastTrig Gonio functions (less exact but faster) 36 | - https://github.com/RobTillaart?tab=repositories&q=math 37 | 38 | ## Interface 39 | 40 | ```cpp 41 | #include "fast_math.h" 42 | ``` 43 | 44 | 45 | ### BCD 46 | 47 | Two conversion functions, typical used in an RTC to convert register values 48 | in **BCD** = binary coded decimal, to normal integer values and back.. 49 | - **uint8_t dec2bcd(uint8_t value)** 50 | - **uint8_t bcd2dec(uint8_t value)** 51 | - **dec2bcdRTC(uint8_t value)** Even faster version, for the range 0..60. 52 | Limited to be used in RTC's. (in fact it does 0..68 correct) 53 | 54 | Backgrounder - https://forum.arduino.cc/t/faster-dec2bcd-routine-especial-for-rtc-libraries/180741/13 55 | 56 | 57 | Indicative performance Arduino UNO. 58 | 59 | | function | us | factor | notes | 60 | |:----------------|:------:|:-------:|:--------| 61 | | dec2bcd (ref) | 5.88 | 1.0 | 100 iterations 62 | | dec2bcd | 1.04 | 4.8 | 63 | | dec2bcdRTC | 0.88 | 5.7 | range 0..68 64 | | | | | 65 | | bcd2dec (ref) | 5.96 | 1.0 | 66 | | bcd2dec | 2.20 | 2.7 | 67 | 68 | 69 | ### DIVMOD 70 | 71 | Calculation of DIV and MOD simultaneous. 72 | 73 | - **void divmod10(uint32_t in, uint32_t \*div, uint8_t \*mod)** 74 | - calculates both divide and modulo 10 faster than the default / 10 and % 10. 75 | 76 | The **divmod10()** function is very useful for extracting the individual digits. 77 | Typical use is to print digits on a display, in a file or send them as ASCII over a network. 78 | 79 | Indicative performance Arduino UNO. 80 | 81 | | function | us | factor | notes | 82 | |:-----------|:------:|:-------:|:--------| 83 | | i % 10 | 38.2 | 1.0 | 84 | | i / 10 | 38.1 | 1.0 | 85 | | divmod10 | 9.1 | 4.1 | 86 | 87 | Note that for printing the gain in time per digit is 65 us. 88 | E.g. for a 4 digit number this adds up to ~quarter millisecond. 89 | 90 | 91 | Backgrounder - https://forum.arduino.cc/t/divmod10-a-fast-replacement-for-10-and-10-unsigned/163586 92 | 93 | 94 | - **void divmod3(uint32_t in, uint32_t \*div, uint8_t \*mod)** used by divmod12/24 95 | - **void divmod5(uint32_t in, uint32_t \*div, uint8_t \*mod)** 96 | - **void divmod12(uint32_t in, uint32_t \*div, uint8_t \*mod)** for hours 97 | - **void divmod24(uint32_t in, uint32_t \*div, uint8_t \*mod)** for hours 98 | - **void divmod60(uint32_t in, uint32_t \*div, uint8_t \*mod)** for minutes seconds 99 | 100 | 101 | For every element of N (natural numbers) one could develop a divmodN() function. 102 | The idea is to split the fraction 1/N into a sum of selected 1/(2^n) so the division 103 | becomes a series of adds and shifts. 104 | Sometimes there are patterns that can be optimized even more. 105 | 106 | Furthermore for limited ranges a division can be replaced by a single multiply shift pair. 107 | 108 | 109 | ### PING distance sensor 110 | 111 | For distance sensors that work with a acoustic pulse, one often see the formula: 112 | ```cm = us / 29;``` to calculate the distance in cm. 113 | In float it should be ```cm = us / 29.15;``` or ```cm = us * 0.0345;``` 114 | Note that as this is the turnaround distance (forth & back) so one 115 | need a divide by two often. (maybe I should include that) 116 | 117 | This library has functions to improve on speed. 118 | The maximum input for the 16 bit functions is 65535 us 119 | which translates to approx. 2250 cm or 22500 mm (20+ meter) 120 | This is enough range for most ping sensors, which are typical 121 | in the range 0 - 10 meter. 122 | 123 | The functions assume a speed of sound of 340 m/sec. 124 | 125 | 16 bit interface 126 | - **uint16_t ping2cm(uint16_t in)** 127 | - **uint16_t ping2mm(uint16_t in)** 128 | 129 | 32 bit interface 130 | - **uint32_t ping2cm32(uint32_t in)** for lengths > 10 meter 131 | - **uint32_t ping2mm32(uint32_t in)** for lengths > 10 meter 132 | Performance wise the 32 bit versions have a gain ~10%. 133 | 134 | Imperial 135 | - **uint16_t ping2inch(uint16_t in)** 136 | - **uint16_t ping2quarter(uint16_t in)** 137 | - **uint16_t ping2sixteenths(uint16_t in)** 138 | 139 | 140 | Indicative performance Arduino UNO (0.2.1) and ESP32 (0.2.4). 141 | 142 | | function | us | factor | us | factor | notes | 143 | |:------------------|:------:|:--------:|:------:|:--------:|:--------| 144 | | us / 29 (ref) | 38.3 | 1.0 | 2.91 | 1.0 | sos == 345 m/s (integer only) 145 | | us \* 0.0345 | 18.5 | 2.0 | 0.73 | 3.9 | sos == 345 m/s 146 | | ping2cm | 3.08 | 12.4 | 0.13 | 22.3 | sos == 340 m/s 147 | | ping2mm | 5.66 | 6.7 | 0.13 | 22.3 | sos == 340 m/s 148 | | | | | | | 149 | | ping2inch | 4.34 | 8.8 | 0.13 | 22.3 | not precise as inches are rather large units 150 | | ping2quarter | 7.55 | 5.0 | 0.14 | 20.7 | in between 151 | | ping2sixteenths | 8.55 | 4.4 | 0.15 | 19.4 | way more accurate than inches 152 | 153 | 154 | #### Temperature corrected 155 | 156 | Instead of taking a fixed value a temperature corrected speed of sound will 157 | be 0-5% more accurate. Of course this depends on the temperature. 158 | 159 | The temperature is in whole degrees C or F. 160 | 161 | - **float ping2cm_tempC(uint16_t duration, int Celsius)** 162 | - duration in us, temperature in Celsius. 163 | - this function is relative slow, a faster version is not tested. 164 | - **float ping2inch_tempC(uint16_t duration, int Celsius)** 165 | - **float ping2inch_tempF(uint16_t duration, int Fahrenheit)** 166 | 167 | 168 | Indicative performance Arduino UNO. 169 | 170 | | function | us | factor | notes | 171 | |:------------------|:------:|:--------:|:--------| 172 | | normal division | 38.3 | 1.0 | not Temperature corrected 173 | | ping2cm_tempC | 17.2 | 2.2 | 174 | | ping2inch_tempC | 16.6 | 2.3 | 175 | | ping2inch_tempF | 16.4 | 2.3 | 176 | 177 | 178 | 179 | ### Polynome 180 | 181 | Routine to evaluate a polynome and be able to change its weights runtime. 182 | E.g y = 3x^2 + 5x + 7 ==> ar\[3] = { 7, 5, 3 }; degree = 2; 183 | - **double polynome(double x, double ar[], uint8_t degree)** 184 | - degree >= 1, ar\[0] exists, and could be 0. 185 | 186 | This function is useful for evaluating a polynome many times and be able to 187 | adjust the weights. This can be used for finding the optimal weights to fit 188 | a curve for a polynome of degree N. See example. 189 | 190 | Another application can be to implement a calibration / offset function that 191 | can be tuned (runtime). 192 | 193 | 194 | ### Log2, log10, log 195 | 196 | Less accurate and expect to be at least 2 times faster, check if the accuracy 197 | and range matches the requirements of your project. 198 | 199 | - **fastLog2(float value)** idem, "base" function for fastLog10() and fastLog() 200 | - **fastLog10(float value)** idem. 201 | - **fastLog(float value)** Natural Logarithm, inverse of exp() 202 | 203 | Indicative performance measured on Arduino UNO and ESP32 (0.2.4) 204 | 205 | | function | us | factor | us | factor | notes | 206 | |:------------|:------:|:--------:|:------:|:--------:|:--------| 207 | | log2 | 200 | 1.0 | 74 | 1.0 | log2(x) = log10(x) x (1 / log10(2)); 208 | | fastLog2 | 68 | 2.9 | 14 | 5.2 | as log2() is emulated this factor is too high 209 | | log10 | 168 | 1.0 | 16 | 1.0 | 210 | | fastLog10 | 76 | 2.2 | 6 | 2.6 | 211 | | log | 160 | 1.0 | 16 | 1.0 | 212 | | fastLog | 76 | 2.1 | 5 | 3.2 | 213 | 214 | 215 | ## Future 216 | 217 | #### Must 218 | 219 | - update documentation 220 | - links, research? 221 | 222 | #### Should 223 | 224 | - unit tests 225 | - or examples that test a lot. 226 | - examples 227 | - check output examples. 228 | - keep investigating faster versions. 229 | - **divmod()** performance table other versions 230 | 231 | #### Could 232 | 233 | - split up in multiple .h files, one per group. 234 | - fast_math.h includes all individual .h files. 235 | - There are several divide functions to be included? 236 | div3(), div5(), div7(), div10() depends on application. 237 | These need more testing (range) 238 | - constants? 239 | - GOLDEN_RATIO 1.61803398875 240 | - check temperature corrected float? 241 | 242 | #### TODO Functions 243 | 244 | DIV 245 | - **uint16_t divmod10()** 16 bit overload version ? 246 | - **uint32_t div10(x, \*d)** would be a bit faster than divmod10() 247 | - **uint32_t mod10(x, \*m)** would be a bit faster too 248 | - **div7()** days - weeks. 249 | 250 | BCD 251 | - **uint16_t dec2bcd()** + 32 bit + back? 252 | 253 | 254 | #### Wont 255 | 256 | 257 | ## Support 258 | 259 | If you appreciate my libraries, you can support the development and maintenance. 260 | Improve the quality of the libraries by providing issues and Pull Requests, or 261 | donate through PayPal or GitHub sponsors. 262 | 263 | Thank you, 264 | 265 | 266 | -------------------------------------------------------------------------------- /fast_math.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: fast_math.cpp 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.2.4 5 | // PURPOSE: Arduino library for fast math algorithms 6 | // DATE: 27 October 2013 7 | // URL: https://github.com/RobTillaart/fast_math 8 | 9 | 10 | #include "fast_math.h" 11 | 12 | 13 | /////////////////////////////////////////////////////////// 14 | // 15 | // DIV MOD 16 | // 17 | void divmod10(uint32_t in, uint32_t *div, uint8_t *mod) 18 | { 19 | uint32_t x = (in|1) - (in >> 2); // div = in/10 <~~> div = (0.8*in) / 8 20 | uint32_t q = (x >> 4) + x; // 0.796875 *in 21 | x = q; 22 | q = (q >> 8) + x; // 0.799987793 * in 23 | q = (q >> 8) + x; // 0.803112745 * in 24 | q = (q >> 8) + x; // 0.8... * in 25 | q = (q >> 8) + x; // 0.8... * in 26 | 27 | x = (q >> 2); 28 | *div = (x >> 1); 29 | *mod = in - ((q & ~0x7) + (*div << 1)); 30 | } 31 | 32 | 33 | void divmod3(uint32_t in, uint32_t *div, uint8_t *mod) 34 | { 35 | uint32_t q = (in >> 1) + (in >> 3); 36 | q = q + (q >> 4); 37 | q = q + (q >> 8); 38 | q = q + (q >> 16); 39 | q = q >> 1; 40 | uint32_t r = in - q * 3; 41 | q = q + (r * 86 >> 8); 42 | *div = q; 43 | *mod = in - q * 3; 44 | } 45 | 46 | 47 | void divmod5(uint32_t in, uint32_t *div, uint8_t *mod) 48 | { 49 | uint32_t q = (in >> 1) + (in >> 2); 50 | q = q + (q >> 4); 51 | q = q + (q >> 8); 52 | q = q + (q >> 16); 53 | q = q >> 2; 54 | uint32_t r = in - q * 5; // remainder approx 55 | q = q + (r * 56 >> 8); 56 | *div = q; 57 | *mod = in - q * 5; 58 | } 59 | 60 | 61 | void divmod12(uint32_t in, uint32_t *div, uint8_t *mod) 62 | { 63 | uint32_t d; 64 | uint8_t m; 65 | divmod3(in, &d, &m); 66 | *div = d >> 2; 67 | *mod = m + (d & 0x03) * 3; 68 | } 69 | 70 | 71 | void divmod24(uint32_t in, uint32_t *div, uint8_t *mod) 72 | { 73 | uint32_t d; 74 | uint8_t m; 75 | divmod3(in, &d, &m); 76 | *div = d >> 3; 77 | *mod = m + (d & 0x07) * 3; 78 | } 79 | 80 | 81 | void divmod60(uint32_t in, uint32_t *div, uint8_t *mod) 82 | { 83 | uint32_t q = (in >> 1) + (in >> 5); 84 | q = (q + (q >> 8) + (q >> 16) + (q >> 24) ) >> 5; 85 | uint8_t r = in - q*60; 86 | if (r > 59) { q++; r -= 60; }; // correction. 87 | *div = q; 88 | *mod = r; 89 | } 90 | 91 | 92 | 93 | /////////////////////////////////////////////////////////// 94 | // 95 | // BCD 96 | // 97 | uint8_t dec2bcdRef(uint8_t value) 98 | { 99 | // two common versions. 100 | // return (value / 10 * 16 + value % 10); 101 | return value + 6 * (value / 10); 102 | } 103 | 104 | 105 | uint8_t dec2bcd(uint8_t value) 106 | { 107 | uint8_t b = (value * 103) >> 10; 108 | return (b * 16 + value - (b * 10)); 109 | // return value + 6 * b; // compiles equally fast. 110 | } 111 | 112 | 113 | uint8_t dec2bcdRTC(uint8_t value) 114 | { 115 | // this trick works faster for range value = 0..60 (think RTC). 116 | uint16_t a = value; 117 | uint8_t b = (a * 26) >> 8; // magic * 26 / 256 ~~ / 10 118 | uint8_t c = value + b * 6; 119 | // if ((c & 0x0F) == 0x0F) c -= 6; // extends range to 0..99 120 | return c; 121 | } 122 | 123 | 124 | uint8_t bcd2decRef(uint8_t value) 125 | { 126 | return value/16 * 10 + value % 10; 127 | } 128 | 129 | 130 | uint8_t bcd2dec(uint8_t value) 131 | { 132 | return value - 6 * (value >> 4); 133 | } 134 | 135 | 136 | /////////////////////////////////////////////////////////// 137 | // 138 | // POLYNOME 139 | // 140 | float polynome(float x, float ar[], uint8_t degree) 141 | { 142 | float value = ar[0]; 143 | float p = x; 144 | for (uint8_t i = 1; i <= degree; i++) 145 | { 146 | if (ar[i] != 0.0) 147 | { 148 | if (ar[i] == 1.0) value += p; 149 | else value += ar[i] * p; 150 | } 151 | p *= x; 152 | } 153 | return value; 154 | } 155 | 156 | 157 | /////////////////////////////////////////////////////////// 158 | // 159 | // PING 160 | // 161 | uint16_t ping2cm(uint16_t in) 162 | { 163 | // divide by 29.41176 == * 0.034 164 | // uint16_t q = (in >> 5) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14); 165 | uint16_t d = in >> 5; 166 | uint16_t q = d; 167 | d >>= 4; // in >> 9 168 | q += d; 169 | d >>= 2; // in >> 11; 170 | q += d; 171 | d >>= 1; // in >> 12 172 | q += d; 173 | d >>= 2; // in >> 14 174 | q += d + 2; 175 | return q; 176 | } 177 | 178 | 179 | uint16_t ping2mm(uint16_t in) 180 | { 181 | // divide by 2.941176 == * 0.34; 182 | // uint16_t q = (in >> 2) + (in >> 4) + (in >> 6) + (in >> 7) + (in >> 8) + (in >> 13); 183 | uint16_t d = in >> 2; 184 | uint16_t q = d; 185 | d >>= 2; // in >> 4 186 | q += d; 187 | d >>= 2; // in >> 6; 188 | q += d; 189 | d >>= 1; // in >> 7 190 | q += d; 191 | d >>= 1; // in >> 8 192 | q += d; 193 | d >>= 5; // in >> 13 194 | q += d + 3; 195 | return q; 196 | } 197 | 198 | 199 | uint16_t ping2inch(uint16_t in) 200 | { 201 | // divide by 74.70588235 == * 0.0133858 202 | // uint16_t q = (in >> 7) + (in >> 8) + (in >> 10) + (in >> 11) + (in >> 13) + (in >> 14) ; 203 | uint16_t d = in >> 7; 204 | uint16_t q = d; 205 | d >>= 1; // in >> 8 206 | q += d; 207 | d >>= 2; // in >> 10 208 | q += d; 209 | d >>= 1; // in >> 11 210 | q += d; 211 | d >>= 2; // in >> 13 212 | q += d; 213 | d >>= 1; // in >> 14 214 | q += d + 2; // correction. 215 | return q; 216 | } 217 | 218 | 219 | uint16_t ping2quarter(uint16_t in) 220 | { 221 | // divide by 18.6764705875 == * 0.05354330709 222 | // uint16_t q = (in >> 5) + (in >> 6) + (in >> 8) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14) ; 223 | uint16_t d = in >> 5; 224 | uint16_t q = d; 225 | d >>= 1; // in >> 6 226 | q += d; 227 | d >>= 2; // in >> 8 228 | q += d; 229 | d >>= 1; // in >> 9 230 | q += d; 231 | d >>= 2; // in >> 11 232 | q += d; 233 | d >>= 1; // in >> 12 234 | q += d; 235 | d >>= 2; // in >> 14 236 | q += d + 3; // correction. 237 | return q; 238 | } 239 | 240 | 241 | uint16_t ping2sixteenths(uint16_t in) 242 | { 243 | // divide by 4.669117646875 == * 0.214173228 244 | // uint16_t q = (in >> 3) + (in >> 4) + (in >> 6) + (in >> 7) + (in >> 9) + (in >> 10) + (in >> 12) + (in >> 14) ; 245 | uint16_t d = in >> 3; 246 | uint16_t q = d; 247 | d >>= 1; // in >> 4 248 | q += d; 249 | d >>= 2; // in >> 6 250 | q += d; 251 | d >>= 1; // in >> 7 252 | q += d; 253 | d >>= 2; // in >> 9 254 | q += d; 255 | d >>= 1; // in >> 10 256 | q += d; 257 | d >>= 2; // in >> 12 258 | q += d; 259 | d >>= 2; // in >> 14 260 | q += d + 3; // correction. 261 | return q; 262 | } 263 | 264 | 265 | ///////////////////////////////////////////////////////////////////////////////////// 266 | 267 | 268 | uint32_t ping2cm32(uint32_t in) 269 | { 270 | // divide by 29.41176 == * 0.034 271 | // uint32_t q = (in >> 5) + (in >> 9) + (in >> 11) + (in >> 12) + (in >> 14) 272 | // + (in >> 19) + (in >> 20) + (In >> 21) + (in >> 24) + (26, 28 29...; 273 | uint32_t d = in >> 5; 274 | uint32_t q = d; 275 | d >>= 4; // in >> 9 276 | q += d; 277 | d >>= 2; // in >> 11; 278 | q += d; 279 | d >>= 1; // in >> 12 280 | q += d; 281 | d >>= 2; // in >> 14 282 | q += d; 283 | d >>= 5; // in >> 19 284 | // q += d; 285 | // d >>= 1; // in >> 20 286 | // q += d; 287 | // d >>= 1; // in >> 21 288 | // q += d; 289 | // d >>= 3; // in >> 24 290 | // q += d; 291 | // d >>= 2; // in >> 26; 292 | // q += d; 293 | // d >>= 2; // in >> 28 294 | // q += d; 295 | // d >>= 1; // in >> 29 296 | q += d + 3; // rounding correction 297 | return q; 298 | } 299 | 300 | 301 | uint32_t ping2mm32(uint32_t in) 302 | { 303 | // divide by 2.941176 == * 0.34; 304 | // uint32_t q = (in >> 2) + (in >> 4) + (in >> 6) + (in >> 7) + (in >> 8) + (in >> 13); 305 | // 15, 19, 20, 21, 22, 24, 26, 27, 28 306 | uint32_t d = in >> 2; 307 | uint32_t q = d; 308 | d >>= 2; // in >> 4 309 | q += d; 310 | d >>= 2; // in >> 6 311 | q += d; 312 | d >>= 1; // in >> 7 313 | q += d; 314 | d >>= 1; // in >> 8 315 | q += d; 316 | d >>= 5; // in >> 13 317 | q += d; 318 | d >>= 2; // in >> 15 319 | q += d; 320 | d >>= 4; // in >> 19 321 | // q += d; 322 | // d >>= 1; // in >> 20 323 | // q += d; 324 | // d >>= 1; // in >> 21 325 | // q += d; 326 | // d >>= 1; // in >> 22 327 | // q += d; 328 | // d >>= 2; // in >> 24 329 | // q += d; 330 | // d >>= 2; // in >> 26 331 | // q += d; 332 | // d >>= 1; // in >> 27 333 | // q += d; 334 | // d >>= 1; // in >> 28 335 | q += d + 3; // rounding correction. 336 | return q; 337 | } 338 | 339 | 340 | ///////////////////////////////////////////////////////////////////////////////////// 341 | 342 | 343 | // temperature in Celsius 344 | float ping2cm_tempC(uint16_t duration, int Celsius ) 345 | { 346 | // 347 | // return duration * 331.45 * sqrt(1 + temp / 273.0) / 10000; 348 | // return duration * 331.45 * sqrt(1 + temp * (1.0 / 273.0)) * 0.0001; 349 | // return duration * 331.45 * (1 + temp * (1.0 / 546.0)) * 0.0001; // little less accurate sqrt 350 | return duration * (0.033145 + Celsius * (0.033145 / 546.0)); // minimized. 351 | } 352 | 353 | 354 | float ping2inch_tempC(uint16_t duration, int Celsius ) 355 | { 356 | // formula ping2cm_tempC converted 357 | return duration * (0.013049 + Celsius * (0.013049 / 546.0)); 358 | } 359 | 360 | 361 | float ping2inch_tempF(uint16_t duration, int Fahrenheit ) 362 | { 363 | // formula ping2inch_tempC converted 364 | // return duration * 331.45 * sqrt(1 + temp * (1.0 / 273.0)) * 0.0001; 365 | // inches 366 | // return duration * 130.49 * (1 + temp * (1.0 / 546.0)) * 0.0001; // little less accurate sqrt 367 | // Fahrenheit 368 | // return duration * (0.013049 + (Fahrenheit - 32) * (5.0/9.0) * (0.013049 / 546.0)); 369 | return duration * (0.013049 + (Fahrenheit - 32) * ((5.0/9.0) * (0.013049 / 546.0))); 370 | } 371 | 372 | 373 | /////////////////////////////////////////////////////////// 374 | // 375 | // FAST LOG2 + LOG10 + LOG 376 | // 377 | // from: https://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html 378 | // and several other places. 379 | // fast approximation for log2() 380 | // y = C[0]*f*f*f + C[1]*f*f + C[2]*f + C[3] + exponent; 381 | float fastLog2(float x) 382 | { 383 | int exponent; 384 | float value = frexpf(fabsf(x), &exponent); 385 | float y = 1.23149591368684f; 386 | y *= value; 387 | y += -4.11852516267426f; 388 | y *= value; 389 | y += 6.02197014179219f; 390 | y *= value; 391 | y += -3.13396450166353f; 392 | y += exponent; 393 | return y; 394 | } 395 | 396 | 397 | // log10(x) = log2(x) * 0.3010299956639812f // log10(2). 398 | float fastLog10(float x) 399 | { 400 | int exponent; 401 | float value = frexpf(fabsf(x), &exponent); 402 | float y = 1.23149591368684f; 403 | y *= value; 404 | y += -4.11852516267426f; 405 | y *= value; 406 | y += 6.02197014179219f; 407 | y *= value; 408 | y += -3.13396450166353f; 409 | y += exponent; 410 | return y * 0.3010299956639812f; 411 | } 412 | 413 | 414 | // log(x) = log2(x) * 0,6931471805599453f // log(2) 415 | float fastLog(float x) 416 | { 417 | int exponent; 418 | float value = frexpf(fabsf(x), &exponent); 419 | float y = 1.23149591368684f; 420 | y *= value; 421 | y += -4.11852516267426f; 422 | y *= value; 423 | y += 6.02197014179219f; 424 | y *= value; 425 | y += -3.13396450166353f; 426 | y += exponent; 427 | return y * 0.6931471805599453f; 428 | } 429 | 430 | 431 | 432 | /////////////////////////////////////////////////////////// 433 | // 434 | // TODO ... 435 | // 436 | 437 | 438 | // -- END OF FILE -- 439 | 440 | --------------------------------------------------------------------------------