{"id":13893784,"url":"https://github.com/RobTillaart/infiniteAverage","last_synced_at":"2025-07-17T08:30:48.426Z","repository":{"id":45332187,"uuid":"331574694","full_name":"RobTillaart/infiniteAverage","owner":"RobTillaart","description":"Arduino Library to calculate an average of many many samples","archived":false,"fork":false,"pushed_at":"2024-04-13T09:16:13.000Z","size":20,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T22:05:10.719Z","etag":null,"topics":["arduino","average","math","statistics"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2021-01-21T09:15:48.000Z","updated_at":"2023-11-09T12:28:58.000Z","dependencies_parsed_at":"2024-04-13T10:29:35.648Z","dependency_job_id":"c37faca1-b262-4a84-ad6a-a90a2102d30d","html_url":"https://github.com/RobTillaart/infiniteAverage","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/RobTillaart/infiniteAverage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FinfiniteAverage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FinfiniteAverage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FinfiniteAverage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FinfiniteAverage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/infiniteAverage/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FinfiniteAverage/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265585273,"owners_count":23792712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","average","math","statistics"],"created_at":"2024-08-06T18:01:17.136Z","updated_at":"2025-07-17T08:30:48.420Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":["C++"],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/infiniteAverage/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/infiniteAverage/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/infiniteAverage/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/infiniteAverage/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/infiniteAverage/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/infiniteAverage.svg)](https://github.com/RobTillaart/infiniteAverage/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/infiniteAverage/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/infiniteAverage.svg?maxAge=3600)](https://github.com/RobTillaart/infiniteAverage/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/infiniteAverage.svg)](https://registry.platformio.org/libraries/robtillaart/infiniteAverage)\n\n\n# infiniteAverage\n\nArduino Library to calculate an average of many samples.\n\n\n## Description\n\n**Experimental**\n\nThis library is an experimental library that cascades a float and a uint32_t type.\nIt was created from an idea when an overflow was encountered in my Statistic Class\ndue too many samples. https://github.com/RobTillaart/statistic\n\n\n### Problem\n\nAs an 32 bit float has ~7 decimals precision, after 10 million additions the sum\ndefinitely becomes 7 orders of magnitude larger than the individual samples. \nFrom that moment the addition will not increase the sum correctly or not at all.\n(assume you add values between 0-100 e.g. temperatures)\n\nTaking the average is taking the sum of the samples and divide that by the count.\nOnly if the count is fixed one could divide the samples first and then sum them.\nThis library supports the first scenario.\n\n\n### Idea \n\nTo cope with the overflow problem, this library uses an float combined with an uint32_t\nto represent the sum.\n\nThe float is used for the decimal part and the uint32_t for the whole part.\nIn theory this should give about 15 significant digits for the average in a 9.6 format.\nbut this precision is only internal to do some math. When the average() is calculated\nthe value returned is \"just\" a float.\n\n(since 0.1.2)\nIf the library detects that there are 4294967000 (almost 2^32) samples added or \nif the internal sum of samples reaches a threshold (default 2^30 ~~ 1 billion) , \nthe internal counter and sum are divided by 2. \nThat does not affect the minimum and maximum and the average only very slightly.\n\nSince 0.1.4 users can change this threshold and adjust it to data added.\nDepending on the data and maxValue per sample this can have side effects.\nUse at your own risk, so test its usability for your application.\n\n\n### Conclusion (for now)\n\nThe library allows two things\n1. take the average of many many samples where normally a summing float would \"overflow\"\n2. take the average of numbers that differ in order of magnitude.\n\n\n\n### Notes\n\n**Note** the practical meaning of the average of millions or billions of numbers \nis a discussion worth taking. Normally (often) the outliers are the most interesting. \n\n**Note** the library is not tested extensively, so use (with care) at your own risk.\n\n**Note** library does not support negative numbers yet. Planned for 0.2.0. \nFirst get more hands-on experience with it.\n\n\n### Related\n\nStatistic related libraries\n\n- https://github.com/RobTillaart/Correlation\n- https://github.com/RobTillaart/GST - Golden standard test metrics\n- https://github.com/RobTillaart/Histogram\n- https://github.com/RobTillaart/infiniteAverage\n- https://github.com/RobTillaart/RunningAngle\n- https://github.com/RobTillaart/RunningAverage\n- https://github.com/RobTillaart/RunningMedian\n- https://github.com/RobTillaart/statHelpers - combinations \u0026 permutations\n- https://github.com/RobTillaart/Statistic\n- https://github.com/RobTillaart/Student\n\nFor printing floats in scientific or engineering format\n- https://github.com/RobTillaart/printHelpers\n\n\n## Interface\n\n```cpp\n#include \"infiniteAverage.h\"\n```\n\n- **IAVG()** constructor, resets the internal counters to 0\n- **void reset()** resets the internal counters to 0\n- **void add(float value)** adds value to the internal float uint32_t pair.\n- **float decimals()** returns the internal float = decimals part.\n- **uint32_t whole()** returns the internal whole part.\n- **uint32_t count()** returns the number of values added. \nNote this may be scaled back a power of 2 (2,4,8,16, ...).\n- **float average()** returns the average in float format, or NAN if count == 0\n- **float minimum()** returns the minimum in float format, or NAN if count == 0\n- **float maximum()** returns the maximum in float format, or NAN if count == 0\n\n\n### 0.1.4\n\nUsers can set a threshold value to prevent the internal sum to overflow.\nDefault at startup this value is (1UL \u003c\u003c 30), and depending on the maxValue \nper sample added this should be set lower.\nWhen the threshold is reached both the sum and the internal counter are divided by 2.\nThis keeps the average almost the same.\n\nThe internal sample counter will trigger the divide by 2 action when 4294967000 \nsamples are added. That is a lot, roughly 1 samples per second for 130 years,\nor 1000 samples per second for 40 days.\n\n- **void setDivideThreshold(uint32_t threshold)**\n- **uint32_t getDivideThreshold()**\n\n\n### 0.1.5\n\n- Fixed a rounding error of the whole part when dividing by 2.\n\nThe threshold value should be as large as possible to get an accurate value.\nIf n is small compared to maxValue(sample) there will be side effects that\nmight break your project. The average will tend to the average of the last\nadded values. So be careful! \n\n\n## Operation\n\nSee examples\n\n\n## Future\n\n#### Must\n\n- improve documentation\n\n\n#### Should\n\nThis library has its limits which needs to be investigated.\n\nOne could upgrade the idea to a combination of a 8 byte double and a uint64_t\nto get around 28 significant digits =\u003e 18.10 format \n\n- investigate the decimal part which still has float inaccuracies when put to the limit.\n- investigate uint32_t for both decimal and whole part, \n  would give a 9.9 format. (how far are we from a BIGINT with comma position?)\n- add option to set a common \"order of magnitude (OOM)\" factor\n  - Compensate by dividing all samples by OOM.\n  This would allow to adjust to known order of size of the numbers.\n  (e.g. if numbers are all in the billions the uint32_t would overflow very fast)\n- investigate \"adaptive\" scaling, now there is a virtual border at 1, \n  but that could be at **value** (and might be user definable)\n- print interface?\n\n#### Could\n\n- investigate other math with this data type, starting with + - / \\* ?\n- printable interface?  sprintf() ?\n- add examples\n- printTo interface?\n\n\n#### 0.2.0\n\n- add negative numbers support.\n- add examples for negative numbers / mixed numbers.\n- move code from .h to .cpp\n\n\n#### Wont\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRobTillaart%2FinfiniteAverage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRobTillaart%2FinfiniteAverage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRobTillaart%2FinfiniteAverage/lists"}