11 Big Integers

\(\newcommand{\footnotename}{footnote}\) \(\def \LWRfootnote {1}\) \(\newcommand {\footnote }[2][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\newcommand {\footnotemark }[1][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\let \LWRorighspace \hspace \) \(\renewcommand {\hspace }{\ifstar \LWRorighspace \LWRorighspace }\) \(\newcommand {\TextOrMath }[2]{#2}\) \(\newcommand {\mathnormal }[1]{{#1}}\) \(\newcommand \ensuremath [1]{#1}\) \(\newcommand {\LWRframebox }[2][]{\fbox {#2}} \newcommand {\framebox }[1][]{\LWRframebox } \) \(\newcommand {\setlength }[2]{}\) \(\newcommand {\addtolength }[2]{}\) \(\newcommand {\setcounter }[2]{}\) \(\newcommand {\addtocounter }[2]{}\) \(\newcommand {\arabic }[1]{}\) \(\newcommand {\number }[1]{}\) \(\newcommand {\noalign }[1]{\text {#1}\notag \\}\) \(\newcommand {\cline }[1]{}\) \(\newcommand {\directlua }[1]{\text {(directlua)}}\) \(\newcommand {\luatexdirectlua }[1]{\text {(directlua)}}\) \(\newcommand {\protect }{}\) \(\def \LWRabsorbnumber #1 {}\) \(\def \LWRabsorbquotenumber "#1 {}\) \(\newcommand {\LWRabsorboption }[1][]{}\) \(\newcommand {\LWRabsorbtwooptions }[1][]{\LWRabsorboption }\) \(\def \mathchar {\ifnextchar "\LWRabsorbquotenumber \LWRabsorbnumber }\) \(\def \mathcode #1={\mathchar }\) \(\let \delcode \mathcode \) \(\let \delimiter \mathchar \) \(\def \oe {\unicode {x0153}}\) \(\def \OE {\unicode {x0152}}\) \(\def \ae {\unicode {x00E6}}\) \(\def \AE {\unicode {x00C6}}\) \(\def \aa {\unicode {x00E5}}\) \(\def \AA {\unicode {x00C5}}\) \(\def \o {\unicode {x00F8}}\) \(\def \O {\unicode {x00D8}}\) \(\def \l {\unicode {x0142}}\) \(\def \L {\unicode {x0141}}\) \(\def \ss {\unicode {x00DF}}\) \(\def \SS {\unicode {x1E9E}}\) \(\def \dag {\unicode {x2020}}\) \(\def \ddag {\unicode {x2021}}\) \(\def \P {\unicode {x00B6}}\) \(\def \copyright {\unicode {x00A9}}\) \(\def \pounds {\unicode {x00A3}}\) \(\let \LWRref \ref \) \(\renewcommand {\ref }{\ifstar \LWRref \LWRref }\) \( \newcommand {\multicolumn }[3]{#3}\) \(\require {textcomp}\) \(\newcommand {\intertext }[1]{\text {#1}\notag \\}\) \(\let \Hat \hat \) \(\let \Check \check \) \(\let \Tilde \tilde \) \(\let \Acute \acute \) \(\let \Grave \grave \) \(\let \Dot \dot \) \(\let \Ddot \ddot \) \(\let \Breve \breve \) \(\let \Bar \bar \) \(\let \Vec \vec \) \(\renewcommand {\vec }{\boldsymbol }\) \(\newcommand {\Edge }{\ensuremath {\,\textemdash \,}}\) \(\newcommand \Const [1]{\text {\textsf {#1}}}\) \(\DeclareMathOperator {\lerp }{lerp}\) \(\DeclareMathOperator {\bitlen }{bitlen}\) \(\DeclareMathOperator {\sign }{sign}\) \(\newcommand {\I }{\mathrm {i}}\) \(\newcommand \AND {\mathbin {\&}}\) \(\newcommand \OR {\mathbin {|}}\) \(\newcommand \XOR {\mathbin {{}^{\wedge }}}\) \(\newcommand \shl {\ll }\) \(\newcommand \shr {\ggg }\) \(\newcommand \asr {\gg }\) \(\newcommand \NOT {\ensuremath {\mathord {\sim }}}\) \(\newcommand {\isep }{\mathrel {{.}\,{.}}}\) \(\newcommand {\Id }[1]{\mathit {#1}}\) \(\newcommand {\const }[1]{\mathsf {#1}}\) \(\newcommand {\algorithmname }[1]{\text {\textsc {#1}}}\) \(\newcommand {\bits }[1]{\text {#1}}\) \(\newcommand {\hexa }[1]{\mathtt {0x#1}}\) \(\newcommand {\num }[1]{#1}\) \(\newcommand {\qed }{\quad \square }\) \(\newcommand {\idiv }[2]{\lfloor #1/#2\rfloor }\) \(\newcommand \attribdot {\ensuremath {\mkern 1.5mu.\mkern 1.5mu}}\) \(\newcommand \attribxr [2]{#1\attribdot \text {#2}}\) \(\newcommand \attribir [2]{\Id {#1}\attribdot \text {#2}}\) \(\newcommand \attribii [2]{\Id {#1}\attribdot \Id {#2}}\) \(\newcommand \textsc [1]{#1}\) \(\require {colortbl}\) \(\let \LWRorigcolumncolor \columncolor \) \(\renewcommand {\columncolor }[2][named]{\LWRorigcolumncolor [#1]{#2}\LWRabsorbtwooptions }\) \(\let \LWRorigrowcolor \rowcolor \) \(\renewcommand {\rowcolor }[2][named]{\LWRorigrowcolor [#1]{#2}\LWRabsorbtwooptions }\) \(\let \LWRorigcellcolor \cellcolor \) \(\renewcommand {\cellcolor }[2][named]{\LWRorigcellcolor [#1]{#2}\LWRabsorbtwooptions }\) \(\newcommand {\tcbset }[1]{}\) \(\newcommand {\tcbsetforeverylayer }[1]{}\) \(\newcommand {\tcbox }[2][]{\boxed {\text {#2}}}\) \(\newcommand {\tcboxfit }[2][]{\boxed {#2}}\) \(\newcommand {\tcblower }{}\) \(\newcommand {\tcbline }{}\) \(\newcommand {\tcbtitle }{}\) \(\newcommand {\tcbsubtitle [2][]{\mathrm {#2}}}\) \(\newcommand {\tcboxmath }[2][]{\boxed {#2}}\) \(\newcommand {\tcbhighmath }[2][]{\boxed {#2}}\) \(\newcommand {\toprule }[1][]{\hline }\) \(\let \midrule \toprule \) \(\let \bottomrule \toprule \) \(\def \LWRbooktabscmidruleparen (#1)#2{}\) \(\newcommand {\LWRbooktabscmidrulenoparen }[1]{}\) \(\newcommand {\cmidrule }[1][]{\ifnextchar (\LWRbooktabscmidruleparen \LWRbooktabscmidrulenoparen }\) \(\newcommand {\morecmidrules }{}\) \(\newcommand {\specialrule }[3]{\hline }\) \(\newcommand {\addlinespace }[1][]{}\) \(\newcommand {\LWRsubmultirow }[2][]{#2}\) \(\newcommand {\LWRmultirow }[2][]{\LWRsubmultirow }\) \(\newcommand {\multirow }[2][]{\LWRmultirow }\) \(\newcommand {\mrowcell }{}\) \(\newcommand {\mcolrowcell }{}\) \(\newcommand {\STneed }[1]{}\) \(\newcommand {\LWRldelimtwo }[1][]{\text {#1}~\LWRbigdelim }\) \(\newcommand {\LWRldelimone }[2][]{\LWRldelimtwo }\) \(\def \ldelim #1#2{\def \LWRbigdelim {#1}\LWRldelimone }\) \(\newcommand {\LWRrdelimtwo }[1][]{\LWRbigdelim ~\text {#1}}\) \(\newcommand {\LWRrdelimone }[2][]{\LWRrdelimtwo }\) \(\def \rdelim #1#2{\def \LWRbigdelim {#1}\LWRrdelimone }\) \(\let \symnormal \mathit \) \(\let \symliteral \mathrm \) \(\let \symbb \mathbb \) \(\let \symbbit \mathbb \) \(\let \symcal \mathcal \) \(\let \symscr \mathscr \) \(\let \symfrak \mathfrak \) \(\let \symsfup \mathsf \) \(\let \symsfit \mathit \) \(\let \symbfsf \mathbf \) \(\let \symbfup \mathbf \) \(\newcommand {\symbfit }[1]{\boldsymbol {#1}}\) \(\let \symbfcal \mathcal \) \(\let \symbfscr \mathscr \) \(\let \symbffrak \mathfrak \) \(\let \symbfsfup \mathbf \) \(\newcommand {\symbfsfit }[1]{\boldsymbol {#1}}\) \(\let \symup \mathrm \) \(\let \symbf \mathbf \) \(\let \symit \mathit \) \(\let \symsf \symsfit \) \(\let \symtt \mathtt \) \(\let \symbffrac \mathbffrac \) \(\newcommand {\mathfence }[1]{\mathord {#1}}\) \(\newcommand {\mathover }[1]{#1}\) \(\newcommand {\mathunder }[1]{#1}\) \(\newcommand {\mathaccent }[1]{#1}\) \(\newcommand {\mathbotaccent }[1]{#1}\) \(\newcommand {\mathalpha }[1]{\mathord {#1}}\) \(\def\Alpha{\unicode{x1D6E2}}\) \(\def\Beta{\unicode{x1D6E3}}\) \(\def\Gamma{\unicode{x1D6E4}}\) \(\def\Digamma{\mathit{\unicode{x03DC}}}\) \(\def\Delta{\unicode{x1D6E5}}\) \(\def\Epsilon{\unicode{x1D6E6}}\) \(\def\Zeta{\unicode{x1D6E7}}\) \(\def\Eta{\unicode{x1D6E8}}\) \(\def\Theta{\unicode{x1D6E9}}\) \(\def\Vartheta{\unicode{x1D6F3}}\) \(\def\Iota{\unicode{x1D6EA}}\) \(\def\Kappa{\unicode{x1D6EB}}\) \(\def\Lambda{\unicode{x1D6EC}}\) \(\def\Mu{\unicode{x1D6ED}}\) \(\def\Nu{\unicode{x1D6EE}}\) \(\def\Xi{\unicode{x1D6EF}}\) \(\def\Omicron{\unicode{x1D6F0}}\) \(\def\Pi{\unicode{x1D6F1}}\) \(\def\Rho{\unicode{x1D6F2}}\) \(\def\Sigma{\unicode{x1D6F4}}\) \(\def\Tau{\unicode{x1D6F5}}\) \(\def\Upsilon{\unicode{x1D6F6}}\) \(\def\Phi{\unicode{x1D6F7}}\) \(\def\Chi{\unicode{x1D6F8}}\) \(\def\Psi{\unicode{x1D6F9}}\) \(\def\Omega{\unicode{x1D6FA}}\) \(\def\alpha{\unicode{x1D6FC}}\) \(\def\beta{\unicode{x1D6FD}}\) \(\def\varbeta{\unicode{x03D0}}\) \(\def\gamma{\unicode{x1D6FE}}\) \(\def\digamma{\mathit{\unicode{x03DD}}}\) \(\def\delta{\unicode{x1D6FF}}\) \(\def\epsilon{\unicode{x1D716}}\) \(\def\varepsilon{\unicode{x1D700}}\) \(\def\zeta{\unicode{x1D701}}\) \(\def\eta{\unicode{x1D702}}\) \(\def\theta{\unicode{x1D703}}\) \(\def\vartheta{\unicode{x1D717}}\) \(\def\iota{\unicode{x1D704}}\) \(\def\kappa{\unicode{x1D705}}\) \(\def\varkappa{\unicode{x1D718}}\) \(\def\lambda{\unicode{x1D706}}\) \(\def\mu{\unicode{x1D707}}\) \(\def\nu{\unicode{x1D708}}\) \(\def\xi{\unicode{x1D709}}\) \(\def\omicron{\unicode{x1D70A}}\) \(\def\pi{\unicode{x1D70B}}\) \(\def\varpi{\unicode{x1D71B}}\) \(\def\rho{\unicode{x1D70C}}\) \(\def\varrho{\unicode{x1D71A}}\) \(\def\sigma{\unicode{x1D70E}}\) \(\def\varsigma{\unicode{x1D70D}}\) \(\def\tau{\unicode{x1D70F}}\) \(\def\upsilon{\unicode{x1D710}}\) \(\def\phi{\unicode{x1D719}}\) \(\def\varphi{\unicode{x1D711}}\) \(\def\chi{\unicode{x1D712}}\) \(\def\psi{\unicode{x1D713}}\) \(\def\omega{\unicode{x1D714}}\) \(\def\upAlpha{\unicode{x0391}}\) \(\def\upBeta{\unicode{x0392}}\) \(\def\upGamma{\unicode{x0393}}\) \(\def\upDigamma{\unicode{x03DC}}\) \(\def\upDelta{\unicode{x0394}}\) \(\def\upEpsilon{\unicode{x0395}}\) \(\def\upZeta{\unicode{x0396}}\) \(\def\upEta{\unicode{x0397}}\) \(\def\upTheta{\unicode{x0398}}\) \(\def\upVartheta{\unicode{x03F4}}\) \(\def\upIota{\unicode{x0399}}\) \(\def\upKappa{\unicode{x039A}}\) \(\def\upLambda{\unicode{x039B}}\) \(\def\upMu{\unicode{x039C}}\) \(\def\upNu{\unicode{x039D}}\) \(\def\upXi{\unicode{x039E}}\) \(\def\upOmicron{\unicode{x039F}}\) \(\def\upPi{\unicode{x03A0}}\) \(\def\upVarpi{\unicode{x03D6}}\) \(\def\upRho{\unicode{x03A1}}\) \(\def\upSigma{\unicode{x03A3}}\) \(\def\upTau{\unicode{x03A4}}\) \(\def\upUpsilon{\unicode{x03A5}}\) \(\def\upPhi{\unicode{x03A6}}\) \(\def\upChi{\unicode{x03A7}}\) \(\def\upPsi{\unicode{x03A8}}\) \(\def\upOmega{\unicode{x03A9}}\) \(\def\itAlpha{\unicode{x1D6E2}}\) \(\def\itBeta{\unicode{x1D6E3}}\) \(\def\itGamma{\unicode{x1D6E4}}\) \(\def\itDigamma{\mathit{\unicode{x03DC}}}\) \(\def\itDelta{\unicode{x1D6E5}}\) \(\def\itEpsilon{\unicode{x1D6E6}}\) \(\def\itZeta{\unicode{x1D6E7}}\) \(\def\itEta{\unicode{x1D6E8}}\) \(\def\itTheta{\unicode{x1D6E9}}\) \(\def\itVartheta{\unicode{x1D6F3}}\) \(\def\itIota{\unicode{x1D6EA}}\) \(\def\itKappa{\unicode{x1D6EB}}\) \(\def\itLambda{\unicode{x1D6EC}}\) \(\def\itMu{\unicode{x1D6ED}}\) \(\def\itNu{\unicode{x1D6EE}}\) \(\def\itXi{\unicode{x1D6EF}}\) \(\def\itOmicron{\unicode{x1D6F0}}\) \(\def\itPi{\unicode{x1D6F1}}\) \(\def\itRho{\unicode{x1D6F2}}\) \(\def\itSigma{\unicode{x1D6F4}}\) \(\def\itTau{\unicode{x1D6F5}}\) \(\def\itUpsilon{\unicode{x1D6F6}}\) \(\def\itPhi{\unicode{x1D6F7}}\) \(\def\itChi{\unicode{x1D6F8}}\) \(\def\itPsi{\unicode{x1D6F9}}\) \(\def\itOmega{\unicode{x1D6FA}}\) \(\def\upalpha{\unicode{x03B1}}\) \(\def\upbeta{\unicode{x03B2}}\) \(\def\upvarbeta{\unicode{x03D0}}\) \(\def\upgamma{\unicode{x03B3}}\) \(\def\updigamma{\unicode{x03DD}}\) \(\def\updelta{\unicode{x03B4}}\) \(\def\upepsilon{\unicode{x03F5}}\) \(\def\upvarepsilon{\unicode{x03B5}}\) \(\def\upzeta{\unicode{x03B6}}\) \(\def\upeta{\unicode{x03B7}}\) \(\def\uptheta{\unicode{x03B8}}\) \(\def\upvartheta{\unicode{x03D1}}\) \(\def\upiota{\unicode{x03B9}}\) \(\def\upkappa{\unicode{x03BA}}\) \(\def\upvarkappa{\unicode{x03F0}}\) \(\def\uplambda{\unicode{x03BB}}\) \(\def\upmu{\unicode{x03BC}}\) \(\def\upnu{\unicode{x03BD}}\) \(\def\upxi{\unicode{x03BE}}\) \(\def\upomicron{\unicode{x03BF}}\) \(\def\uppi{\unicode{x03C0}}\) \(\def\upvarpi{\unicode{x03D6}}\) \(\def\uprho{\unicode{x03C1}}\) \(\def\upvarrho{\unicode{x03F1}}\) \(\def\upsigma{\unicode{x03C3}}\) \(\def\upvarsigma{\unicode{x03C2}}\) \(\def\uptau{\unicode{x03C4}}\) \(\def\upupsilon{\unicode{x03C5}}\) \(\def\upphi{\unicode{x03D5}}\) \(\def\upvarphi{\unicode{x03C6}}\) \(\def\upchi{\unicode{x03C7}}\) \(\def\uppsi{\unicode{x03C8}}\) \(\def\upomega{\unicode{x03C9}}\) \(\def\italpha{\unicode{x1D6FC}}\) \(\def\itbeta{\unicode{x1D6FD}}\) \(\def\itvarbeta{\unicode{x03D0}}\) \(\def\itgamma{\unicode{x1D6FE}}\) \(\def\itdigamma{\mathit{\unicode{x03DD}}}\) \(\def\itdelta{\unicode{x1D6FF}}\) \(\def\itepsilon{\unicode{x1D716}}\) \(\def\itvarepsilon{\unicode{x1D700}}\) \(\def\itzeta{\unicode{x1D701}}\) \(\def\iteta{\unicode{x1D702}}\) \(\def\ittheta{\unicode{x1D703}}\) \(\def\itvartheta{\unicode{x1D717}}\) \(\def\itiota{\unicode{x1D704}}\) \(\def\itkappa{\unicode{x1D705}}\) \(\def\itvarkappa{\unicode{x1D718}}\) \(\def\itlambda{\unicode{x1D706}}\) \(\def\itmu{\unicode{x1D707}}\) \(\def\itnu{\unicode{x1D708}}\) \(\def\itxi{\unicode{x1D709}}\) \(\def\itomicron{\unicode{x1D70A}}\) \(\def\itpi{\unicode{x1D70B}}\) \(\def\itvarpi{\unicode{x1D71B}}\) \(\def\itrho{\unicode{x1D70C}}\) \(\def\itvarrho{\unicode{x1D71A}}\) \(\def\itsigma{\unicode{x1D70E}}\) \(\def\itvarsigma{\unicode{x1D70D}}\) \(\def\ittau{\unicode{x1D70F}}\) \(\def\itupsilon{\unicode{x1D710}}\) \(\def\itphi{\unicode{x1D719}}\) \(\def\itvarphi{\unicode{x1D711}}\) \(\def\itchi{\unicode{x1D712}}\) \(\def\itpsi{\unicode{x1D713}}\) \(\def\itomega{\unicode{x1D714}}\) \(\let \lparen (\) \(\let \rparen )\) \(\newcommand {\cuberoot }[1]{\,{}^3\!\!\sqrt {#1}}\,\) \(\newcommand {\fourthroot }[1]{\,{}^4\!\!\sqrt {#1}}\,\) \(\newcommand {\longdivision }[1]{\mathord {\unicode {x027CC}#1}}\) \(\newcommand {\mathcomma }{,}\) \(\newcommand {\mathcolon }{:}\) \(\newcommand {\mathsemicolon }{;}\) \(\newcommand {\overbracket }[1]{\mathinner {\overline {\ulcorner {#1}\urcorner }}}\) \(\newcommand {\underbracket }[1]{\mathinner {\underline {\llcorner {#1}\lrcorner }}}\) \(\newcommand {\overbar }[1]{\mathord {#1\unicode {x00305}}}\) \(\newcommand {\ovhook }[1]{\mathord {#1\unicode {x00309}}}\) \(\newcommand {\ocirc }[1]{\mathord {#1\unicode {x0030A}}}\) \(\newcommand {\candra }[1]{\mathord {#1\unicode {x00310}}}\) \(\newcommand {\oturnedcomma }[1]{\mathord {#1\unicode {x00312}}}\) \(\newcommand {\ocommatopright }[1]{\mathord {#1\unicode {x00315}}}\) \(\newcommand {\droang }[1]{\mathord {#1\unicode {x0031A}}}\) \(\newcommand {\leftharpoonaccent }[1]{\mathord {#1\unicode {x020D0}}}\) \(\newcommand {\rightharpoonaccent }[1]{\mathord {#1\unicode {x020D1}}}\) \(\newcommand {\vertoverlay }[1]{\mathord {#1\unicode {x020D2}}}\) \(\newcommand {\leftarrowaccent }[1]{\mathord {#1\unicode {x020D0}}}\) \(\newcommand {\annuity }[1]{\mathord {#1\unicode {x020E7}}}\) \(\newcommand {\widebridgeabove }[1]{\mathord {#1\unicode {x020E9}}}\) \(\newcommand {\asteraccent }[1]{\mathord {#1\unicode {x020F0}}}\) \(\newcommand {\threeunderdot }[1]{\mathord {#1\unicode {x020E8}}}\) \(\newcommand {\Bbbsum }{\mathop {\unicode {x2140}}\limits }\) \(\newcommand {\oiint }{\mathop {\unicode {x222F}}\limits }\) \(\newcommand {\oiiint }{\mathop {\unicode {x2230}}\limits }\) \(\newcommand {\intclockwise }{\mathop {\unicode {x2231}}\limits }\) \(\newcommand {\ointclockwise }{\mathop {\unicode {x2232}}\limits }\) \(\newcommand {\ointctrclockwise }{\mathop {\unicode {x2233}}\limits }\) \(\newcommand {\varointclockwise }{\mathop {\unicode {x2232}}\limits }\) \(\newcommand {\leftouterjoin }{\mathop {\unicode {x27D5}}\limits }\) \(\newcommand {\rightouterjoin }{\mathop {\unicode {x27D6}}\limits }\) \(\newcommand {\fullouterjoin }{\mathop {\unicode {x27D7}}\limits }\) \(\newcommand {\bigbot }{\mathop {\unicode {x27D8}}\limits }\) \(\newcommand {\bigtop }{\mathop {\unicode {x27D9}}\limits }\) \(\newcommand {\xsol }{\mathop {\unicode {x29F8}}\limits }\) \(\newcommand {\xbsol }{\mathop {\unicode {x29F9}}\limits }\) \(\newcommand {\bigcupdot }{\mathop {\unicode {x2A03}}\limits }\) \(\newcommand {\bigsqcap }{\mathop {\unicode {x2A05}}\limits }\) \(\newcommand {\conjquant }{\mathop {\unicode {x2A07}}\limits }\) \(\newcommand {\disjquant }{\mathop {\unicode {x2A08}}\limits }\) \(\newcommand {\bigtimes }{\mathop {\unicode {x2A09}}\limits }\) \(\newcommand {\modtwosum }{\mathop {\unicode {x2A0A}}\limits }\) \(\newcommand {\sumint }{\mathop {\unicode {x2A0B}}\limits }\) \(\newcommand {\intbar }{\mathop {\unicode {x2A0D}}\limits }\) \(\newcommand {\intBar }{\mathop {\unicode {x2A0E}}\limits }\) \(\newcommand {\fint }{\mathop {\unicode {x2A0F}}\limits }\) \(\newcommand {\cirfnint }{\mathop {\unicode {x2A10}}\limits }\) \(\newcommand {\awint }{\mathop {\unicode {x2A11}}\limits }\) \(\newcommand {\rppolint }{\mathop {\unicode {x2A12}}\limits }\) \(\newcommand {\scpolint }{\mathop {\unicode {x2A13}}\limits }\) \(\newcommand {\npolint }{\mathop {\unicode {x2A14}}\limits }\) \(\newcommand {\pointint }{\mathop {\unicode {x2A15}}\limits }\) \(\newcommand {\sqint }{\mathop {\unicode {x2A16}}\limits }\) \(\newcommand {\intlarhk }{\mathop {\unicode {x2A17}}\limits }\) \(\newcommand {\intx }{\mathop {\unicode {x2A18}}\limits }\) \(\newcommand {\intcap }{\mathop {\unicode {x2A19}}\limits }\) \(\newcommand {\intcup }{\mathop {\unicode {x2A1A}}\limits }\) \(\newcommand {\upint }{\mathop {\unicode {x2A1B}}\limits }\) \(\newcommand {\lowint }{\mathop {\unicode {x2A1C}}\limits }\) \(\newcommand {\bigtriangleleft }{\mathop {\unicode {x2A1E}}\limits }\) \(\newcommand {\zcmp }{\mathop {\unicode {x2A1F}}\limits }\) \(\newcommand {\zpipe }{\mathop {\unicode {x2A20}}\limits }\) \(\newcommand {\zproject }{\mathop {\unicode {x2A21}}\limits }\) \(\newcommand {\biginterleave }{\mathop {\unicode {x2AFC}}\limits }\) \(\newcommand {\bigtalloblong }{\mathop {\unicode {x2AFF}}\limits }\) \(\newcommand {\arabicmaj }{\mathop {\unicode {x1EEF0}}\limits }\) \(\newcommand {\arabichad }{\mathop {\unicode {x1EEF1}}\limits }\)

11.9 Problems

Analysis of Karatsuba Multiplication

\(\star \) Exercise 11.17. The runtime complexity of many divide-and-conquer algorithms can be analyzed using the so-called master theorem. Assume we are given a problem of size \(n\) (in the case of multiplication, \(n\) is the number of digits of the two numbers being multiplied) and let \(T(n)\) denote the time required to solve this problem using a particular algorithm. If the algorithm recursively splits the problem into \(a\) smaller problems of size \(n/b\), we can write \(T(n)\) as

\begin{equation} \label {eq:masterbase} T(n) = aT\left (\frac {n}{b}\right ) + \left (\begin{array}{@{}c@{}} \text {Time required for splitting problem}\\ \text {and combining solutions} \end {array}\right ). \end{equation}

The master theorem now states that \(T(n)\) has the asymptotic complexity

\begin{equation} T(n) = O(n^{\log _b a}), \end{equation}

provided the second term on the right-hand side of Eq. (11.18) is sufficiently small.5

Here is a simple example. In Section 3.1 we discussed a simple recursive algorithm for finding the smallest element in an array of integers. The algorithm splits the array into two parts, recursively finds the minimum of each, and then returns the smaller of the two values. If we split the array into two equal parts, we have \(a=2\) and \(b=2\), so

\[ T(n) = 2\cdot T(n / 2) + C, \]

where \(C\) is a constant that measures the work done before and after the recursive calls, which is independent of \(n\). According to the master theorem, the complexity of the algorithm is therefore

\[ T(n) = O(n^{\log _2 2}) = O(n). \]

  • a) What are the values of \(a\) and \(b\) for the recursive multiplication scheme in Eqs. (11.7) and (11.8)? Assume that master theorem can be applied. What is the resulting asymptotic complexity of \(T(n)\)?

  • b) What are the values of \(a\) and \(b\) for Karatsuba’s algorithm? Again, assume that master theorem can be applied and derive the asymptotic complexity of \(T(n)\).

5 For the technical details and a more general version of the master theorem, see [25, Chapter 4].

Integer Powers

Exercise 11.18.Consider the problem of computing \(x^m\) for two integers \(x\) and \(m\). The obvious algorithm computes the product \(x\cdot x\cdot \dots \cdot x\), where \(x\) is repeated \(m\) times, which requires a total number of \(m-1\) multiplications. A much faster algorithm for computing integer powers can be obtained by repeated squaring. It’s easiest to see how it works by considering an example. If we want to compute \(x^{19}\), we start with the binary expansion of the exponent \(19=10011_2=1+2+16\) and then write \(x^{19}\) as a product of three terms of the form \(x^e\), where \(e\) is a power of 2:

\begin{equation*} x^{19}=x^{1+2+16}=xx^2x^{16}. \end{equation*}

Each of the terms \(x^e\) can be obtained by repeatedly squaring the previous term: \(x^2\) is obtained by squaring \(x\) once, and \(x^{16}\) is obtained by squaring \(x^2\) three times:

\begin{equation*} x\xrightarrow {\text {square once}} x^2 \xrightarrow {\text {square 3 times}} x^{16}. \end{equation*}

This method reduces the problem of computing \(x^{19}\) from 18 multiplications to only six multiplications: four multiplications to compute the terms \(x^e\) and two multiplications to accumulate their product.

  • a) Use a similar decomposition to compute \(x^{43}\). How many multiplications are necessary?

We can turn this idea into a proper algorithm as follows. Assume we want to compute \(x^m\) for some integer \(x\) and and a positive exponent \(m\). As in the example we just discussed, the first step is to write \(x^m\) as a product of smaller powers of \(x\) using the binary representation of the exponent

\begin{equation*} m = (m_{M-1} \dots m_1m_0)_2 = m_{M-1} 2^{M-1} + \dots + m_1 2^1 + m_0 2^0. \end{equation*}

Using this expansion, we can use the fact that \(x^{a+b}=x^ax^b\) to rewrite \(x^m\) as a product of smaller powers:

\begin{align*} x^m &= x^{m_{M-1} 2^{M-1} + \dots + m_1 2^1 + m_0 2^0}\\ &=x^{m_{M-1} 2^{M-1}} \cdots x^{m_1 2^1} x^{m_0 2^0}; \end{align*} This expression can be simplified further since each bit \(m_k\) is either 0 or 1, which means that each term can be written as

\begin{equation*} x^{m_k 2^k} = \begin{cases} x^{2^k} & \text {if $m_k=1$};\\ 1 & \text {otherwise}. \end {cases} \end{equation*}

Only the terms for which \(m_k=1\) contribute to the final product, so we have our final result:

\begin{equation} x^m = \prod _{0\le k<M, m_k=1} x^{2^k}. \end{equation}

The \(\prod {}\) operator is essentially the mathematical notation for a loop that computes a product of the terms on its right. To translate this expression into an actual loop, we iterate over the nonzero binary digits of the exponent \(m\), and for each such digit \(k\) multiply the result by the term \(x^{2^k}\). The successive terms \(x^{2^k}\) can be easily computed as we go, starting with \(x\) as the first term and computing the following terms \(x^2, x^4, \dots \) by repeated squaring.

  • b) Use this idea to implement an algorithm that computes \(x^k\) for two integers \(x\) and \(k\).

  • c) How many multiplications does this algorithm perform when computing \(x^k\)?

