{"id":17383121,"url":"https://github.com/clarity20/shellmath","last_synced_at":"2025-04-15T09:52:41.037Z","repository":{"id":179386510,"uuid":"264544331","full_name":"clarity20/shellmath","owner":"clarity20","description":"Yes, Virginia, you can do floating-point arithmetic in Bash!","archived":false,"fork":false,"pushed_at":"2023-09-28T23:26:21.000Z","size":247,"stargazers_count":35,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T19:07:12.901Z","etag":null,"topics":["arithmetic","bash","calculator","floating-point","linux","shell","shell-scripts"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clarity20.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2020-05-16T23:08:05.000Z","updated_at":"2025-01-04T03:52:33.000Z","dependencies_parsed_at":"2023-09-29T00:34:57.400Z","dependency_job_id":null,"html_url":"https://github.com/clarity20/shellmath","commit_stats":null,"previous_names":["clarity20/shellmath"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarity20%2Fshellmath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarity20%2Fshellmath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarity20%2Fshellmath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarity20%2Fshellmath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clarity20","download_url":"https://codeload.github.com/clarity20/shellmath/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249048711,"owners_count":21204305,"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":["arithmetic","bash","calculator","floating-point","linux","shell","shell-scripts"],"created_at":"2024-10-16T07:40:41.341Z","updated_at":"2025-04-15T09:52:41.019Z","avatar_url":"https://github.com/clarity20.png","language":"Shell","readme":"# Shellmath\nIntroducing floating-point arithmetic libraries for the Bash shell, because\nthey said it couldn't be done... and because:\n\n.\n\n![image info](./image.png)\n\n## Quick-start guide\nDownload this project and source the file `shellmath.sh` into your shell script,\nthen fire away at the shellmath API!\n\nThe ___basic___ API looks like this:\n```\n    _shellmath_add        arg1   arg2  [...]  argN\n    _shellmath_subtract   arg1   arg2               # means arg1 - arg2\n    _shellmath_multiply   arg1   arg2  [...]  argN\n    _shellmath_divide     arg1   arg2               # means arg1 / arg2\n```\n\nThe ___extended___ API introduces one more function:\n```\n    _shellmath_getReturnValue   arg\n```\n\nThis function optimizes away the need for ___$(___ subshelling ___)___ in order to capture `shellmath`'s output.\nTo use this feature, just be sure to set `__shellmath_isOptimized=1` at the top\nof your script. (You can find an example in `faster_e_demo.sh`.)\n\nOperands to the _shellmath_ functions can be integers or decimal\nnumbers presented in either standard or scientific notation:\n```\n    _shellmath_add   1.009   4.223e-2\n    _shellmath_getReturnValue   sum\n    echo \"The sum is $sum\"\n```\nAddition and multiplication are of arbitrary arity; try this on for size:\n```\n    _shellmath_multiply  1  2  3  4  5  6\n    _shellmath_getReturnValue   sixFactorial\n    echo \"6 factorial is $sixFactorial\"\n```\nSubtraction and division, OTOH, are exclusively binary operations. \n\n## The demos\nFor a gentle introduction to `shellmath` run the demo `slower_e_demo.sh` \nwith a small whole-number argument, say 15:\n```\n$ slower_e_demo.sh 15\ne = 2.7182818284589936\n```\n\nThis script uses a few `shellmath` API calls to calculate *e*, the mathematical\nconstant also known as [Euler's number](https://oeis.org/A001113). The argument \n*15* tells the script to evaluate the *15th-degree* Maclaurin polynomial for *e*.\n(That's the Taylor polynomial centered at 0.) Take a look inside the script to\nsee how it uses the `shellmath` APIs.\n\nThere is another demo script very much like this one but *different*, and the\nsensitive user can *feel* the difference. Try the following, but don't blink \nor you'll miss it ;)\n```\n$ faster_e_demo.sh 15\ne = 2.7182818284589936\n```\n\nDid you feel the difference? Try the `-t` option with both scripts; this will produce\ntiming statistics. Here are my results\nwhen running from my minGW64 command prompt on Windows 10 with an Intel i3 Core CPU:\n```\n$ for n in {1..5}; do faster_e_demo.sh -t 15 2\u003e\u00261; done | awk '/^real/ {print $2}'\n0m0.055s\n0m0.051s\n0m0.056s\n0m0.054s\n0m0.054s\n\n$ for n in {1..5}; do slower_e_demo.sh -t 15 2\u003e\u00261; done | awk '/^real/ {print $2}'\n0m0.498s\n0m0.594s\n0m0.536s\n0m0.511s\n0m0.580s\n```\n\n(When sizing up these timings, do keep in mind that ___we are timing the\ncalculation of e from its Maclaurin polynomial. Every invocation of either\nscript is exercising the shellmath arithmetic subroutines 31 times.___)\n\nThe comment header in `faster_e_demo.sh` explains the optimization and shows\nhow to put this faster version to work for you.\n\n## Competitive with awk and bc in runtime efficiency\nThe file `timingData.txt` captures the results of some timing experiments that compare \n`shellmath` against the GNU versions of the calculators `awk` and `bc`. The experiments\nexercised each of the arithmetic operations and captured the results in a shell variable.\nThe result summary below shows that `shellmath` is competitive with `awk` and runs faster\nthan `bc` in these experiments. (One commenter noted that the differences in execution speed\ncan be partially explained by the fact that `shellmath` and `awk` use finite precision \nwhereas `bc` uses arbitrary precision. Another factor in these measurements is the need to \nsubshell 'awk' and 'bc' to capture their results, whereas 'shellmath' writes directly to\nthe shell's global memory.)\n\nHere are the run times of `shellmath` as a percentage of the `awk` and `bc` equivalents:\n```\n                    versus awk    versus bc\n   Addition:          82.2%         40.6%\n   Subtraction:       95.9%         50.5%\n   Multiplication:   135.9%         73.3%\n   Division:          80.3%         43.2%\n```\n\nAstute observers will note the experiments provide approximations to the sum, difference, \nproduct, and quotient of *pi* and *e*. Unfortunately I did not gain insight as to which \nof these values, if any, are\n[transcendental](https://en.wikipedia.org/wiki/Transcendental_number#Possible_transcendental_numbers).\n\nYou can find a deeper discussion of shellmath's runtime efficiency\n[here](https://github.com/clarity20/shellmath/wiki/Shellmath-and-runtime-efficiency).\n\n## Background\nThe Bash shell does not have built-in operators for decimal arithmetic, making it\nsomething of an oddity among well-known, widely-used programming languages. For the most part,\npractitioners in need of powerful computational building blocks have naturally opted\nfor *other* languages and tools. Their widespread availability has diverted attention\nfrom the possibility of *implementing* decimal arithmetic in Bash and it's easy to assume\nthat this ***cannot*** be done:\n\n+ From the indispensable _Bash FAQ_ (on _Greg's Wiki_): [How can I calculate with floating point numbers?](http://mywiki.wooledge.org/BashFAQ/022)  \n  *\"For most operations... an external program must be used.\"*\n+ From Mendel Cooper's wonderful and encyclopedic _Advanced Bash Scripting Guide_:  \n  [Bash does not understand floating point arithmetic. Use bc instead.](https://tldp.org/LDP/abs/html/ops.html#NOFLOATINGPOINT)\n+ From a community discussion on Stack Overflow, _How do I use floating point division in bash?_  \n  The user's [preferred answer](https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division-in-bash#12722107)\n  is a good example of _prevailing thought_ on this subject.\n\nMeanwhile, \n\n+ Bash maintainer (BDFL?) Chet Ramey sounds a (brighter?) note in [The Bash Reference Guide, Section 6.5](https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic)\n  by emphasizing what the built-in arithmetic operators ***can*** do.\n\nBut finally, a glimmer of hope:\n\n+ A [diamond-in-the-rough](http://stackoverflow.com/a/24431665/3776858) buried elsewhere\n  on Stack Overflow.  \n  This down-and-dirty milestone computes the decimal quotient of two integer arguments. At a casual\n  glance, it seems to have drawn inspiration from the [Euclidean algorithm](https://mathworld.wolfram.com/EuclideanAlgorithm.html)\n  for computing GCDs, an entirely different approach than `shellmath`'s.\n\nPlease try `shellmath` on for size and draw your own conclusions!\n\n## How it works\n`shellmath` splits decimal numbers into their integer and fractional parts,\nperforms the appropriate integer operations on the parts, and recombines the results.\n(In the spirit of Bash, numerical overflow is silently ignored.)\n\nBecause if we can get carrying, borrowing, place value, and the distributive\nlaw right, then the sky's the limit! As they say--erm, as they ___said___ in Rome,\n\n        Ad astra per aspera.\n\n## And now...\nYou can run your floating-point calculations directly in Bash!\n\n## Please see also:\n[A short discussion on arbitrary precision and shellmath](https://github.com/clarity20/shellmath/wiki/Shellmath-and-arbitrary-precision-arithmetic)\n\n-- Michael Wood\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarity20%2Fshellmath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclarity20%2Fshellmath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarity20%2Fshellmath/lists"}