{"id":1393,"url":"https://github.com/attaswift/BigInt","last_synced_at":"2025-08-06T13:33:02.793Z","repository":{"id":38953386,"uuid":"48700429","full_name":"attaswift/BigInt","owner":"attaswift","description":"Arbitrary-precision arithmetic in pure Swift","archived":false,"fork":false,"pushed_at":"2024-07-02T13:18:47.000Z","size":3825,"stargazers_count":760,"open_issues_count":16,"forks_count":105,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-10-29T20:38:13.085Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","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/attaswift.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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":"2015-12-28T16:05:12.000Z","updated_at":"2024-10-29T04:58:22.000Z","dependencies_parsed_at":"2024-11-05T23:33:06.170Z","dependency_job_id":"80b1bb56-3124-43af-897c-c8a9933f4a31","html_url":"https://github.com/attaswift/BigInt","commit_stats":{"total_commits":369,"total_committers":27,"mean_commits":"13.666666666666666","dds":"0.20867208672086723","last_synced_commit":"793a7fac0bfc318e85994bf6900652e827aef33e"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attaswift%2FBigInt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attaswift%2FBigInt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attaswift%2FBigInt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/attaswift%2FBigInt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/attaswift","download_url":"https://codeload.github.com/attaswift/BigInt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228466342,"owners_count":17924727,"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-01-05T20:15:45.413Z","updated_at":"2024-12-09T14:31:08.403Z","avatar_url":"https://github.com/attaswift.png","language":"Swift","funding_links":[],"categories":["Math","Libs","Swift","Math [🔝](#readme)"],"sub_categories":["Other Hardware","Math","Other free courses"],"readme":"[![BigInt](https://github.com/attaswift/BigInt/raw/master/images/banner.png)](https://github.com/attaswift/BigInt)\n\n* [Overview](#overview)\n* [API Documentation](#api)\n* [License](#license)\n* [Requirements and Integration](#integration)\n* [Implementation Notes](#notes)\n    * [Why is there no generic `BigInt\u003cDigit\u003e` type?](#generics)\n* [Calculation Samples](#samples)\n\t* [Obligatory factorial demo](#factorial)\n\t* [RSA Cryptography](#rsa)\n\t* [Calculating the Digits of π](#pi)\n\n[![Swift](https://github.com/attaswift/BigInt/actions/workflows/swift.yml/badge.svg?branch=master)](https://github.com/attaswift/BigInt/actions/workflows/swift.yml)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fattaswift%2FBigInt%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/attaswift/BigInt)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fattaswift%2FBigInt%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/attaswift/BigInt)\n\n\u003c!-- [![Code Coverage](https://codecov.io/github/attaswift/BigInt/coverage.svg?branch=master)](https://codecov.io/github/attaswift/BigInt?branch=master) --\u003e\n\n## \u003ca name=\"overview\"\u003eOverview\u003c/a\u003e\n\nThis repository provides [integer types of arbitrary width][wiki] implemented\nin 100% pure Swift. The underlying representation is in base 2^64, using `Array\u003cUInt64\u003e`.\n\n[wiki]: https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic\n\nThis module is handy when you need an integer type that's wider than `UIntMax`, but\nyou don't want to add [The GNU Multiple Precision Arithmetic Library][GMP]\nas a dependency.\n\n[GMP]: https://gmplib.org\n\nTwo big integer types are included: [`BigUInt`][BigUInt] and [`BigInt`][BigInt],\nthe latter being the signed variant.\nBoth of these are Swift structs with copy-on-write value semantics, and they can be used much\nlike any other integer type.\n\nThe library provides implementations for some of the most frequently useful functions on\nbig integers, including\n\n- All functionality from [`Comparable`][comparison] and [`Hashable`][hashing]\n\n- [The full set of arithmetic operators][addition]: `+`, `-`, `*`, `/`, `%`, `+=`, `-=`, `*=`, `/=`, `%=`\n  - [Addition][addition] and [subtraction][subtraction] have variants that allow for\n    shifting the digits of the second operand on the fly.\n  - Unsigned subtraction will trap when the result would be negative.\n    ([There are variants][subtraction] that return an overflow flag.)\n  - [Multiplication][mul] uses brute force for numbers up to 1024 digits, then switches to Karatsuba's recursive method.\n    (This limit is configurable, see `BigUInt.directMultiplicationLimit`.)\n  - A [fused multiply-add][fused] method is also available, along with other [special-case variants][multiplication].\n  - [Division][division] uses Knuth's Algorithm D, with its 3/2 digits wide quotient approximation.\n    It will trap when the divisor is zero.\n  - [`BigUInt.divide`][divide] returns the quotient and\n    remainder at once; this is faster than calculating them separately.\n\n- [Bitwise operators][bitwise]: `~`, `|`, `\u0026`, `^`, `|=`, `\u0026=`, `^=`, plus the following read-only properties:\n  - [`bitWidth`][width]: the minimum number of bits required to store the integer,\n  - [`trailingZeroBitCount`][trailingZeroBitCount]: the number of trailing zero bits in the binary representation,\n  - [`leadingZeroBitCount`][leadingZeroBitCount]: the number of leading zero bits (when the last digit isn't full),\n\n- [Shift operators][shift]: `\u003e\u003e`, `\u003c\u003c`, `\u003e\u003e=`, `\u003c\u003c=`\n\n- Methods to [convert `NSData` to big integers][data] and vice versa.\n\n- Support for [generating random integers][random] of specified maximum width or magnitude.\n\n- Radix conversion to/from [`String`s][radix1] and [big integers][radix2] up to base 36 (using repeated divisions).\n  - Big integers use this to implement `StringLiteralConvertible` (in base 10).\n\n- [`sqrt(n)`][sqrt]: The square root of an integer (using Newton's method).\n\n- [`BigUInt.gcd(n, m)`][GCD]: The greatest common divisor of two integers (Stein's algorithm).\n\n- [`base.power(exponent, modulus)`][powmod]: Modular exponentiation (right-to-left binary method).\n  [Vanilla exponentiation][power] is also available.\n- [`n.inverse(modulus)`][inverse]: Multiplicative inverse in modulo arithmetic (extended Euclidean algorithm).\n- [`n.isPrime()`][prime]: Miller–Rabin primality test.\n\nThe implementations are intended to be reasonably efficient, but they are unlikely to be\ncompetitive with GMP at all, even when I happened to implement an algorithm with same asymptotic\nbehavior as GMP. (I haven't performed a comparison benchmark, though.)\n\nThe library has 100% unit test coverage. Sadly this does not imply that there are no bugs\nin it.\n\n## \u003ca name=\"api\"\u003eAPI Documentation\u003c/a\u003e\n\nGenerated API docs are available at https://attaswift.github.io/BigInt/.\n\n## \u003ca name=\"license\"\u003eLicense\u003c/a\u003e\n\nBigInt can be used, distributed and modified under [the MIT license][license].\n\n## \u003ca name=\"integration\"\u003eRequirements and Integration\u003c/a\u003e\n\nBigInt 4.0.0 requires Swift 4.2 (The last version with support for Swift 3.x was BigInt 2.1.0.\nThe last version with support for Swift 2 was BigInt 1.3.0.)\n\n| Swift Version | last BigInt Version|\n| ------------- |:-------------------|\n| 3.x           | 2.1.0              |\n| 4.0           | 3.1.0              |\n| 4.2           | 4.0.0              |\n| 5.x           | 5.4.0              |\n\n\nBigInt deploys to macOS 10.10, iOS 9, watchOS 2 and tvOS 9.\nIt has been tested on the latest OS releases only---however, as the module uses very few platform-provided APIs,\nthere should be very few issues with earlier versions.\n\nBigInt uses no APIs specific to Apple platforms, so\nit should be easy to port it to other operating systems.\n\nSetup instructions:\n\n- **Swift Package Manager:**\n  Although the Package Manager is still in its infancy, BigInt provides experimental support for it.\n  Add this to the dependency section of your `Package.swift` manifest:\n\n    ```Swift\n    .package(url: \"https://github.com/attaswift/BigInt.git\", from: \"5.4.0\")\n    ```\n\n## \u003ca name=\"notes\"\u003eImplementation notes\u003c/a\u003e\n\n[`BigUInt`][BigUInt] is a `MutableCollectionType` of its 64-bit digits, with the least significant\ndigit at index 0. As a convenience, [`BigUInt`][BigUInt] allows you to subscript it with indexes at\nor above its `count`. [The subscript operator][subscript] returns 0 for out-of-bound `get`s and\nautomatically extends the array on out-of-bound `set`s. This makes memory management simpler.\n\n[`BigInt`][BigInt] is just a tiny wrapper around a `BigUInt` [absolute value][magnitude] and a\n[sign bit][negative], both of which are accessible as public read-write properties.\n\n### \u003ca name=\"generics\"\u003eWhy is there no generic `BigInt\u003cDigit\u003e` type?\u003c/a\u003e\n\nThe types provided by `BigInt` are not parametric—this is very much intentional, as\nSwift generics cost us dearly at runtime in this use case. In every approach I tried,\nmaking arbitrary-precision arithmetic operations work with a generic `Digit` type parameter\nresulted in code that was literally *ten times slower*. If you can make the algorithms generic\nwithout such a huge performance hit, [please enlighten me][twitter]!\n\nThis is an area that I plan to investigate more, as it would be useful to have generic\nimplementations for arbitrary-width arithmetic operations. (Polynomial division and decimal bases\nare two examples.) The library already implements double-digit multiplication and division as\nextension methods on a protocol with an associated type requirement; this has not measurably affected\nperformance. Unfortunately, the same is not true for `BigUInt`'s methods.\n\nOf course, as a last resort, we could just duplicate the code to create a separate\ngeneric variant that was slower but more flexible.\n\n[license]: https://github.com/attaswift/BigInt/blob/master/LICENSE.md\n[twitter]: https://twitter.com/lorentey\n[BigUInt]: http://attaswift.github.io/BigInt/Structs/BigUInt.html\n[BigInt]: http://attaswift.github.io/BigInt/Structs/BigInt.html\n[comparison]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Comparison\n[hashing]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Hashing\n[addition]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Addition\n[subtraction]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Subtraction\n[mul]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:ZFV6BigInt7BigUIntoi1mFTS0_S0__S0_\n[fused]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt14multiplyAndAddFTS0_Vs6UInt6410atPositionSi_T_\n[multiplication]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Multiplication\n[division]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Division\n[divide]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt7dividedFT2byS0__T8quotientS0_9remainderS0__\n[bitwise]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Bitwise%20Operations\n[width]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt5widthSi\n[leadingZeroBitCount]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt13leadingZeroBitCountSi\n[trailingZeroBitCount]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:vV6BigInt7BigUInt14trailingZeroBitCountSi\n[shift]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Shift%20Operators\n[data]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/NSData%20Conversion\n[random]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Random%20Integers\n[radix1]: http://attaswift.github.io/BigInt/Extensions/String.html#/s:FE6BigIntSScFTVS_7BigUInt5radixSi9uppercaseSb_SS\n[radix2]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUIntcFTSS5radixSi_GSqS0__\n[sqrt]: http://attaswift.github.io/BigInt/Functions.html#/s:F6BigInt4sqrtFVS_7BigUIntS0_\n[GCD]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:ZFV6BigInt7BigUInt3gcdFTS0_S0__S0_\n[powmod]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt5powerFTS0_7modulusS0__S0_\n[power]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt5powerFSiS0_\n[inverse]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/s:FV6BigInt7BigUInt7inverseFS0_GSqS0__\n[prime]: http://attaswift.github.io/BigInt/Structs/BigUInt.html#/Primality%20Testing\n[abs]: http://attaswift.github.io/BigInt/Structs/BigInt.html#/s:vV6BigInt6BigInt3absVS_7BigUInt\n[negative]: http://attaswift.github.io/BigInt/Structs/BigInt.html#/s:vV6BigInt6BigInt8negativeSb\n[subscript]: https://github.com/attaswift/BigInt/blob/v2.0.0/Sources/BigUInt.swift#L216-L239\n[fullmuldiv]: https://github.com/attaswift/BigInt/blob/v2.0.0/Sources/BigDigit.swift#L96-L167\n\n\n## \u003ca name=\"samples\"\u003eCalculation Samples\u003c/a\u003e\n\n### \u003ca name=\"factorial\"\u003eObligatory Factorial Demo\u003c/a\u003e\n\nIt is easy to use `BigInt` to calculate the factorial function for any integer:\n\n```Swift\nimport BigInt\n\nfunc factorial(_ n: Int) -\u003e BigInt {\n    return (1 ... n).map { BigInt($0) }.reduce(BigInt(1), *)\n}\n\nprint(factorial(10))\n==\u003e 362880\n\nprint(factorial(100))\n==\u003e 93326215443944152681699238856266700490715968264381621468592963895217599993229915\n    6089414639761565182862536979208272237582511852109168640000000000000000000000\n\nprint(factorial(1000))\n==\u003e 40238726007709377354370243392300398571937486421071463254379991042993851239862902\n    05920442084869694048004799886101971960586316668729948085589013238296699445909974\n    24504087073759918823627727188732519779505950995276120874975462497043601418278094\n    64649629105639388743788648733711918104582578364784997701247663288983595573543251\n    31853239584630755574091142624174743493475534286465766116677973966688202912073791\n    43853719588249808126867838374559731746136085379534524221586593201928090878297308\n    43139284440328123155861103697680135730421616874760967587134831202547858932076716\n    91324484262361314125087802080002616831510273418279777047846358681701643650241536\n    91398281264810213092761244896359928705114964975419909342221566832572080821333186\n    11681155361583654698404670897560290095053761647584772842188967964624494516076535\n    34081989013854424879849599533191017233555566021394503997362807501378376153071277\n    61926849034352625200015888535147331611702103968175921510907788019393178114194545\n    25722386554146106289218796022383897147608850627686296714667469756291123408243920\n    81601537808898939645182632436716167621791689097799119037540312746222899880051954\n    44414282012187361745992642956581746628302955570299024324153181617210465832036786\n    90611726015878352075151628422554026517048330422614397428693306169089796848259012\n    54583271682264580665267699586526822728070757813918581788896522081643483448259932\n    66043367660176999612831860788386150279465955131156552036093988180612138558600301\n    43569452722420634463179746059468257310379008402443243846565724501440282188525247\n    09351906209290231364932734975655139587205596542287497740114133469627154228458623\n    77387538230483865688976461927383814900140767310446640259899490222221765904339901\n    88601856652648506179970235619389701786004081188972991831102117122984590164192106\n    88843871218556461249607987229085192968193723886426148396573822911231250241866493\n    53143970137428531926649875337218940694281434118520158014123344828015051399694290\n    15348307764456909907315243327828826986460278986432113908350621709500259738986355\n    42771967428222487575867657523442202075736305694988250879689281627538488633969099\n    59826280956121450994871701244516461260379029309120889086942028510640182154399457\n    15680594187274899809425474217358240106367740459574178516082923013535808184009699\n    63725242305608559037006242712434169090041536901059339838357779394109700277534720\n    00000000000000000000000000000000000000000000000000000000000000000000000000000000\n    00000000000000000000000000000000000000000000000000000000000000000000000000000000\n    00000000000000000000000000000000000000000000000000000000000000000000000000000000\n    00000\n```\n\nWell, I guess that's all right, but it's not very interesting. Let's try something more useful.\n\n### \u003ca name=\"rsa\"\u003eRSA Cryptography\u003c/a\u003e\n\nThe `BigInt` module provides all necessary parts to implement an (overly)\nsimple [RSA cryptography system][RSA].\n\n[RSA]: https://en.wikipedia.org/wiki/RSA_(cryptosystem)\n\nLet's start with a simple function that generates a random n-bit prime. The module\nincludes a function to generate random integers of a specific size, and also an\n`isPrime` method that performs the Miller–Rabin primality test. These are all we need:\n\n```Swift\nfunc generatePrime(_ width: Int) -\u003e BigUInt {\n    while true {\n        var random = BigUInt.randomInteger(withExactWidth: width)\n        random |= BigUInt(1)\n        if random.isPrime() {\n            return random\n        }\n    }\n}\n\nlet p = generatePrime(1024)\n==\u003e 13308187650642192396256419911012544845370493728424936791561478318443071617242872\n    81980956747087187419914435169914161116601678883358611076800743580556055714173922\n    08406194264346635072293912609713085260354070700055888678514690878149253177960273\n    775659537560220378850112471985434373425534121373466492101182463962031\n\nlet q = generatePrime(1024)\n==\u003e 17072954422657145489547308812333368925007949054501204983863958355897172093173783\n    10108226596943999553784252564650624766276133157586733504784616138305701168410157\n    80784336308507083874651158029602582993233111593356512531869546706885170044355115\n    669728424124141763799008880327106952436883614887277350838425336156327\n```\n\nCool! Now that we have two large primes, we can produce an RSA public/private keypair\nout of them.\n\n```Swift\ntypealias Key = (modulus: BigUInt, exponent: BigUInt)\n\nlet n = p * q\n==\u003e 22721008120758282530010953362926306641542233757318103044313144976976529789946696\n    15454966720907712515917481418981591379647635391260569349099666410127279690367978\n    81184375533755888994370640857883754985364288413796100527262763202679037134021810\n    57933883525572232242690805678883227791774442041516929419640051653934584376704034\n    63953169772816907280591934423237977258358097846511079947337857778137177570668391\n    57455417707100275487770399281417352829897118140972240757708561027087217205975220\n    02207275447810167397968435583004676293892340103729490987263776871467057582629588\n    916498579594964478080508868267360515953225283461208420137\n\nlet e: BigUInt = 65537\nlet phi = (p - 1) * (q - 1)\nlet d = e.inverse(phi)!     // d * e % phi == 1\n==\u003e 13964664343869014759736350480776837992604500903989703383202366291905558996277719\n    77822086142456362972689566985925179681282432115598451765899180050962461295573831\n    37069237934291884106584820998146965085531433195106686745474222222620986858696591\n    69836532468835154412554521152103642453158895363417640676611704542784576974374954\n    45789456921660619938185093118762690200980720312508614337759620606992462563490422\n    76669559556568917533268479190948959560397579572761529852891246283539604545691244\n    89999692877158676643042118662613875863504016129837099223040687512684532694527109\n    80742873307409704484365002175294665608486688146261327793\n\nlet publicKey: Key = (n, e)\nlet privateKey: Key = (n, d)\n```\n\nIn RSA, modular exponentiation is used to encrypt (and decrypt) messages.\n\n```Swift\nfunc encrypt(_ message: BigUInt, key: Key) -\u003e BigUInt {\n    return message.power(key.exponent, modulus: key.modulus)\n}\n```\n\nLet's try out our new keypair by converting a string into UTF-8, interpreting\nthe resulting binary representation as a big integer, and encrypting it with the\npublic key. `BigUInt` has an initializer that takes an `NSData`, so this is pretty\neasy to do:\n\n```Swift\nlet secret: BigUInt = BigUInt(\"Arbitrary precision arithmetic is fun!\".dataUsingEncoding(NSUTF8StringEncoding)!)\n==\u003e 83323446846105976078466731524728681905293067701804838925389198929123912971229457\n    68818568737\n\nlet cyphertext = encrypt(secret, key: publicKey)\n==\u003e 95186982543485985200666516508066093880038842892337880561554910904277290917831453\n    54854954722744805432145474047391353716305176389470779020645959135298322520888633\n    61674945129099575943384767330342554525120384485469428048962027149169876127890306\n    77028183904699491962050888974524603226290836984166164759586952419343589385279641\n    47999991283152843977988979846238236160274201261075188190509539751990119132013021\n    74866638595734222867005089157198503204192264814750832072844208520394603054901706\n    06024394731371973402595826456435944968439153664617188570808940022471990638468783\n    49208193955207336172861151720299024935127021719852700882\n```\n\nWell, it looks encrypted all right, but can we get the original message back?\nIn theory, encrypting the cyphertext with the private key returns the original message.\nLet's see:\n\n```Swift\nlet plaintext = encrypt(cyphertext, key: privateKey)\n==\u003e 83323446846105976078466731524728681905293067701804838925389198929123912971229457\n    68818568737\n\nlet received = String(data: plaintext.serialize(), encoding: NSUTF8StringEncoding)\n==\u003e \"Arbitrary precision arithmetic is fun!\"\n```\n\nYay! This is truly terrific, but please don't use this example code in an actual\ncryptography system. RSA has lots of subtle (and some not so subtle) complications\nthat we ignored to keep this example short.\n\n### \u003ca name=\"pi\"\u003eCalculating the Digits of π\u003c/a\u003e\n\nAnother fun activity to try with `BigInt`s is to generate the digits of π.\nLet's try implementing [Jeremy Gibbon's spigot algorithm][spigot].\nThis is a rather slow algorithm as π-generators go, but it makes up for it with its grooviness\nfactor: it's remarkably short, it only uses (big) integer arithmetic, and every iteration\nproduces a single new digit in the base-10 representation of π. This naturally leads to an\nimplementation as an infinite `GeneratorType`:\n\n[spigot]: http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf\n\n```Swift\nfunc digitsOfPi() -\u003e AnyGenerator\u003cInt\u003e {\n    var q: BigUInt = 1\n    var r: BigUInt = 180\n    var t: BigUInt = 60\n    var i: UInt64 = 2 // Does not overflow until digit #826_566_842\n    return AnyIterator {\n        let u: UInt64 = 3 * (3 * i + 1) * (3 * i + 2)\n        let y = (q.multiplied(byDigit: 27 * i - 12) + 5 * r) / (5 * t)\n        (q, r, t) = (\n            10 * q.multiplied(byDigit: i * (2 * i - 1)),\n            10 * (q.multiplied(byDigit: 5 * i - 2) + r - y * t).multiplied(byDigit: u),\n            t.multiplied(byDigit: u))\n        i += 1\n        return Int(y[0])\n    }\n}\n```\n\nWell, that was surprisingly easy. But does it work? Of course it does!\n\n```Swift\nvar digits = \"π ≈ \"\nvar count = 0\nfor digit in digitsOfPi() {\n    assert(digit \u003c 10)\n    digits += String(digit)\n    count += 1\n    if count == 1 { digits += \".\" }\n    if count == 1000 { break }\n}\n\ndigits\n==\u003e π ≈ 3.14159265358979323846264338327950288419716939937510582097494459230781640628\n    62089986280348253421170679821480865132823066470938446095505822317253594081284811\n    17450284102701938521105559644622948954930381964428810975665933446128475648233786\n    78316527120190914564856692346034861045432664821339360726024914127372458700660631\n    55881748815209209628292540917153643678925903600113305305488204665213841469519415\n    11609433057270365759591953092186117381932611793105118548074462379962749567351885\n    75272489122793818301194912983367336244065664308602139494639522473719070217986094\n    37027705392171762931767523846748184676694051320005681271452635608277857713427577\n    89609173637178721468440901224953430146549585371050792279689258923542019956112129\n    02196086403441815981362977477130996051870721134999999837297804995105973173281609\n    63185950244594553469083026425223082533446850352619311881710100031378387528865875\n    33208381420617177669147303598253490428755468731159562863882353787593751957781857\n    780532171226806613001927876611195909216420198\n```\n\nNow go and have some fun with big integers on your own!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattaswift%2FBigInt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fattaswift%2FBigInt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fattaswift%2FBigInt/lists"}