This algorithm for computing \(x^k\) makes only two assumptions: the exponent \(k\) is a nonnegative integer and the base \(x\) is a mathematical object that can be multiplied. We can therefore use the same approach to compute integer powers of other mathematical objects, including real and complex numbers, fractions, and matrices.

  • d) Implement a method BigNat.pow() that computes the integer power of a big integer. Assume that the exponent is of type int.

Decimal Digits

Exercise 11.19. A positive integer with decimal digits \(abcde\dots \) is called polydivisible if every number formed by the first \(n\) digits is divisible by \(n\). For example, the number 62 485 is polydivisible because the first digit 6 is divisible by 1, the first two digits 62 are divisible by 2, and the numbers 624, 6248, and 62 485 are divisible by 3, 4, and 5, respectively.

  • a) There are nine polydivisible numbers with a single digit: 1, 2, 3, 4, 5, 6, 7, 8, and 9. How many polydivisible numbers with two digits are there?

  • b) Write a program that computes all polydivisible numbers. How many polydivisible numbers are there? How many digits does the largest polydivisible number have? What is the first polydivisible number that contains all decimal digits exactly once?

Exercise 11.20.A rational number is a quotient of the form \(n/m\), where \(n\) and \(m\) are integers. Every rational number has a decimal representation that consists of an integer part and a fractional part. For instance, we have \(7/4=1.75\) with the integer part 1 and the fractional part \(.75\).

  • a) Given two positive integers \(n\) and \(m\), devise an algorithm that computes a certain number of decimal digits of \(n/m\). For example, computing 5 decimal digits of \(7/3\) should produce 2.3333.

  • b) Use this algorithm to compute the first few thousand decimal digits of \(1/998\,001\).

