{"id":13481355,"url":"https://github.com/leegao/float-hacks","last_synced_at":"2025-10-23T17:24:16.506Z","repository":{"id":66915722,"uuid":"66583341","full_name":"leegao/float-hacks","owner":"leegao","description":"Floating Point Hacks","archived":false,"fork":false,"pushed_at":"2017-08-15T19:35:08.000Z","size":292,"stargazers_count":167,"open_issues_count":2,"forks_count":13,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-16T05:31:40.673Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://bullshitmath.lol","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/leegao.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}},"created_at":"2016-08-25T18:32:59.000Z","updated_at":"2025-03-05T17:18:03.000Z","dependencies_parsed_at":"2023-05-13T21:45:41.164Z","dependency_job_id":null,"html_url":"https://github.com/leegao/float-hacks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leegao%2Ffloat-hacks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leegao%2Ffloat-hacks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leegao%2Ffloat-hacks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leegao%2Ffloat-hacks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leegao","download_url":"https://codeload.github.com/leegao/float-hacks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243928284,"owners_count":20370262,"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":[],"created_at":"2024-07-31T17:00:51.132Z","updated_at":"2025-10-23T17:24:11.448Z","avatar_url":"https://github.com/leegao.png","language":"C++","funding_links":[],"categories":["Additional Resources","C++","Floats"],"sub_categories":[],"readme":"# Floating Point Hacks\n\n### Completely useless, but fun nevertheless.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/690b9db878741ab50045c64c303ad998.svg?invert_in_darkmode\" align=middle width=235.2768pt height=39.30498pt/\u003e\u003c/p\u003e\n\n\u003csub\u003e*Equations for a \"fast\" \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/3f5ce0fda24ff090e168fcbc2b6288a9.svg?invert_in_darkmode\" align=middle width=18.253455pt height=27.72pt/\u003e method.*\u003c/sub\u003e\n\n-------------------------------------\n\nTable of Contents\n=================\n\n* [Floating Point Hacks](#floating-point-hacks)\n  * [Usage](#usage)\n     * [For Contributors](#for-contributors)\n     * [Pow](#pow)\n     * [Exp](#exp)\n     * [Log](#log)\n     * [Geometric Mean](#geometric-mean)\n  * [Justification](#justification)\n     * [Prelude](#prelude)\n     * [Arbitrary Powers](#arbitrary-powers)\n     * [Exp](#exp-1)\n        * [Differentiating the l2f and \u003ccode\u003ef2l\u003c/code\u003e functions.](#differentiating-the-l2f-and-f2l-functions)\n        * [A Tale of Two Functions](#a-tale-of-two-functions)\n        * [Exp, redux.](#exp-redux)\n     * [Log](#log-1)\n     * [Geometric Mean](#geometric-mean-1)\n\n-------------------------------------\n\nThis repository contains a set of procedures to compute numerical methods in the vein of the\n[fast inverse root method](https://en.wikipedia.org/wiki/Fast_inverse_square_root). In particular,\nwe will generate code that\n\n1. Computes rational powers (\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/d49c11cb1a1f5ee6a6e609ab67b4f6bb.svg?invert_in_darkmode\" align=middle width=17.69757pt height=27.81669pt/\u003e) to an arbitrary precision.\n2. Computes irrational powers (\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1bed8656510c12b49e4a47c9a81e78ac.svg?invert_in_darkmode\" align=middle width=15.212505pt height=21.80211pt/\u003e) to within 10% relative error.\n3. Computes \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/559b96359a4653a6c35dbf27c11f68d2.svg?invert_in_darkmode\" align=middle width=47.211615pt height=24.5652pt/\u003e to within 10% relative error.\n4. Computes \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/38f816ed8d9782e71ecfd164e77c5150.svg?invert_in_darkmode\" align=middle width=43.33032pt height=24.5652pt/\u003e to within 10% relative error.\n5. Computes the geometric mean \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/c68457d92ea69ee4bcbeec172ff6d974.svg?invert_in_darkmode\" align=middle width=60.618525pt height=30.26991pt/\u003e of an `std::array` quickly to within 10% error.\n\nAdditionally, we will do so using mostly just integer arithmetic.\n\n## Usage\n\nYou can use everything in `floathacks` by including `hacks.h`\n\n    #include \u003cfloathacks/hacks.h\u003e\n    using namespace floathacks; // Comment this out if you don't want your top-level namespace to be polluted\n\n#### For Contributors\n\nThis document is compiled from `READOTHER.md` by `readme2tex`. Make sure that you `pip install readme2tex`. You\ncan run\n\n    python -m readme2tex --output README.md --branch svgs\n\nto recompile these docs.\n\n#### Pow\n\nTo generate an estimation for \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1bed8656510c12b49e4a47c9a81e78ac.svg?invert_in_darkmode\" align=middle width=15.212505pt height=21.80211pt/\u003e, where \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/3e18a4a28fdee1744e5e3f79d13b9ff6.svg?invert_in_darkmode\" align=middle width=7.087113pt height=14.10222pt/\u003e is any floating point number, you can run\n\n    float approximate_root = fpow\u003cFLOAT(0.12345)\u003e::estimate(x);\n\nSince estimates of `pow` can be refined into better iterates (as long as `c` is \"rational enough\"), you can also\ncompute a more exact result via\n\n    float root = pow\u003cFLOAT(0.12345), n\u003e(x);\n\nwhere `n` is the number of newton iterations to perform. The code generated by this template will unroll itself, so it's\nrelatively efficient.\n\nHowever, the optimized code does not let you use it as a `constexpr` or where the exponent is not constant. In those cases,\nyou can use `consts::fpow(x, c)` and `consts::pow(x, c, iterations = 2)` instead:\n\n    float root = consts::pow(x, 0.12345, n);\n\nNote that the compiler isn't able to deduce the optimal constants in these cases, so you'll incur additional penalties\ncomputing the constants of the method.\n\n#### Exp\n\nYou can also compute an approximation of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/559b96359a4653a6c35dbf27c11f68d2.svg?invert_in_darkmode\" align=middle width=47.211615pt height=24.5652pt/\u003e with\n\n    float guess = fexp(x);\n\nUnfortunately, since there are no refinement methods available for exponentials, we can't do much\nwith this result if it's too coarse for your needs. In addition, due to overflow, this method breaks down\nwhen `x` approaches 90.\n\n#### Log\n\nSimilarly, you can also compute an approximation of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/38f816ed8d9782e71ecfd164e77c5150.svg?invert_in_darkmode\" align=middle width=43.33032pt height=24.5652pt/\u003e with\n\n    float guess = flog(x);\n\nAgain, as is with the case of `fexp`, there are no refinement methods available for logarithms either.\n\nAll of the `f***` methods above have bounded relative errors of at most 10%. The refined `pow` method\ncan be made to give arbitrary precision by increasing the number of refinement iterations. Each refinement\niteration takes time proportional to the number of digits in the floating point representation of the exponent.\nNote that since floats are finite, this is bounded above by 32 (and more tightly, 23).\n\n#### Geometric Mean\n\nYou can compute the geometric mean (\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/c68457d92ea69ee4bcbeec172ff6d974.svg?invert_in_darkmode\" align=middle width=60.618525pt height=30.26991pt/\u003e) of a `std::array\u003cfloat, n\u003e` with\n\n    float guess = fgmean\u003c3\u003e({ 1, 2, 3 });\n\nThis can be refined, but you typically do not care about the absolute precision of a mean-like statistic.\nTo refine this, you can run Newton's method on \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/9f6ce9432d21290378ce4be4a814bbee.svg?invert_in_darkmode\" align=middle width=140.99184pt height=27.21543pt/\u003e. As far as I am aware, this is\nalso an original method.\n\n## Justification\n\n### Prelude\n\nThe key ingredient of these types of methods is the pair of transformations\n\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/b46a9543f58a8f4ef51bf513d0195b76.svg?invert_in_darkmode\" align=middle width=141.311775pt height=24.5652pt/\u003e and \n\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/8b1eb6ddb44c5ea9346105ed36f25424.svg?invert_in_darkmode\" align=middle width=141.077475pt height=24.5652pt/\u003e.\n\n* \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/014a505b8ec0a2e3dd98b6c8577cbdea.svg?invert_in_darkmode\" align=middle width=39.905745pt height=24.5652pt/\u003e takes a `IEEE 754` single precision floating point number and outputs its \"machine\" representation.\nIn essence, it acts like\n\n\n        unsigned long f2l(float x) {\n          union {float fl; unsigned long lg;} lens = { x };\n          return lens.lg;\n        }\n* \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/2484e1c18e94550c31824679fd30291d.svg?invert_in_darkmode\" align=middle width=38.88489pt height=24.5652pt/\u003e takes an unsigned long representing a float and returns a `IEEE 754` single precision floating point number.\nIt acts like\n\n\n        float l2f(unsigned long z) {\n          union {float fl; unsigned long lg;} lens = { z };\n          return lens.fl;\n        }\n\nSo for example, the fast inverse root method:\n\n      union {float fl; unsigned long lg;} lens = { x };\n      lens.lg = 0x5f3759df - lens.lg / 2;\n      float y = lens.fl;\n\ncan be equivalently expressed as\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1956bacf4be82337ef506b5f97ad6590.svg?invert_in_darkmode\" align=middle width=185.85105pt height=39.30498pt/\u003e\u003c/p\u003e\n\nIn a similar vein, a fast inverse cube-root method is presented at the start of this page.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/690b9db878741ab50045c64c303ad998.svg?invert_in_darkmode\" align=middle width=235.2768pt height=39.30498pt/\u003e\u003c/p\u003e\n\nWe will justify this in the next section.\n\n### Arbitrary Powers\n\nWe can approximate any \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1bed8656510c12b49e4a47c9a81e78ac.svg?invert_in_darkmode\" align=middle width=15.212505pt height=21.80211pt/\u003e using just integer arithmetic on the machine representation of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/332cc365a4987aacce0ead01b8bdcc0b.svg?invert_in_darkmode\" align=middle width=9.35979pt height=14.10222pt/\u003e. To do\nso, compute\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/85325d7348ff0db8a0a89d53e9cec59f.svg?invert_in_darkmode\" align=middle width=142.973985pt height=16.376943pt/\u003e\u003c/p\u003e\n\nwhere \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/763af86a1c2d443760aeb707325ee397.svg?invert_in_darkmode\" align=middle width=204.28353pt height=24.5652pt/\u003e. In general, any value of `bias`, as long\nas it is reasonably small, will work. At `bias = 0`, the method computes a value whose error is completely positive.\nTherefore, by increasing the bias, we can shift some of the error down into the negative plane and\nhalve the error. \n\nAs seen in the fast-inverse-root method, a bias of `-0x5c416` tend to work well for pretty much every case that I've\ntried, as long as we tack on at least one Newton refinement stage at the end. It works well without refinement as well,\nbut an even bias of `-0x5c000` works even better.\n\nWhy does this work? See [these slides](http://www.bullshitmath.lol/FastRoot.slides.html) for the derivation. In\nparticular, the fast inverse square-root is a subclass of this method.\n\n### Exp\n\nWe can approximate \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/559b96359a4653a6c35dbf27c11f68d2.svg?invert_in_darkmode\" align=middle width=47.211615pt height=24.5652pt/\u003e up to \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/b921a412dbb057d50cc70ebb4f18df62.svg?invert_in_darkmode\" align=middle width=47.606625pt height=21.10779pt/\u003e using a similar set of bit tricks. I'll first give its equation, and then\ngive its derivations. As far as I am aware, these are original. However, since there are no refinement methods\nfor the computation of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/559b96359a4653a6c35dbf27c11f68d2.svg?invert_in_darkmode\" align=middle width=47.211615pt height=24.5652pt/\u003e, there is practically no reason to ever resort to this approximation unless you're okay\nwith 10% error.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/dd860a34346bda9f243b20a8f2525b7f.svg?invert_in_darkmode\" align=middle width=313.85475pt height=19.85742pt/\u003e\u003c/p\u003e\n\nHere, \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/7ccca27b5ccc533a2dd72dc6fa28ed84.svg?invert_in_darkmode\" align=middle width=6.6473385pt height=14.10222pt/\u003e is the [machine epsilon](https://en.wikipedia.org/wiki/Machine_epsilon) for single precision, and it\nis computed by \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/e0032bb43ddccaa3ea0566c22746ee48.svg?invert_in_darkmode\" align=middle width=125.74419pt height=24.5652pt/\u003e.\n\nTo give a derivation of this equation, we'll need to borrow a few mathematical tools from analysis. In particular, while\n`l2f` and `f2l` have many discontinuities (\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/4f3b183ca15faf05b91c6ad7e3b6d7a5.svg?invert_in_darkmode\" align=middle width=14.716515pt height=26.70624pt/\u003e of them to be exact), it is mostly smooth. This\ncarries over to its \"rate-of-change\" as well, so we will just pretend that it has mostly smooth derivatives\neverywhere.\n\n#### Differentiating the `l2f` and `f2l` functions.\nConsider the function\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/12d8e344454774536a8da176b6cc638d.svg?invert_in_darkmode\" align=middle width=208.39995pt height=34.679205pt/\u003e\u003c/p\u003e\n\nwhere the equality is a consequence of the chain-rule, assuming that `f2l` is differentiable at the particular value of\n\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/210d22201f1dd53994dc748e91210664.svg?invert_in_darkmode\" align=middle width=30.86391pt height=24.5652pt/\u003e. Now, this raises an interesting question: What does it mean to take a derivative of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/014a505b8ec0a2e3dd98b6c8577cbdea.svg?invert_in_darkmode\" align=middle width=39.905745pt height=24.5652pt/\u003e?\n\nWell, it's not all that mysterious. The derivative of `f2l` is just the rate at which a number's IEEE 754 machine\nrepresentation changes as we make small perturbations to a number. Unfortunately, while it might be easy to compute\nthis derivative as a numerical approximation, we still don't have an approximate form for algebraic manipulation.\n\nWhile \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/c380902839f6237c1c6760127ad4ccfa.svg?invert_in_darkmode\" align=middle width=44.51766pt height=27.44082pt/\u003e might be difficult to construct, we can fair much better with its sibling, \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/ed9711acdecd664aa11a66b17111740a.svg?invert_in_darkmode\" align=middle width=44.51766pt height=27.44082pt/\u003e.\nNow, the derivative \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/ed9711acdecd664aa11a66b17111740a.svg?invert_in_darkmode\" align=middle width=44.51766pt height=27.44082pt/\u003e is the rate that a float will change given that we make small perturbations\nto its machine representation. However, since its machine representations are all bit-vectors, it doesn't make sense\nto take a derivative here since we can't make these perturbations arbitrarily small. The smallest change we can make\nis to either add or subtract one. However, if we just accept our fate, then we can define the \"derivative\" as the finite\ndifference\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/51b0758e839d40e093628d5fdad75d91.svg?invert_in_darkmode\" align=middle width=196.7394pt height=34.679205pt/\u003e\u003c/p\u003e\n\nwhere\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/594af30420fe403e3ecad1c72cd67c0e.svg?invert_in_darkmode\" align=middle width=262.6734pt height=44.137005pt/\u003e\u003c/p\u003e\n\nHere, equality holds when \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/71207e357beb2b5cf4f092c9ebcedc2a.svg?invert_in_darkmode\" align=middle width=39.905745pt height=24.5652pt/\u003e is a perfect power of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/76c5792347bb90ef71cfbace628572cf.svg?invert_in_darkmode\" align=middle width=8.188389pt height=21.10779pt/\u003e (including fractions of the form \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/99f338fcaa9681622b3f135c089bf43a.svg?invert_in_darkmode\" align=middle width=25.662945pt height=27.85266pt/\u003e).\n\nTherefore,\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/202b89eea44d638e1fee08bb018a0f17.svg?invert_in_darkmode\" align=middle width=132.98439pt height=17.81472pt/\u003e\u003c/p\u003e\n\nFrom here, we also have\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/95f95e0e442c68d11bba22f18d4752b1.svg?invert_in_darkmode\" align=middle width=451.5093pt height=216.1665pt/\u003e\u003c/p\u003e\n\n#### A Tale of Two Functions\n\nGiven \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/41bd2b9df7093e1c0caa2c5cade45afc.svg?invert_in_darkmode\" align=middle width=89.15874pt height=33.78408pt/\u003e, antidifferentiating both sides gives\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/ec4b015914608948961ad0b8aa7aca12.svg?invert_in_darkmode\" align=middle width=165.06105pt height=18.269295pt/\u003e\u003c/p\u003e\n\nSimilarly, since \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/4517ee70225fd1fbc2a56462aad1fb33.svg?invert_in_darkmode\" align=middle width=112.94085pt height=27.44082pt/\u003e satisfies \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/fe24365f266dbd2a3c942fa304305bde.svg?invert_in_darkmode\" align=middle width=50.365095pt height=24.66816pt/\u003e, we have\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/3742db4f3e50f5a3a2b9b24080b3b10e.svg?invert_in_darkmode\" align=middle width=125.461875pt height=16.376943pt/\u003e\u003c/p\u003e\n\nThis makes sense, since we'd like these two functions to be inverses of each other.\n\n#### Exp, redux.\n\nConsider\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1f804b1d46ed8b17c6969731592141ac.svg?invert_in_darkmode\" align=middle width=240.7647pt height=18.269295pt/\u003e\u003c/p\u003e\n\nwhich suggests that \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/02956f2e4eb289405ddb74c773002d97.svg?invert_in_darkmode\" align=middle width=171.25053pt height=27.94044pt/\u003e.\n\nSince we would like \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/fc627948191f20de9f76da56255cf0ff.svg?invert_in_darkmode\" align=middle width=76.09866pt height=24.5652pt/\u003e, we can impose the boundary condition\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/96ca7d2813c9f413253ffba263c6fee6.svg?invert_in_darkmode\" align=middle width=277.70985pt height=19.85742pt/\u003e\u003c/p\u003e\n\nwhich gives \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/168268e1451a8dfc43a23b8773d2ab42.svg?invert_in_darkmode\" align=middle width=73.484895pt height=24.5652pt/\u003e. However, while this method gives bounded relative error, in its unbiased form\nthis is pretty off the mark for general purposes (it approximates some other \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/80c5c65e2fa2a2d733d1ac16fa5b3acc.svg?invert_in_darkmode\" align=middle width=14.513565pt height=21.80211pt/\u003e). Instead, we can add in an unbiased form:\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/1768bdc96604f36fc58deea3f106c4f1.svg?invert_in_darkmode\" align=middle width=236.9136pt height=19.85742pt/\u003e\u003c/p\u003e\n\nwhere, empirically, \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/fd57f6d91f6e31899590811fc9f2128b.svg?invert_in_darkmode\" align=middle width=94.86114pt height=22.74558pt/\u003e gives a good approximation. Notice that the \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/4bdc8d9bcfb35e1c9bfb51fc69687dfc.svg?invert_in_darkmode\" align=middle width=7.0283235pt height=22.74558pt/\u003e we've chosen is close to\n\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/23f78e0b2a6bbbadec2d25ce8d5a81a0.svg?invert_in_darkmode\" align=middle width=44.33715pt height=26.70624pt/\u003e, which is what we need to transform \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/80c5c65e2fa2a2d733d1ac16fa5b3acc.svg?invert_in_darkmode\" align=middle width=14.513565pt height=21.80211pt/\u003e to \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/b6b70db98c2a5c2031dea120886f8211.svg?invert_in_darkmode\" align=middle width=15.05196pt height=21.80211pt/\u003e.\nIn particular, for all \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/55a049b8f161ae7cfeb0197d75aff967.svg?invert_in_darkmode\" align=middle width=9.829875pt height=14.10222pt/\u003e, the \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/596205e74b63d939fb386f5456910cf6.svg?invert_in_darkmode\" align=middle width=17.673315pt height=26.70624pt/\u003e, \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/e8831293b846e3a3799cd6a02e4a0cd9.svg?invert_in_darkmode\" align=middle width=17.673315pt height=26.70624pt/\u003e, and \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/72d8c986bb268cc5845e6aa7b3d3ce0f.svg?invert_in_darkmode\" align=middle width=24.201375pt height=22.38159pt/\u003e relative error is always below 10%.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"http://i.imgur.com/Kr7dcSz.png\"/\u003e\u003c/p\u003e\n\n### Log\n\nIn a similar spirit, we can use the approximation\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/ec4b015914608948961ad0b8aa7aca12.svg?invert_in_darkmode\" align=middle width=165.06105pt height=18.269295pt/\u003e\u003c/p\u003e\n\nto derive\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/a59a6cf3ffdb2becd3ffa45eacf5df41.svg?invert_in_darkmode\" align=middle width=177.48225pt height=16.376943pt/\u003e\u003c/p\u003e\n\nImposing a boundary condition at \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/8614628c35cbd72f9732b246c2e4d7b8.svg?invert_in_darkmode\" align=middle width=39.41817pt height=21.10779pt/\u003e gives \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/168268e1451a8dfc43a23b8773d2ab42.svg?invert_in_darkmode\" align=middle width=73.484895pt height=24.5652pt/\u003e, so we should expect\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/7774c7653eb46407ac10b0ebf9f0ab66.svg?invert_in_darkmode\" align=middle width=203.3361pt height=16.376943pt/\u003e\u003c/p\u003e\n\nHowever, this actually computes some other logarithm \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/c6774276dd6e07aabea5c2d3725f52b4.svg?invert_in_darkmode\" align=middle width=50.026845pt height=24.5652pt/\u003e, and we'll have to, again, unbias this term\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/7bacde2da21534aaaf06d6f354884c15.svg?invert_in_darkmode\" align=middle width=301.46325pt height=16.376943pt/\u003e\u003c/p\u003e\n\nwhere the \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/2bf3e29d19ad9f0c0758e54dcc9fdf9b.svg?invert_in_darkmode\" align=middle width=50.70483pt height=24.5652pt/\u003e term came from the fact that the base computation approximates the 2-logarithm. Empirically, I've\nfound that a bias of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/a6bb6f6852e5def4a2ac06b15cdee7a8.svg?invert_in_darkmode\" align=middle width=86.672685pt height=22.74558pt/\u003e works well. In particular, for all \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/55a049b8f161ae7cfeb0197d75aff967.svg?invert_in_darkmode\" align=middle width=9.829875pt height=14.10222pt/\u003e, the \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/596205e74b63d939fb386f5456910cf6.svg?invert_in_darkmode\" align=middle width=17.673315pt height=26.70624pt/\u003e,\n\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/e8831293b846e3a3799cd6a02e4a0cd9.svg?invert_in_darkmode\" align=middle width=17.673315pt height=26.70624pt/\u003e, and \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/72d8c986bb268cc5845e6aa7b3d3ce0f.svg?invert_in_darkmode\" align=middle width=24.201375pt height=22.38159pt/\u003e relative error is always below 10%.\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"http://i.imgur.com/TsjGPwc.png\"/\u003e\u003c/p\u003e\n\n### Geometric Mean\n\nThere's a straightforward derivation of the geometric mean. Consider the approximations of \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/28653a190084a1cb3afa50867e89bc25.svg?invert_in_darkmode\" align=middle width=17.302725pt height=23.60787pt/\u003e and \u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/708d35d0117081328cfd6b94751faca6.svg?invert_in_darkmode\" align=middle width=18.58131pt height=23.60787pt/\u003e,\nwe can refine them as\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/4fce83c43066f0d63a49f27bdf7543ed.svg?invert_in_darkmode\" align=middle width=197.8218pt height=45.00837pt/\u003e\u003c/p\u003e\n\nTherefore, a bit of algebra will show that\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/829691d57c701ef3292701cf056b54c7.svg?invert_in_darkmode\" align=middle width=215.03295pt height=40.178325pt/\u003e\u003c/p\u003e\n\nwhich reduces to the equation for the geometric mean. \n\nNotice that we just add a series of integers, followed by\nan integer divide, which is pretty efficient.\n\n-------------------------------------\n\nFor more information on how the constant (\u003cimg src=\"https://rawgit.com/leegao/fast-inverse-cube-root/svgs/svgs/020b87e24d0ffe9a99194ef0411648e7.svg?invert_in_darkmode\" align=middle width=78.24564pt height=22.74558pt/\u003e) is derived for\nthe cube-root, visit http://www.bullshitmath.lol/.\n\nEquations rendered with [readme2tex](https://github.com/leegao/readme2tex).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleegao%2Ffloat-hacks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleegao%2Ffloat-hacks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleegao%2Ffloat-hacks/lists"}