{"id":16692514,"url":"https://github.com/ckormanyos/wide-integer","last_synced_at":"2025-04-04T08:05:16.053Z","repository":{"id":37289166,"uuid":"152905142","full_name":"ckormanyos/wide-integer","owner":"ckormanyos","description":"Wide-Integer implements a generic C++ template for uint128_t, uint256_t, uint512_t, uint1024_t, etc.","archived":false,"fork":false,"pushed_at":"2024-10-11T09:24:05.000Z","size":2110,"stargazers_count":187,"open_issues_count":5,"forks_count":33,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-10-13T16:27:21.081Z","etag":null,"topics":["arbitrary-precision","arbitrary-precision-integer","big-integer","embedded-systems","high-performance","multiprecision","numerical","uint128","uint24","uint256","uint48","uint512"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckormanyos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","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":"2018-10-13T19:03:19.000Z","updated_at":"2024-10-11T09:24:05.000Z","dependencies_parsed_at":"2023-10-16T06:31:58.240Z","dependency_job_id":"31f5b652-14a8-4f2e-a06b-c33b81ceee6f","html_url":"https://github.com/ckormanyos/wide-integer","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/ckormanyos%2Fwide-integer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckormanyos%2Fwide-integer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckormanyos%2Fwide-integer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckormanyos%2Fwide-integer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckormanyos","download_url":"https://codeload.github.com/ckormanyos/wide-integer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247139625,"owners_count":20890262,"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":["arbitrary-precision","arbitrary-precision-integer","big-integer","embedded-systems","high-performance","multiprecision","numerical","uint128","uint24","uint256","uint48","uint512"],"created_at":"2024-10-12T16:27:23.495Z","updated_at":"2025-04-04T08:05:16.023Z","avatar_url":"https://github.com/ckormanyos.png","language":"C++","readme":"﻿Wide-integer\n==================\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer/actions\"\u003e\n        \u003cimg src=\"https://github.com/ckormanyos/wide-integer/actions/workflows/wide_integer.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer/actions\"\u003e\n        \u003cimg src=\"https://github.com/ckormanyos/wide-integer/actions/workflows/wide_integer_fuzzing.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc\"\u003e\n        \u003cimg src=\"https://custom-icon-badges.herokuapp.com/github/issues-raw/ckormanyos/wide-integer?logo=github\" alt=\"Issues\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer/actions?query=workflow%3ACodeQL\"\u003e\n        \u003cimg src=\"https://github.com/ckormanyos/wide-integer/actions/workflows/CodeQL.yml/badge.svg\" alt=\"CodeQL\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://scan.coverity.com/projects/ckormanyos-wide-integer\"\u003e\n        \u003cimg src=\"https://scan.coverity.com/projects/24742/badge.svg\" alt=\"Coverity Scan\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://sonarcloud.io/summary/new_code?id=ckormanyos_wide-integer\"\u003e\n        \u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=ckormanyos_wide-integer\u0026metric=alert_status\" alt=\"Quality Gate Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.codacy.com/gh/ckormanyos/wide-integer/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=ckormanyos/wide-integer\u0026amp;utm_campaign=Badge_Grade\"\u003e\n        \u003cimg src=\"https://app.codacy.com/project/badge/Grade/40d129959071441b9780e68998514226\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/ckormanyos/wide-integer\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/ckormanyos/wide-integer/branch/master/graph/badge.svg?token=kiBP4MAjdV\" alt=\"code coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer/blob/master/LICENSE_1_0.txt\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-BSL%201.0-blue.svg\" alt=\"Boost Software License 1.0\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://img.shields.io/github/commit-activity/y/ckormanyos/wide-integer\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/commit-activity/y/ckormanyos/wide-integer\" alt=\"GitHub commit activity\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ckormanyos/wide-integer\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/languages/code-size/ckormanyos/wide-integer\" alt=\"GitHub code size in bytes\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://godbolt.org/z/Gj7cEc3jc\" alt=\"godbolt\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/try%20it%20on-godbolt-green\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nWide-integer implements a generic C++ template for extended width\nunsigned and signed integral types.\n\nThis C++ template header-only library implements drop-in big integer types\nsuch as `uint128_t`, `uint256_t`, `uint384_t`, `uint512_t`, `uint1024_t`, `uint1536_t`, etc.\nThese can be used essentially like regular built-in integers.\nCorresponding _signed_ integer types such as `int128_t`, `int256_t`, and the like\ncan also be used.\n\nThe big integer class is called `math::wide_integer::uintwide_t`\n(i.e., `uintwide_t` residing in the `namespace` `math::wide_integer`),\nas shown in greater detail below.\n\nWide-integer supports both unsigned as well as\nsigned integral types having width of\n$1 {\\ldots} 63 {\\times} 2^N$\nwhile being $16$, $24$, $32$ or larger.\nIn addition, small integer types such as software-synthesized versions of\n`uint24_t`, `uint48_t`, `uint64_t`, `uint96_t`, `uint128_t`, etc.\n(or signed counterparts of these) can also be created with wide-integer.\n\nWe also emphasize here that less-common types (i.e., those less common than, say,\n`uint128_t`, `uint256_t`, `uint512_t`, etc.) can also be synthesized.\nTypes such as `uint80_t` made from five 16-bit limbs,\nor `uint96_t` composed of three 32-bit limbs, or\nother similar types can be readily synthesized with wide-integer.\n\nWide-integer also features basic realizations of several\nelementary and number theoretical functions such as root finding,\nrandom distribution, Miller-Rabin primality testing,\ngreatest common denominator (GCD), least common multiplier (LCM),\ninteger division (i.e., `divmod()`) and more.\n\nInclusion of a single C++14 header file\nis all that is needed for using wide-integer,\nas shown in the [examples](./examples).\n\n## Implementation goals\n\n  - Signed and unsigned versions of `uintwide_t` should behave as closely as possible to the behaviors of signed and unsigned versions of built-in `int`.\n  - Relatively wide precision range from $24$, $32$, $64$ bits up to tens of thousands of bits.\n  - Moderately good efficiency over the entire wide precision range.\n  - Clean header-only C++14 design.\n  - Seamless portability to any modern C++14, 17, 20, 23 compiler and beyond.\n  - Scalability with small memory footprint and efficiency suitable for both PC/workstation systems as well as _bare-metal_ embedded systems.\n  - C++14, 17, 20, 23 and beyond `constexpr`-ness.\n\n## Quick start\n\nWhen working in your own project with wide-integer,\nusing the [`uintwide_t.h` header](./math/wide_integer/uintwide_t.h)\nis straightforward. Identify the header within\nits directory. Include this header path to the compiler's set\nof include paths or in your project.\nThen simply `#include \u003cuintwide_t.h\u003e` the normal C++ way.\n\nEasy application follows via traditional C-style typedef or alias\nsuch as `uint512_t`. An instance of the defined type can be used very much\nlike a built-in integral type.\n\nIn the following code, for example,\nthe static `uint512_t` variable `x` is initialized with unsigned, integral value `3U`.\nThe `main` subroutine subsequently computes $3^{301}$ with the specialized\nwide-integer, namespace-specific function `pow`, which is found via ADL.\n\nThe approximate result is\n\n$$3^{301}~{\\approx}~4.10674{\\times}~10^{143}\\text{.}$$\n\nSee also the following informative links to Wolfram Alpha(R).\n\n  - Query the approximate value of $3^{301}$ with [`N[3^301]`](https://www.wolframalpha.com/input?i=N%5B3%5E301%5D)\n  - Verify the exact value of $3^{301}$ with [`3^301`](https://www.wolframalpha.com/input?i=3%5E301)\n\nThis example, compiled with successful output result,\nis shown in its entirety in the following\n[short link](https://godbolt.org/z/bjxxrK1xP) to [godbolt](https://godbolt.org).\n\nIn particular,\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\n#include \u003ciostream\u003e\n\nauto main() -\u003e int\n{\n  using uint512_t = ::math::wide_integer::uintwide_t\u003c512U, std::uint32_t\u003e;\n\n  const uint512_t x { 3U };\n\n  const auto p3 = pow(x, 301);\n\n  // 410674437175765127973978082146264947899391086876012309414440570235106991532497229781400618467066824164751453321793982128440538198297087323698003\n  std::cout \u003c\u003c \"p3: \" \u003c\u003c p3 \u003c\u003c std::endl;\n\n  std::cout \u003c\u003c \"Cast p3 to double: \" \u003c\u003c double { p3 } \u003c\u003c std::endl;\n}\n```\n\nThe code sequence above defines the local data type `uint512_t` with\nan alias. The first template parameter `512U` sets the binary width\n(or bit count) while the second optional template parameter `std::uint32_t`\nsets the internal _limb_ _type_. The limb type must be unsigned and one of\n`std::uint8_t`, `std::uint16_t`, `std::uint32_t` or on some systems\n`std::uint64_t`. If the second template parameter `LimbType` is left blank,\nthe default limb type is thirty-two bits in width and unsigned.\n\nThe complete template signature of the `uintwide_t` class is shown below.\n\n```cpp\nnamespace math::wide_integer {\n\nnamespace detail { using size_t = std::uint32_t; }\n\nusing detail::size_t;\n\n// Forward declaration of the uintwide_t template class.\ntemplate\u003cconst size_t Width2,\n         typename LimbType      = std::uint32_t,\n         typename AllocatorType = void,\n         const bool IsSigned    = false\u003e\nclass uintwide_t;\n\n} // namespace math::wide_integer\n```\n\n`uintwide_t` also has a third optional template paramter that\nis used to set the _allocator_ _type_ employed for internal storage of the\nbig integer's data. The default allocator type is `void`\nand `uintwide_t` uses stack allocation with an `std::array`-like internal representation.\nSetting the allocator type to an actual allocator such as,\nfor instance, `std::allocator\u003climb_type\u003e` activates allocator-based\ninternal storage for `uintwide_t`.\nUsing allocator-based storage reduces stack consumption and\ncan be especially beneficial for higher digit counts.\nFor low digit counts, the allocator type can\nsimply be left blank (thus defaulting to `void`)\nor explicitly be set to `void` and stack allocation\nwill be used in either case.\n\nIf an allocator is supplied with any granularity other than `limb_type`\n(in other words `LimbType`) such as `std::allocator\u003cvoid\u003e`, `custom_allocator_type\u003cchar\u003e`, etc.,\nthen the `uintwide_t` class will internally _rebind_ the allocator\nto the granularity and `unsigned`-ness of `limb_type` using `rebind_alloc`\nfrom `std::allocator_traits`.\n\nThe fourth template parameter `IsSigned` can be set to `true`\nto activate a signed integer type. If left blank,\nthe default value of `IsSigned` is  `false`\nand the integer type will be unsigned.\n\n## Examples\n\nVarious interesting and algorithmically challenging\n[examples](./examples) have been implemented.\nIt is hoped that the examples provide inspiration and guidance\non how to use wide-integer.\n\n  - ![`example000_numeric_limits.cpp`](./examples/example000_numeric_limits.cpp) verifies parts of the specializations of `std::numeric_limits` for (unsigned) `uint256_t`and (signed) `int256_t`.\n  - ![`example000a_builtin_convert.cpp`](./examples/example000a_builtin_convert.cpp) exercises some conversions to/from built-in types/`uintwide_t`.\n  - ![`example001_mul_div.cpp`](./examples/example001_mul_div.cpp) performs multiplication and division.\n  - ![`example001a_div_mod.cpp`](./examples/example001a_div_mod.cpp) exercises division and modulus calculations.\n  - ![`example002_shl_shr.cpp`](./examples/example002_shl_shr.cpp) does a few left and right shift operations.\n  - ![`example003_sqrt.cpp`](./examples/example003_sqrt.cpp) computes a square root.\n  - ![`example003a_cbrt`](./examples/example003a_cbrt.cpp) computes a cube root.\n  - ![`example004_rootk_pow.cpp`](./examples/example004_rootk_pow.cpp) computes an integral seventh root and its corresponding power. A negative-valued cube root is also tested.\n  - ![`example005_powm.cpp`](./examples/example005_powm.cpp) tests the power-modulus function `powm`.\n  - ![`example005a_pow_factors_of_p99.cpp`](./examples/example005a_pow_factors_of_p99.cpp) verifies a beautiful, known prime factorization result from a classic tabulated value.\n  - ![`example006_gcd.cpp`](./examples/example006_gcd.cpp) tests several computations of greatest common divisor using the `gcd` function.\n  - ![`example007_random_generator.cpp`](./examples/example007_random_generator.cpp) computes some large pseudo-random integers.\n  - ![`example008_miller_rabin_prime.cpp`](./examples/example008_miller_rabin_prime.cpp) implements primality testing via Miller-Rabin.\n  - ![`example008a_miller_rabin_prime.cpp`](./examples/example008a_miller_rabin_prime.cpp) verifies Boost's interpretation of Miller-Rabin primality testing using `uintwide_t`-based types.\n  - ![`example009_timed_mul.cpp`](./examples/example009_timed_mul.cpp) measures multiplication timings.\n  - ![`example009a_timed_mul_4_by_4.cpp`](./examples/example009a_timed_mul_4_by_4.cpp) also measures multiplication timings for the special case of wide integers having four limbs.\n  - ![`example009b_timed_mul_8_by_8.cpp`](./examples/example009b_timed_mul_8_by_8.cpp) measures, yet again, multiplication timings for the special case of wide integers having eight limbs.\n  - ![`example010_uint48_t.cpp`](./examples/example010_uint48_t.cpp) verifies 48-bit integer caluclations.\n  - ![`example011_uint24_t.cpp`](./examples/example011_uint24_t.cpp) performs calculations with 24-bits, which is definitely on the small side of the range of wide-integer.\n  - ![`example012_rsa_crypto.cpp`](./examples/example012_rsa_crypto.cpp) performs cryptographic calculations with 2048-bits, exploring a standardized test case.\n  - ![`example013_ecdsa_sign_verify.cpp`](./examples/example013_ecdsa_sign_verify.cpp) provides an intuitive view on elliptic-curve algebra, depicting a well-known cryptographic key-gen/sign/verify method.\n  - ![`example014_pi_spigot_wide.cpp`](./examples/example014_pi_spigot_wide.cpp) calculates $10,001$ decimal digits of the mathematical constant $\\pi$ using a `uintwide_t`-based template spigot algorithm.\n\n## Building\n\n### Build Status\n\n[![Build Status](https://github.com/ckormanyos/wide-integer/actions/workflows/wide_integer.yml/badge.svg)](https://github.com/ckormanyos/wide-integer/actions)\n\nThe recent status of building and executing the tests and examples\nin Continuous Integration (CI) is always shown in the Build Status banner.\nAdditional banners from other syntax checks and builds may also be visible.\n\nIt is also possible, if desired, to build and execute\nthe tests and examples using various different OS/compiler\ncombinations.\n\n### Build with Microsoft Visual Studio\n\nBuilding and running the tests and examples can be accomplished\nusing the Microsoft VisualStudio solution workspace provided\nin `wide_integer.sln`, `wide_integer_vs2022.sln`, etc.\nThe MSVC solution file(s) are located in the project's root directory.\n\n### Build with CMake\n\nYou can also build and run tests and examples from an empty directory\nusing CMake. Follow the CMake pattern:\n\n```sh\ncmake /path/to/wide-integer\ncmake --build .\nctest --verbose\n```\n\n### Build on the *nix command line\n\nAlternatively building the tests and examples with native GCC (i.e., on *nix)\ncan be executed with a simple, but rather lengthy, command line\nentered manually from the command shell.\nConsider, for instance, building in Linux with GCC in the presence of `unsigned` `__int128`.\nFurthermore, the Boost.Multiprecision library is used for some examples and tests.\nIn this build example, Boost is intended to be located\nin the made-up directory `../boost-root`,\nwhich needs to be adapted according to the actual location of Boost.\nThe command line below illustrates how to build all\nof the wide_integer tests and examples directly\nfrom the *nix command line.\n\n```sh\ncd wide_integer\ng++                                         \\\n-finline-functions                          \\\n-finline-limit=32                           \\\n-march=native                               \\\n-mtune=native                               \\\n-O3                                         \\\n-Wall                                       \\\n-Wextra                                     \\\n-Wpedantic                                  \\\n-Wconversion                                \\\n-Wsign-conversion                           \\\n-Wno-maybe-uninitialized                    \\\n-Wno-cast-function-type                     \\\n-std=c++14                                  \\\n-DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64         \\\n-I.                                         \\\n-I../boost-root                             \\\n-pthread                                    \\\n-lpthread                                   \\\ntest/test.cpp                               \\\ntest/test_uintwide_t_boost_backend.cpp      \\\ntest/test_uintwide_t_edge_cases.cpp         \\\ntest/test_uintwide_t_examples.cpp           \\\ntest/test_uintwide_t_float_convert.cpp      \\\ntest/test_uintwide_t_int_convert.cpp        \\\ntest/test_uintwide_t_n_base.cpp             \\\ntest/test_uintwide_t_n_binary_ops_base.cpp  \\\ntest/test_uintwide_t_spot_values.cpp        \\\nexamples/example000_numeric_limits.cpp      \\\nexamples/example000a_builtin_convert.cpp    \\\nexamples/example001_mul_div.cpp             \\\nexamples/example001a_div_mod.cpp            \\\nexamples/example002_shl_shr.cpp             \\\nexamples/example003_sqrt.cpp                \\\nexamples/example003a_cbrt.cpp               \\\nexamples/example004_rootk_pow.cpp           \\\nexamples/example005_powm.cpp                \\\nexamples/example005a_pow_factors_of_p99     \\\nexamples/example006_gcd.cpp                 \\\nexamples/example007_random_generator.cpp    \\\nexamples/example008_miller_rabin_prime.cpp  \\\nexamples/example008a_miller_rabin_prime.cpp \\\nexamples/example009_timed_mul.cpp           \\\nexamples/example009a_timed_mul_4_by_4.cpp   \\\nexamples/example009b_timed_mul_8_by_8.cpp   \\\nexamples/example010_uint48_t.cpp            \\\nexamples/example011_uint24_t.cpp            \\\nexamples/example012_rsa_crypto.cpp          \\\nexamples/example013_ecdsa_sign_verify.cpp   \\\nexamples/example014_pi_spigot_wide.cpp      \\\n-o wide_integer.exe\n```\n\n## Testing, CI and Quality Checks\n\n### Testing\n\nTesting is definitely a big issue. A growing, supported\ntest suite improves confidence in the library.\nIt provides for tested, efficient functionality on the PC and workstation.\nThe GitHub code is, as mentioned above, delivered with an affiliated MSVC\nproject or a variety of other build/make options that use easy-to-understand\nsubroutines called from `main()`. These exercise the various\nexamples and the full suite of test cases.\n\nIf an issue is reported, reproduced and verified, an attempt\nis made to correct it without breaking any other\ncode. Upon successful correction, specific test cases\nexercising the reported issue are usually added as part\nof the issue resolution process.\n\n### CI and Quality checks\n\nCI runs on both push-to-branch as well as pull request using GitHub Actions.\nVarious compilers, operating systems, and C++ standards\nranging from C++14, 17, 20, 23 are included in CI.\n\nIn CI, we use both elevated GCC/clang compiler warnings\nas well as MSVC level 4 warnings active on the correspondoing platforms.\nFor additional in-depth syntax checking, clang-tidy is used both in CI\nas well as in offline checks to improve static code quality.\n\nGCC's run-time\n[sanitizers](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)\nare used in CI in order to help assure dynamic quality.\nThis effort also includes _fuzzing_ with\n[libFuzzer](https://llvm.org/docs/LibFuzzer.html).\n\nAdditional quality checks are performed on pull-request\nand merge to master using modern third party open-source services.\nThese include\n[CodeQL](https://github.com/ckormanyos/wide-integer/actions?query=workflow%3ACodeQL),\n[Synopsis Coverity](https://scan.coverity.com/projects/ckormanyos-wide-integer),\nand [CodeSonar](https://sonarcloud.io/summary/new_code?id=ckormanyos_wide-integer).\nAt the moment, the Coverity check is run with manual report submission.\nAutomation of this is, however, planned.\n\nCode coverage uses GCC/gcov/lcov and has a\nquality-gate with comparison/baseline-check provided by\n[Codecov](https://app.codecov.io/gh/ckormanyos/wide-integer).\n\nQuality badges are displayed at the top of this repository's\nreadme page.\n\n## Detailed examples\n\nWe will now present various straightforward detailed examples.\n\nThe code below performs some elementary algebraic calculations\nwith a simple mixture of 256-bit and 512-bit unsigned integral types.\n\nThis example, compiled with successful output result,\nis shown in its entirety in the following\n[short link](https://godbolt.org/z/Gj7cEc3jc) to [godbolt](https://godbolt.org).\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003csstream\u003e\n\nauto main() -\u003e int\n{\n  using uint256_t = ::math::wide_integer::uint256_t;\n  using uint512_t = ::math::wide_integer::uint512_t;\n\n  // Construction from string. Additional constructors\n  // are available from other built-in types.\n\n  const uint256_t a(\"0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE\");\n  const uint256_t b(\"0x166D63E0202B3D90ECCEAA046341AB504658F55B974A7FD63733ECF89DD0DF75\");\n\n  // Elementary arithmetic operations.\n  const uint512_t c = (uint512_t(a) * uint512_t(b));\n  const uint256_t d = (a / b);\n\n  // Logical comparison.\n  const auto result_is_ok = (   (c == \"0x1573D6A7CEA734D99865C4F428184983CDB018B80E9CC44B83C773FBE11993E7E491A360C57EB4306C61F9A04F7F7D99BE3676AAD2D71C5592D5AE70F84AF076\")\n                             \u0026\u0026 (d == \"0xA\"));\n\n  // Print the hexadecimal representation string output.\n  std::stringstream strm;\n\n  strm \u003c\u003c \"0x\" \u003c\u003c std::hex \u003c\u003c std::uppercase \u003c\u003c c \u003c\u003c '\\n';\n  strm \u003c\u003c \"0x\" \u003c\u003c std::hex \u003c\u003c std::uppercase \u003c\u003c d \u003c\u003c '\\n';\n\n  // Visualize if the result is OK.\n\n  strm \u003c\u003c \"result_is_ok: \" \u003c\u003c std::boolalpha \u003c\u003c result_is_ok;\n\n  std::cout \u003c\u003c strm.str() \u003c\u003c std::endl;\n}\n```\n\nWide-integer also supports a small selection of number-theoretical\nfunctions such as least and most significant bit,\nsquare root, $k^{th}$ root,\npower, power-modulus, greatest common denominator\nand random number generation.\nThese functions are found via ADL.\n\nThe example below calculates an integer square root.\n\nThis example, compiled with successful output result,\nis shown in its entirety in the following\n[short link](https://godbolt.org/z/KofWbMq8M) to [godbolt](https://godbolt.org).\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n\nauto main() -\u003e int\n{\n  using uint256_t = ::math::wide_integer::uint256_t;\n\n  const uint256_t a(\"0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE\");\n\n  const uint256_t s = sqrt(a);\n\n  const auto result_is_ok = (s == \"0xFA5FE7853F1D4AD92BDF244179CA178B\");\n\n  const auto flg = std::cout.flags();\n\n  std::cout \u003c\u003c \"result_is_ok: \" \u003c\u003c std::boolalpha \u003c\u003c result_is_ok \u003c\u003c std::endl;\n\n  std::cout.flags(flg);\n\n  return (result_is_ok ? 0 : -1);\n}\n```\n\nThe following sample performs add, subtract, multiply and divide of `uint48_t`.\nSee this example also in the following\n[short link](https://godbolt.org/z/hc8GWMhed) to [godbolt](https://godbolt.org).\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003crandom\u003e\n#include \u003csstream\u003e\n\nauto main() -\u003e int\n{\n  using uint48_t = ::math::wide_integer::uintwide_t\u003cstatic_cast\u003cmath::wide_integer::size_t\u003e(UINT32_C(48)), std::uint8_t\u003e;\n\n  using distribution_type  = ::math::wide_integer::uniform_int_distribution\u003cstatic_cast\u003cmath::wide_integer::size_t\u003e(UINT32_C(48)), typename uint48_t::limb_type\u003e;\n\n  using random_engine_type = std::linear_congruential_engine\u003cstd::uint32_t, UINT32_C(48271), UINT32_C(0), UINT32_C(2147483647)\u003e;\n\n  random_engine_type generator(static_cast\u003cstd::uint32_t\u003e(UINT32_C(0xF00DCAFE))); // NOLINT(cert-msc32-c,cert-msc51-cpp,cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)\n\n  distribution_type distribution;\n\n  const auto a64 = static_cast\u003cstd::uint64_t\u003e(distribution(generator));\n  const auto b64 = static_cast\u003cstd::uint64_t\u003e(distribution(generator));\n\n  const uint48_t a(a64);\n  const uint48_t b(b64);\n\n  const uint48_t c_add = (a + b);\n  const uint48_t c_sub = (a - b);\n  const uint48_t c_mul = (a * b);\n  const uint48_t c_div = (a / b);\n\n  const auto result_is_ok = (   (   (c_add == static_cast\u003cstd::uint64_t\u003e((a64 + b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (c_sub == static_cast\u003cstd::uint64_t\u003e((a64 - b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (c_mul == static_cast\u003cstd::uint64_t\u003e((a64 * b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (c_div == static_cast\u003cstd::uint64_t\u003e((a64 / b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF)))))\n                             \u0026\u0026\n                                (   (static_cast\u003cstd::uint64_t\u003e(c_add) == static_cast\u003cstd::uint64_t\u003e((a64 + b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (static_cast\u003cstd::uint64_t\u003e(c_sub) == static_cast\u003cstd::uint64_t\u003e((a64 - b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (static_cast\u003cstd::uint64_t\u003e(c_mul) == static_cast\u003cstd::uint64_t\u003e((a64 * b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))\n                                 \u0026\u0026 (static_cast\u003cstd::uint64_t\u003e(c_div) == static_cast\u003cstd::uint64_t\u003e((a64 / b64) \u0026 static_cast\u003cstd::uint64_t\u003e(UINT64_C(0x0000FFFFFFFFFFFF))))));\n\n  std::stringstream strm { };\n\n  strm \u003c\u003c \"result_is_ok: \" \u003c\u003c std::boolalpha \u003c\u003c result_is_ok;\n\n  std::cout \u003c\u003c strm.str() \u003c\u003c std::endl;\n}\n```\n\nThe next example computes the real-valued cube root of $10^{3,333}$.\nThe real-valued cube root of this very large unsigned integer is $10^{1,111}$.\nWe will use the (somewhat uncommon) integral data type `uint11264_t`.\nSince `uint11264_t` has approximately $3,390$ decimal digits of precision,\nit is large enough to hold the value of $10^{3,333}$\nprior to (and following) the cube root operation.\n\nSee this example fully worked out at the following\n[short link](https://godbolt.org/z/nE1eq7h6M) to [godbolt](https://godbolt.org)\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003csstream\u003e\n\nauto main() -\u003e int\n{\n  using uint11264_t = ::math::wide_integer::uintwide_t\u003c11264U, std::uint32_t\u003e;\n\n  // Create the string '1' + 3,333 times '0', which is\n  // equivalent to the decimal integral value 10^3333.\n\n  const std::string str_a = \"1\" + std::string(3333U, '0');\n\n  const uint11264_t a = str_a.data();\n\n  const uint11264_t s = cbrt(a);\n\n  // Create the string '1' + 1,111 times '0', which is\n  // equivalent to the decimal integral value 10^1111.\n  // (This is the cube root of 10^3333.)\n\n  const std::string str_control = \"1\" + std::string(1111U, '0');\n\n  const auto result_is_ok = (s == uint11264_t(str_control.data()));\n\n  std::stringstream strm { };\n\n  strm \u003c\u003c s;\n\n  strm \u003c\u003c \"\\nresult_is_ok: \" \u003c\u003c std::boolalpha \u003c\u003c result_is_ok;\n\n  std::cout \u003c\u003c strm.str() \u003c\u003c std::endl;\n}\n```\n\n## Additional details\n\nWide-Integer has been tested with numerous compilers, for target systems ranging from eight to sixty-four bits.\nThe library is specifically designed for efficiency with small to medium bit counts.\nSupported bit counts include integers\n$1 {\\ldots} 63 {\\times} 2^N$\nwhile being $16$, $24$, $32$ or larger such as\n$256$, $384$, $512$, $768$, $1024$,\nor other less common bit counts such as $11,264$, etc.\n\nSmall, medium and large bit counts are supported.\nCommon applications might use the range of `uint128_t`, `uint256_t` or `uint512_t`.\nIt is also possible to make\nsoftware-synthesized (not very efficient) versions of `uint24_t`, `uint32_t` or `uint48_t`,\nwhich might useful for hardware prototyping or other simulation and verification needs.\nOn the high-digit end, Karatsuba multiplication extends the high performance range\nto many thousands of bits. Fast long division, however, relies on a classical algorithm\nand sub-quadratic high-precision division is not yet implemented.\n\nPortability of the code is another key point of focus. Special care\nhas been taken to test in certain high-performance embedded real-time\nprogramming environments.\n\n### Configuration macros (compile-time)\n\nVarious configuration features can optionally be\nenabled or disabled at compile time with the compiler switches:\n\n```cpp\n#define WIDE_INTEGER_DISABLE_IOSTREAM\n#define WIDE_INTEGER_DISABLE_TO_STRING\n#define WIDE_INTEGER_DISABLE_FLOAT_INTEROP\n#define WIDE_INTEGER_DISABLE_IMPLEMENT_UTIL_DYNAMIC_ARRAY\n#define WIDE_INTEGER_HAS_LIMB_TYPE_UINT64\n#define WIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL\n#define WIDE_INTEGER_DISABLE_TRIVIAL_COPY_AND_STD_LAYOUT_CHECKS\n#define WIDE_INTEGER_NAMESPACE\n#define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS\n#define WIDE_INTEGER_HAS_CLZ_LIMB_OPTIMIZATIONS\n```\n\nWhen working with even the most tiny microcontroller systems,\nI/O streaming can optionally be disabled with the compiler switch:\n\n```cpp\n#define WIDE_INTEGER_DISABLE_IOSTREAM\n```\n\nThe default setting is `WIDE_INTEGER_DISABLE_IOSTREAM` not set\nand I/O streaming operations are enabled.\n\nConversion to `std::string` is supported with the specialized wide-integer, namespace-specific function\n`to_string`. This analagous to the standard library's `std::to_string` function,\nbut implemented specifically for instances of `uintwide_t`.\nWide-integer's local, namespace-specific `to_string`\nfunction (and the inclusion of the necessary `\u003cstring\u003e` header)\nare both deactivated with:\n\n```cpp\n#define WIDE_INTEGER_DISABLE_TO_STRING\n```\n\nInteroperability with built-in floating-point types\nsuch as construct-from, cast-to, binary arithmetic with\nbuilt-in floating-point types can be\noptionally disabled by defining:\n\n```cpp\n#define WIDE_INTEGER_DISABLE_FLOAT_INTEROP\n```\n\nThe default setting is `WIDE_INTEGER_DISABLE_FLOAT_INTEROP` not set\nand all available functions implementing construction-from,\ncast-to, binary arithmetic with built-in floating-point types\nare enabled.\n\n```cpp\n#define WIDE_INTEGER_DISABLE_IMPLEMENT_UTIL_DYNAMIC_ARRAY\n```\n\nThis macro disables `uintwide_t.h`'s own local implementation\nof the `util::dynamic_array` template class.\nThe logic of this macro is negated. Its default setting\n(of being disabled itself) ensures that standalone `uintwide_t.h`\nis free from any additional header dependencies.\n\nThe template utility class `util::dynamic_array` is used\nas a storage container for certain instantiations of `uintwide_t`.\nThis macro is disabled by default and `uintwide_t.h`\ndoes actually provide its own local implementation\nof the `util::dynamic_array` template class.\nOtherwise, the header file `\u003cutil/utility/util_dynamic_array.h\u003e`\nmust be found in the include path.\n\nWhen working on high-performance systems having `unsigned __int128`\n(an extended-width, yet non-standard data type),\na 64-bit limb of type `uint64_t` can be used.\nEnable the 64-bit limb type on such systems\nwith the compiler switch:\n\n```cpp\n#define WIDE_INTEGER_HAS_LIMB_TYPE_UINT64\n```\n\nor (when using GCC, clang or similar) on the compiler\ncommand line with:\n\n```cpp\n-DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64\n```\n\nThis macro is disabled by default.\n\nThe example below, for instance, uses a 64-bit limb type\non GCC or clang.\n\n```cpp\n#define WIDE_INTEGER_HAS_LIMB_TYPE_UINT64\n\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\nusing uint_fast256_t = ::math::wide_integer::uintwide_t\u003c256U, std::uint64_t\u003e;\n\nstatic uint_fast256_t x = 42U;\n```\n\nAnother potential optimization macro can be activated with:\n\n```cpp\n#define WIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL\n```\n\nThis macro might improve performance on some target/compiler systems\nby manually unrolling the multiplication loop(s) for\n`uintwide_t` instances having eight limbs. This macro is disabled\nby default.\n\n```cpp\n#define WIDE_INTEGER_DISABLE_TRIVIAL_COPY_AND_STD_LAYOUT_CHECKS\n```\n\nThis macro disables compile-time checks for `std::is_trivially_copyable`\nand `std::is_standard_layout`. These checks provide assurance\n(among other attributes) that `uintwide_t`'s constructors\nsatisfy rules needed for mixed-language C/C++ usage.\nSome older legacy target/compiler systems might have non-standard\nor incomplete STL implementations that lack these compile-time\ntemplates. For such compilers, it makes sense to deactivate\nthese compile-time checks via activation of this macro.\nThis macro is disabled by default and both the trivially-copyable\nas well as the standard-layout compile-time checks are active.\n\n```cpp\n#define WIDE_INTEGER_NAMESPACE something_unique\n```\n\nThis is an advanced macro intended to be used in strict, exacting applications for which\nusing the unqualified, global namespace `math` (i.e., `namespace` `::math`) is undesired or inacceptable.\nWe recall that all parts of the wide-integer implementation,\nsuch as the `uintwide_t` class and its associated implementation\ndetails reside within `namespace` `::math::wide_integer`\n\nDefining the macro `WIDE_INTEGER_NAMESPACE` to be something like,\nfor instance,\n\n```sh\n-DWIDE_INTEGER_NAMESPACE=something_unique\n```\n\nplaces all parts of the wide-integer implementation and its details\nwithin the prepended outer namespace `something_unique` -\nas in\n\n```cpp\nnamespace something_unique::math::wide_integer\n{\n  // ...\n}\n```\n\nWhen utilizing the `WIDE_INTEGER_NAMESPACE` option,\nthe actual name or nesting depth of the desired prepended\nouter namespace can be varied if (or as) needed\nfor the particular project.\n\nBy default the macro `WIDE_INTEGER_NAMESPACE` is not defined.\nIn this default state, `namespace` `::math::wide_integer` is used\nand the `uintwide_t` class and its associated implementation\ndetails reside therein.\n\n```cpp\n#define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS\n```\n\nThis optional macro can be used to switch `uintwide_t`'s\ndata member access from _private_ to _public_. This allows the\n`uintwide_t` class to be used as a so-called _structured_ class,\nsuch as is needed for constant-valued template parameters\nin a `constexpr` context.\nThis preprocessor switch was invented based on the discussion in\n[issue 335](https://github.com/ckormanyos/wide-integer/issues/335)\n\nMaking private data members public is unusual for some designs.\nSo the preprocessor switch `WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS`\nis not defined (i.e., not set) by default. This ensures that\n`uintwide_t`'s data members remain private by default.\n\n```cpp\n#define WIDE_INTEGER_HAS_CLZ_LIMB_OPTIMIZATIONS\n```\n\nThis optional macro activates certain optimizations\nthat count leading zero-limbs prior to classical quadratic\nmultiplication. This may offer performance advantages on some systems\nby avoiding some potentially costly zero-valued limb-multiplication steps.\n\nThis preprocessor switch was motivated by the discussion in\n[issue 362](https://github.com/ckormanyos/wide-integer/issues/362)\n\nBy default, the preprocessor switch `WIDE_INTEGER_HAS_CLZ_LIMB_OPTIMIZATIONS`\nis not defined and CLZ-limb optimizations are default-_disabled_.\n\n### C++14, 17, 20, 23 and beyond `constexpr` support\n\n`uintwide_t` supports C++14, 17, 20, 23 and beyond compile-time\n`constexpr`-ness for all constructions, casts, operations,\nevaluation of function results, etc.\n\nThe code below, for instance, shows compile-time instantiations\nof `uintwide_t` from character strings with subsequent `constexpr` evaluations\nof binary operations multiply, divide, intergal cast and comparison.\n\nSee this example fully worked out at the following\n[short link](https://godbolt.org/z/avWGasbdj) to [godbolt](https://godbolt.org).\nThe generated assembly includes nothing other than the call to `main()`\nand its subsequent `return` of the value zero\n(i.e., `main()`'s successful return-value in this example).\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\nusing uint256_t = ::math::wide_integer::uintwide_t\u003c256U\u003e;\nusing uint512_t = ::math::wide_integer::uintwide_t\u003c512U\u003e;\n\n// Compile-time construction from string.\nconstexpr auto a = uint256_t(\"0xF4DF741DE58BCB2F37F18372026EF9CBCFC456CB80AF54D53BDEED78410065DE\");\nconstexpr auto b = uint256_t(\"0x166D63E0202B3D90ECCEAA046341AB504658F55B974A7FD63733ECF89DD0DF75\");\n\n// Compile time binary arithmetic operations.\nconstexpr auto c = uint512_t(a) * uint512_t(b);\nconstexpr auto d = uint256_t(a / b);\n\n// Compile-time comparison.\nconstexpr auto result_is_ok = (   (c == \"0x1573D6A7CEA734D99865C4F428184983CDB018B80E9CC44B83C773FBE11993E7E491A360C57EB4306C61F9A04F7F7D99BE3676AAD2D71C5592D5AE70F84AF076\")\n                               \u0026\u0026 (static_cast\u003cstd::uint_fast8_t\u003e(d) == static_cast\u003cstd::uint_fast8_t\u003e(UINT8_C(10))));\n\n// constexpr verification.\nstatic_assert(result_is_ok, \"Error: example is not OK!\");\n\nauto main() -\u003e int { }\n```\n\n### Signed integer support\n\nSigned big integers are also supported in the wide_integer library.\nUse the fourth template partameter `IsSigned` to indicate the\nsigned-_ness_ (or unsigned-_ness_) of `uintwide_t`.\nThe code below, for instance, uses an aliased version of\nsigned `int256_t`.\n\n```cpp\n#include \u003cmath/wide_integer/uintwide_t.h\u003e\n\nusing int256_t = ::math::wide_integer::uintwide_t\u003c256U, std::uint32_t, void, true\u003e;\n\nconst int256_t n1(-3);\nconst int256_t n2(-3);\n\n// +9\nconst int256_t n3 = n1 * n2;\n```\n\n### Negative arguments in number theoretical functions\n\nThe following design choices have been implemented when handling\nnegative arguments in number theoretical functions.\n\n  - Right shift by `n` bits via `operator\u003e\u003e(n)` performs a so-called _arithmetic_ right shift (ASHR). For signed integers having negative value, right-shift continually fills the sign bit with 1 while shifting right. The result is similar to signed division and closely mimics common compiler behavior for right-shift of negative-valued built-in signed `int`.\n  - `sqrt` of `x` negative returns zero.\n  - `cbrt` of `x` nexative integer returns `-cbrt(-x)`.\n  - $k^{th}$ root of `x` negative returns zero unless the cube root is being computed, in which case `-cbrt(-x)` is returned.\n  - GCD and LCM of `a`, `b` signed convert both arguments to positive and negate the result for `a`, `b` having opposite signs.\n  - Miller-Rabin primality testing treats negative inetegers as positive when testing for prime, thus extending the set of primes to negative integers.\n  - MSB/LSB (most/least significant bit) do not differentiate between positive or negative argument such that MSB of a negative integer will be the highest bit of the corresponding unsigned type.\n  - Printing both positive-valued and negative-valued signed integers in hexadecimal format is supported. When printing negative-valued, signed  `uintwide_t` in hexadecimal format, the sign bit and all other bits are treated as if the integer were unsigned. The negative sign is not explicitly shown when using hexadecimal format, even if the underlying integer is signed and negative-valued. A potential positive sign, however, will be shown for positive-valued signed integers in hexadecimal form in the presence of `std::showpos`.\n  - Signed integer division and modulus results obtained from the `divmod()` function follow established number-theoretical rounding conventions, which are the same as those used by the `//`-operator in Python-3 (i.e., the same as Python-3's built-in `divmod()` function). These conventions also match those used by Mathematica(R)'s `QuotientRemainder[]` function.\n\n## Further details\n\n### Notable construction/conversion rules\n\nThe following notable construction/conversion rules have been implemented\nin the wide-integer project.\n\n  - Constructions-from built-in types are implicit. These are considered widening conversions.\n  - Casts to built-in types are explicit and considered narrowing, regardless of the widths of left-and-right hand sides of the conversion.\n  - All of both constructions-from as well as casts-to wider/less-wide and signed/unsigned wide-integer types are implicit (even if the conversion at hand is narrowing via having fewer bits). Casts such as `int128_t` to/from `uint160_t` and similar, for instance, are implicit.\n  - All wide-integer-types are move constructable.\n  - All wide-integer types having the same widths and having the same limb-type (but possibly different sign) are move-assignable and `std::move()`-capable.\n\n### Importing and exporting characters and bits\n\nFor sufficiently modern standards-conforming compilers,\nnamespace-specific functions `to_chars()` and `from_chars()`\nare available. These each have the _usual_ `\u003ccharconv\u003e`-like\nbehavior, known from C++17. For motivational words on\n`to_chars()` and `from_chars()`,\nsee also [issue 153](https://github.com/ckormanyos/wide-integer/issues/153)\nand [issue 398](https://github.com/ckormanyos/wide-integer/issues/398).\n\nSupport for importing and exporting bits is granted by the subroutines\n`import_bits()` and `export_bits()`. Their interfaces, input/output forms\nand constraints are intended to be identical with those used in\n[Boost's import/export-bits functions](https://www.boost.org/doc/libs/1_80_0/libs/multiprecision/doc/html/boost_multiprecision/tut/import_export.html).\n\n### Alternatives and limitations\n\nAlternative libraries for big integral types include,\namong others, most notably\n[GMP](https://gmplib.org/)\nand\n[`Boost.Multiprecision`](https://www.boost.org/doc/libs/1_79_0/libs/multiprecision/doc/html/index.html).\n\nAt the moment, the digit range of wide-integer is limited\nto the granularity of the full limb type.\nThis means that less-common bit counts\nrequiring the use of non-full limbs\nare not supported. It is **not** possible with this library,\nfor instance, to synthesize, let's say, a 61-bit integral type.\n\nThis can have performance impact. If you would like\nto synthesize an 80-bit integral type, for example, this can\nbe done, but at the cost of using five 16-bit limbs.\nThis degrades performance due to the higher limb count.\nThis phenomenon was discussed in\n[issue 234](https://github.com/ckormanyos/wide-integer/issues/234)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckormanyos%2Fwide-integer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckormanyos%2Fwide-integer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckormanyos%2Fwide-integer/lists"}