Rational numbers have the following property: their decimal expansion is either finite or eventually produces a sequence of digits that repeats indefinitely; the length of this repeating sequence of digits is called the number’s period. For \(1/4\) the decimal expansion is \(0.25\), which is finite. For \(25/12\), however, the decimal expansion \(2.08\overline {3}\) continues forever; since the repeating sequence consists of a single digit, its period is 1.

  • c) Extend your algorithm to find the shortest sequence of repeating digits in the decimal expansion of \(n/m\). What is the period of \(987\,654\,321/123\,456\,789\)? Hint: Don’t search for repetitions in the sequence of decimal digits. Instead, determine when the algorithm returns to a previous state.

Durations

Exercise 11.21.Time durations are traditionally specified in a way that resembles a positional number system. A duration like “three weeks, two days, one hour, five minutes, and ten seconds” can be represented as a sequence of “digits” \(3, 2, 1, 5, 10\) in which each position represents one unit of time. Compared to ordinary number systems, the main difference is that each digit now has its own radix: Seconds and minutes are stored in base-60, hours in base-24, days in base-7, and assuming that weeks are the largest unit we use, we can choose as its radix any sufficiently large integer. Number systems in which each position has its own radix are also known as mixed-radix systems. In this exercise, we will see how arithmetic works in such systems.

  • a) Design a class that stores durations consisting of weeks, days, hours, minutes, and seconds. It should be possible to represent both positive and negative durations. The format should be normalized, so that two durations only have the same representation if they also represent the same time span.

    Note: Since the focus of this exercise is on algorithms for mixed-radix systems, durations should be stored as an array of “digits”, not as a single number such as the total number of seconds. For instance, a duration of 70 seconds should be stored as 1 minute and 10 seconds.

  • b) Explain how to compare two durations for equality and how to implement the Comparable interface.

  • c) Define factory methods that construct durations representing a certain number of weeks, days, hours, minutes, or seconds. An example of such a factory method would be a function days() that is declared as follows:

    public static Duration days(int n);
    

    In this case, calling days(-8) should return a duration that represents minus 1 week and 1 day.

    Also define corresponding methods for querying the number of weeks, days, etc. stored in a duration.

To add and subtract durations, we can use algorithms similar to those for big integers. The main difference is that each unit of time has its own radix, so subtracting 2 seconds from 1 day produces 23 hours, 59 minutes, and 58 seconds.

  • d) Implement methods for adding and subtracting durations.

In our discussion so far we have represented durations using a mixture of units such as “1 hour and 30 minutes”, but it is also possible to express the same durations using single units of time such as “1.5 hours” or “90 minutes” or “5400 seconds”.

  • e) Implement methods such as totalWeeks() or totalDays() that convert a duration to the given unit of time, returning the result as a double.

Computing Pi

Exercise 11.22. The problem of computing numerical approximations to \(\pi \) — the ratio of a circle’s circumference to its diameter — has a long and storied history. The first real algorithm for estimating \(\pi \) is due to the Greek mathematician Archimedes of Syracuse.

The idea behind Archimedes’ algorithm is to approximate circles using many-sided polygons. For example, given a circle of radius 1, we can construct two regular \(n\)-sided polygons, one inscribed in the circle and one circumscribed around it, as illustrated in Fig. 11.1. It is clear that the circle’s circumference, which is \(2\pi \), must larger than the perimeter of the inscribed polygon, which we call \(p_n\), but smaller than the perimeter of the circumscribed polygon, which we call \(P_n\):

\begin{equation*} p_n < 2\pi < P_n. \end{equation*}

The more sides the polygons have, the closer they fit the circle, so as we increase \(n\), the values \(p_n\) and \(P_n\) converge toward the true circumference \(2\pi \).

Figure 11.1 The geometry of Archimedes’ method. The circumference of the gray circle can be bounded from below and above by constructing the inscribed and circumscribed polygons and measuring their perimeter. The more sides we use, the better our estimate of \(\pi \) becomes.

Archimedes’ crucial insight was that it is possible to compute \(p_n\) and \(P_n\) for large values of \(n\) without actually constructing the corresponding polygons. Instead, we can use the following formulas to repeatedly double the number of sides:

\begin{equation} \label {eq:archimedes} p_{2n} = \frac {2p_nP_n}{p_n + P_n},\qquad P_{2n} = \sqrt {p_{2n} P_n}. \end{equation}

This formula is also known as Archimedes’ recurrence formula (see Box 11.5 for a proof). The first identity states that \(p_{2n}\) is the harmonic mean of \(p_n\) and \(P_n\), and the second identity states that \(P_{2n}\) is the geometric mean of \(p_{2n}\) and \(P_n\).

For small \(n\) we can derive the values of \(p_n\) and \(P_n\) geometrically. For \(n=4\) the inscribed square has a side length of \(1/\sqrt {2}\) and the circumscribed square has a side length of 1, so we have \(p_4 = 2\sqrt {2}\) and \(P_4= 4\). Similarly, for \(n=6\) the inscribed and circumscribed hexagons have a side length of \(1/2\) and \(1/\sqrt {3}\), respectively, so the perimeters are \(p_6 = 3\) and \(P_6 =2\sqrt {3}\). Using these starting values we then repeatedly apply Archimedes’ recurrence formula to compute increasingly good estimates of \(\pi \).

  • a) Write a program that computes an approximation to \(\pi \) using Archimedes recurrence formula. Estimate the number of correct decimal digits this algorithm produces per iteration.

Box 11.5: Derivation of Archimedes’ AlgorithmArchimedes’ recurrence formula in Eq. (11.21) is easy to prove using basic trigonometry. The idea is to take a circle of radius 1 and construct inscribed and circumscribed \(n\)-gons as indicated in the following image:

Each segment consists of two right triangles, so the perimeter \(p_n\) of the inscribed polygon and the perimeter \(P_n\) of the circumscribed polygon can be expressed as

\begin{equation*} P_n = 2n\tan \pi /n,\qquad p_n = 2n\sin \pi /n. \end{equation*}

The formulas for \(P_{2n}\) and \(p_{2n}\) now follow from the following trigonometric identities for half angles:

\begin{align*} \tan (\alpha /2)=\frac {\sin \alpha }{1+\cos \alpha } = \frac {1-\cos \alpha }{\sin \alpha },\qquad \sin (\alpha /2)= \sqrt {\frac {1-\cos \alpha }{2}}. \end{align*} By substituting \(\alpha =\pi /n\) we get:

\begin{align*} P_{2n} &= 4n\tan (\alpha /2) = 4n \frac {\sin \alpha }{1 + \cos \alpha } = 4n \frac {\sin \alpha \tan \alpha }{\sin \alpha +\tan \alpha } = \frac {2P_np_n}{P_n + p_n}, \intertext {and} p_{2n} &= 4n\sin (\alpha /2) = \sqrt {8n^2(1-\cos \alpha )} = \sqrt {8n^2\sin \alpha \tan (\alpha /2)} = \sqrt {P_{2n}p_n}. \end{align*}

Exercise 11.23. For many centuries, Archimedes’ method remained the best known method for computing \(\pi \), but its slow convergence and the amount of computational work it requires made it hard to use in practice. It wasn’t until the development of calculus in the 17th century — almost two millennia later — that more efficient methods for approximating \(\pi \) finally became available.

The most important formula from this era is Machin’s formula, which relates \(\pi \) to the arctan function:

\begin{equation} \label {eq:machin} \frac {\pi }{4}=4\arctan \frac {1}{5}-\arctan \frac {1}{239}. \end{equation}

The arctan function itself can be approximated very efficiently using its Taylor expansion:

\begin{equation} \label {eq:arctan} \arctan \left (\frac {1}{x}\right ) = \frac {1}{x}-\frac {1}{3x^3} + \frac {1}{5x^5}-\cdots . \end{equation}

For \(x>1\) this series expansion converges very quickly since the denominators grow rapidly.

  • a) Use Machin’s formula to manually compute an approximation to \(\pi \); use the first two terms of the expansion in Eq. (11.23).

It is easy to adapt Machin’s formula to compute digits of \(\pi \) using integer arithmetic only. First, we scale Eq. (11.22) by multiplying both sides by a large integer \(U\):

\begin{equation} \label {eq:machin-scaled} \pi U=16U\arctan \frac {1}{5}-4U\arctan \frac {1}{239}. \end{equation}

If we set \(U=10^k\), the integer part of the right-hand side contains the first \(k\) decimal digits of \(\pi \). To compute this integer part, we first note that \(A\cdot \arctan 1/x\) is

\begin{equation*} A\arctan \left (\frac {1}{x}\right ) = \frac {A}{x}-\frac {A}{3x^3} + \frac {A}{5x^5}-\cdots . \end{equation*}

Now, ignoring the fractional parts of all terms, we replace the divisions on the right-hand side with integer divisions:

\begin{equation} \label {eq:arctan1x} A\cdot \arctan \left (\frac {1}{x}\right ) \approx \left \lfloor \frac {A}{x}\right \rfloor - \left \lfloor \frac {A}{3x^3}\right \rfloor + \left \lfloor \frac {A}{5x^5}\right \rfloor - \cdots \end{equation}

Since the denominators \((2k + 1)x^{2k + 1}\) grow very quickly, almost all of the resulting terms are zero, so we can truncate the series after a finite number of terms.

  • b) Use this approximation to manually compute \(100\pi \).

  • c) Implement Eq. (11.24) and Eq. (11.25) to obtain an algorithm that estimates \(U\pi \) for a given value of \(U\).

In general, we have to be careful when ignoring the fractional parts in a computation like this, but in the case of Machin’s formula, the rounding errors turn out to be fairly minor.

  • d) Use your implementation of Machin’s algorithm to compute \(10^{10000}\pi \). Find a table of \(\pi \) online; how many digits of your result are correct?