BigInteger.cs 166 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956
  1. #pragma warning disable SA1028 // Code should not contain trailing whitespace
  2. //
  3. // System.Numerics.BigInteger
  4. //
  5. // Authors:
  6. // Rodrigo Kumpera (rkumpera@novell.com)
  7. // Marek Safar <marek.safar@gmail.com>
  8. //
  9. // Copyright (C) 2010 Novell, Inc (http://www.novell.com)
  10. // Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. // A big chuck of code comes the DLR (as hosted in http://ironpython.codeplex.com),
  32. // which has the following License:
  33. //
  34. /* ****************************************************************************
  35. *
  36. * Copyright (c) Microsoft Corporation.
  37. *
  38. * This source code is subject to terms and conditions of the Microsoft Public License. A
  39. * copy of the license can be found in the License.html file at the root of this distribution. If
  40. * you cannot locate the Microsoft Public License, please send an email to
  41. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  42. * by the terms of the Microsoft Public License.
  43. *
  44. * You must not remove this notice, or any other, from this software.
  45. *
  46. *
  47. * ***************************************************************************/
  48. #pragma warning restore SA1028 // Code should not contain trailing whitespace
  49. using System;
  50. using System.Collections.Generic;
  51. using System.Globalization;
  52. using Renci.SshNet.Abstractions;
  53. /*
  54. * Optimization:
  55. * - Have proper popcount function for IsPowerOfTwo
  56. * - Use unsafe ops to avoid bounds check
  57. * - CoreAdd could avoid some resizes by checking for equal sized array that top overflow
  58. * - For bitwise operators, hoist the conditionals out of their main loop
  59. * - Optimize BitScanBackward
  60. * - Use a carry variable to make shift opts do half the number of array ops.
  61. * -Schoolbook multiply is O(n^2), use Karatsuba /Toom-3 for large numbers
  62. */
  63. namespace Renci.SshNet.Common
  64. {
  65. /// <summary>
  66. /// Represents an arbitrarily large signed integer.
  67. /// </summary>
  68. public struct BigInteger : IComparable, IFormattable, IComparable<BigInteger>, IEquatable<BigInteger>
  69. {
  70. private const ulong Base = 0x100000000;
  71. private const int Bias = 1075;
  72. private const int DecimalSignMask = unchecked((int)0x80000000);
  73. private static readonly BigInteger ZeroSingleton = new BigInteger(0);
  74. private static readonly BigInteger OneSingleton = new BigInteger(1);
  75. private static readonly BigInteger MinusOneSingleton = new BigInteger(-1);
  76. // LSB on [0]
  77. private readonly uint[] _data;
  78. private readonly short _sign;
  79. #region SSH.NET additions
  80. /// <summary>
  81. /// Gets number of bits used by the number.
  82. /// </summary>
  83. /// <value>
  84. /// The number of the bit used.
  85. /// </value>
  86. public readonly int BitLength
  87. {
  88. get
  89. {
  90. if (_sign == 0)
  91. {
  92. return 0;
  93. }
  94. var msbIndex = _data.Length - 1;
  95. while (_data[msbIndex] == 0)
  96. {
  97. msbIndex--;
  98. }
  99. var msbBitCount = BitScanBackward(_data[msbIndex]) + 1;
  100. return (msbIndex * 4 * 8) + msbBitCount + ((_sign > 0) ? 0 : 1);
  101. }
  102. }
  103. /// <summary>
  104. /// Mods the inverse.
  105. /// </summary>
  106. /// <param name="bi">The bi.</param>
  107. /// <param name="modulus">The modulus.</param>
  108. /// <returns>
  109. /// Modulus inverted number.
  110. /// </returns>
  111. public static BigInteger ModInverse(BigInteger bi, BigInteger modulus)
  112. {
  113. BigInteger a = modulus, b = bi % modulus;
  114. BigInteger p0 = 0, p1 = 1;
  115. while (!b.IsZero)
  116. {
  117. if (b.IsOne)
  118. {
  119. return p1;
  120. }
  121. p0 += (a / b) * p1;
  122. a %= b;
  123. if (a.IsZero)
  124. {
  125. break;
  126. }
  127. if (a.IsOne)
  128. {
  129. return modulus - p0;
  130. }
  131. p1 += (b / a) * p0;
  132. b %= a;
  133. }
  134. return 0;
  135. }
  136. /// <summary>
  137. /// Returns positive remainder that results from division with two specified <see cref="BigInteger"/> values.
  138. /// </summary>
  139. /// <param name="dividend">The value to be divided.</param>
  140. /// <param name="divisor">The value to divide by.</param>
  141. /// <returns>
  142. /// Positive remainder that results from the division.
  143. /// </returns>
  144. public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor)
  145. {
  146. var result = dividend % divisor;
  147. if (result < 0)
  148. {
  149. result += divisor;
  150. }
  151. return result;
  152. }
  153. /// <summary>
  154. /// Generates a new, random <see cref="BigInteger"/> of the specified length.
  155. /// </summary>
  156. /// <param name="bitLength">The number of bits for the new number.</param>
  157. /// <returns>A random number of the specified length.</returns>
  158. public static BigInteger Random(int bitLength)
  159. {
  160. var bytesArray = CryptoAbstraction.GenerateRandom((bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0));
  161. bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value
  162. return new BigInteger(bytesArray);
  163. }
  164. #endregion SSH.NET additions
  165. private BigInteger(short sign, uint[] data)
  166. {
  167. _sign = sign;
  168. _data = data;
  169. }
  170. /// <summary>
  171. /// Initializes a new instance of the <see cref="BigInteger"/> structure using a 32-bit signed integer value.
  172. /// </summary>
  173. /// <param name="value">A 32-bit signed integer.</param>
  174. public BigInteger(int value)
  175. {
  176. if (value == 0)
  177. {
  178. _sign = 0;
  179. _data = null;
  180. }
  181. else if (value > 0)
  182. {
  183. _sign = 1;
  184. _data = new[] { (uint)value };
  185. }
  186. else
  187. {
  188. _sign = -1;
  189. _data = new[] { (uint)-value };
  190. }
  191. }
  192. /// <summary>
  193. /// Initializes a new instance of the <see cref="BigInteger"/> structure using an unsigned 32-bit integer value.
  194. /// </summary>
  195. /// <param name="value">An unsigned 32-bit integer value.</param>
  196. [CLSCompliant(false)]
  197. public BigInteger(uint value)
  198. {
  199. if (value == 0)
  200. {
  201. _sign = 0;
  202. _data = null;
  203. }
  204. else
  205. {
  206. _sign = 1;
  207. _data = new[] { value };
  208. }
  209. }
  210. /// <summary>
  211. /// Initializes a new instance of the <see cref="BigInteger"/> structure using a 64-bit signed integer value.
  212. /// </summary>
  213. /// <param name="value">A 64-bit signed integer.</param>
  214. public BigInteger(long value)
  215. {
  216. if (value == 0)
  217. {
  218. _sign = 0;
  219. _data = null;
  220. }
  221. else if (value > 0)
  222. {
  223. _sign = 1;
  224. var low = (uint)value;
  225. var high = (uint)(value >> 32);
  226. _data = new uint[high != 0 ? 2 : 1];
  227. _data[0] = low;
  228. if (high != 0)
  229. {
  230. _data[1] = high;
  231. }
  232. }
  233. else
  234. {
  235. _sign = -1;
  236. value = -value;
  237. var low = (uint)value;
  238. var high = (uint)((ulong)value >> 32);
  239. _data = new uint[high != 0 ? 2 : 1];
  240. _data[0] = low;
  241. if (high != 0)
  242. {
  243. _data[1] = high;
  244. }
  245. }
  246. }
  247. /// <summary>
  248. /// Initializes a new instance of the <see cref="BigInteger"/> structure with an unsigned 64-bit integer value.
  249. /// </summary>
  250. /// <param name="value">An unsigned 64-bit integer.</param>
  251. [CLSCompliant(false)]
  252. public BigInteger(ulong value)
  253. {
  254. if (value == 0)
  255. {
  256. _sign = 0;
  257. _data = null;
  258. }
  259. else
  260. {
  261. _sign = 1;
  262. var low = (uint)value;
  263. var high = (uint)(value >> 32);
  264. _data = new uint[high != 0 ? 2 : 1];
  265. _data[0] = low;
  266. if (high != 0)
  267. {
  268. _data[1] = high;
  269. }
  270. }
  271. }
  272. /// <summary>
  273. /// Initializes a new instance of the <see cref="BigInteger"/> structure using a double-precision floating-point value.
  274. /// </summary>
  275. /// <param name="value">A double-precision floating-point value.</param>
  276. public BigInteger(double value)
  277. {
  278. if (double.IsNaN(value) || double.IsInfinity(value))
  279. {
  280. throw new OverflowException();
  281. }
  282. var bytes = BitConverter.GetBytes(value);
  283. var mantissa = Mantissa(bytes);
  284. if (mantissa == 0)
  285. {
  286. // 1.0 * 2**exp, we have a power of 2
  287. int exponent = Exponent(bytes);
  288. if (exponent == 0)
  289. {
  290. _sign = 0;
  291. _data = null;
  292. return;
  293. }
  294. var res = Negative(bytes) ? MinusOne : One;
  295. res <<= exponent - 0x3ff;
  296. _sign = res._sign;
  297. _data = res._data;
  298. }
  299. else
  300. {
  301. // 1.mantissa * 2**exp
  302. int exponent = Exponent(bytes);
  303. mantissa |= 0x10000000000000ul;
  304. BigInteger res = mantissa;
  305. res = exponent > Bias ? res << (exponent - Bias) : res >> (Bias - exponent);
  306. _sign = (short)(Negative(bytes) ? -1 : 1);
  307. _data = res._data;
  308. }
  309. }
  310. /// <summary>
  311. /// Initializes a new instance of the <see cref="BigInteger"/> structure using a single-precision floating-point value.
  312. /// </summary>
  313. /// <param name="value">A single-precision floating-point value.</param>
  314. public BigInteger(float value)
  315. : this((double)value)
  316. {
  317. }
  318. /// <summary>
  319. /// Initializes a new instance of the <see cref="BigInteger"/> structure using a <see cref="decimal"/> value.
  320. /// </summary>
  321. /// <param name="value">A decimal number.</param>
  322. public BigInteger(decimal value)
  323. {
  324. // First truncate to get scale to 0 and extract bits
  325. var bits = decimal.GetBits(decimal.Truncate(value));
  326. var size = 3;
  327. while (size > 0 && bits[size - 1] == 0)
  328. {
  329. size--;
  330. }
  331. if (size == 0)
  332. {
  333. _sign = 0;
  334. _data = null;
  335. return;
  336. }
  337. _sign = (short)((bits[3] & DecimalSignMask) != 0 ? -1 : 1);
  338. _data = new uint[size];
  339. _data[0] = (uint)bits[0];
  340. if (size > 1)
  341. {
  342. _data[1] = (uint)bits[1];
  343. }
  344. if (size > 2)
  345. {
  346. _data[2] = (uint)bits[2];
  347. }
  348. }
  349. /// <summary>
  350. /// Initializes a new instance of the <see cref="BigInteger"/> structure using the values in a byte array.
  351. /// </summary>
  352. /// <param name="value">An array of <see cref="byte"/> values in little-endian order.</param>
  353. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  354. [CLSCompliant(false)]
  355. public BigInteger(byte[] value)
  356. {
  357. if (value is null)
  358. {
  359. throw new ArgumentNullException(nameof(value));
  360. }
  361. var len = value.Length;
  362. if (len == 0 || (len == 1 && value[0] == 0))
  363. {
  364. _sign = 0;
  365. _data = null;
  366. return;
  367. }
  368. if ((value[len - 1] & 0x80) != 0)
  369. {
  370. _sign = -1;
  371. }
  372. else
  373. {
  374. _sign = 1;
  375. }
  376. #pragma warning disable CA1508 // Avoid dead conditional code | this is the following bug in the analyzer rule: https://github.com/dotnet/roslyn-analyzers/issues/6991
  377. if (_sign == 1)
  378. #pragma warning restore CA1508 // Avoid dead conditional code
  379. {
  380. while (value[len - 1] == 0)
  381. {
  382. if (--len == 0)
  383. {
  384. _sign = 0;
  385. _data = null;
  386. return;
  387. }
  388. }
  389. int size;
  390. var fullWords = size = len / 4;
  391. if ((len & 0x3) != 0)
  392. {
  393. ++size;
  394. }
  395. _data = new uint[size];
  396. var j = 0;
  397. for (var i = 0; i < fullWords; ++i)
  398. {
  399. _data[i] = (uint)value[j++] |
  400. (uint)(value[j++] << 8) |
  401. (uint)(value[j++] << 16) |
  402. (uint)(value[j++] << 24);
  403. }
  404. size = len & 0x3;
  405. if (size > 0)
  406. {
  407. var idx = _data.Length - 1;
  408. for (var i = 0; i < size; ++i)
  409. {
  410. _data[idx] |= (uint)(value[j++] << (i * 8));
  411. }
  412. }
  413. }
  414. else
  415. {
  416. int size;
  417. var fullWords = size = len / 4;
  418. if ((len & 0x3) != 0)
  419. {
  420. ++size;
  421. }
  422. _data = new uint[size];
  423. uint word, borrow = 1;
  424. ulong sub;
  425. var j = 0;
  426. for (var i = 0; i < fullWords; ++i)
  427. {
  428. word = (uint)value[j++] |
  429. (uint)(value[j++] << 8) |
  430. (uint)(value[j++] << 16) |
  431. (uint)(value[j++] << 24);
  432. sub = (ulong)word - borrow;
  433. word = (uint)sub;
  434. borrow = (uint)(sub >> 32) & 0x1u;
  435. _data[i] = ~word;
  436. }
  437. size = len & 0x3;
  438. if (size > 0)
  439. {
  440. word = 0;
  441. uint storeMask = 0;
  442. for (var i = 0; i < size; ++i)
  443. {
  444. word |= (uint)(value[j++] << (i * 8));
  445. storeMask = (storeMask << 8) | 0xFF;
  446. }
  447. sub = word - borrow;
  448. word = (uint)sub;
  449. borrow = (uint)(sub >> 32) & 0x1u;
  450. if ((~word & storeMask) == 0)
  451. {
  452. Array.Resize(ref _data, _data.Length - 1);
  453. }
  454. else
  455. {
  456. _data[_data.Length - 1] = ~word & storeMask;
  457. }
  458. }
  459. if (borrow != 0)
  460. {
  461. #pragma warning disable CA2201 // Do not raise reserved exception types
  462. throw new Exception("non zero final carry");
  463. #pragma warning restore CA2201 // Do not raise reserved exception types
  464. }
  465. }
  466. }
  467. private static bool Negative(byte[] v)
  468. {
  469. return (v[7] & 0x80) != 0;
  470. }
  471. private static ushort Exponent(byte[] v)
  472. {
  473. return (ushort)((((ushort)(v[7] & 0x7F)) << (ushort)4) | (((ushort)(v[6] & 0xF0)) >> 4));
  474. }
  475. private static ulong Mantissa(byte[] v)
  476. {
  477. var i1 = (uint)v[0] | ((uint)v[1] << 8) | ((uint)v[2] << 16) | ((uint)v[3] << 24);
  478. var i2 = (uint)v[4] | ((uint)v[5] << 8) | ((uint)(v[6] & 0xF) << 16);
  479. return (ulong)i1 | ((ulong)i2 << 32);
  480. }
  481. /// <summary>
  482. /// Gets a value indicating whether the value of the current <see cref="BigInteger"/> object is an even number.
  483. /// </summary>
  484. /// <value>
  485. /// <see langword="true"/> if the value of the <see cref="BigInteger"/> object is an even number; otherwise, <see langword="false"/>.
  486. /// </value>
  487. public readonly bool IsEven
  488. {
  489. get { return _sign == 0 || (_data[0] & 0x1) == 0; }
  490. }
  491. /// <summary>
  492. /// Gets a value indicating whether the value of the current <see cref="BigInteger"/> object is <see cref="One"/>.
  493. /// </summary>
  494. /// <value>
  495. /// <see langword="true"/> if the value of the <see cref="BigInteger"/> object is <see cref="One"/>;
  496. /// otherwise, <see langword="false"/>.
  497. /// </value>
  498. public readonly bool IsOne
  499. {
  500. get { return _sign == 1 && _data.Length == 1 && _data[0] == 1; }
  501. }
  502. // Gem from Hacker's Delight
  503. // Returns the number of bits set in @x
  504. private static int PopulationCount(uint x)
  505. {
  506. x -= (x >> 1) & 0x55555555;
  507. x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
  508. x = (x + (x >> 4)) & 0x0F0F0F0F;
  509. x += x >> 8;
  510. x += x >> 16;
  511. return (int)(x & 0x0000003F);
  512. }
  513. /// <summary>
  514. /// Returns the number of bits set in <paramref name="x"/>.
  515. /// </summary>
  516. /// <returns>
  517. /// The number of bits set in <paramref name="x"/>.
  518. /// </returns>
  519. /// <remarks>
  520. /// Based on code by Zilong Tan on Ulib released under MIT license.
  521. /// </remarks>
  522. private static int PopulationCount(ulong x)
  523. {
  524. x -= (x >> 1) & 0x5555555555555555UL;
  525. x = (x & 0x3333333333333333UL) + ((x >> 2) & 0x3333333333333333UL);
  526. x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fUL;
  527. return (int)((x * 0x0101010101010101UL) >> 56);
  528. }
  529. private static int LeadingZeroCount(uint value)
  530. {
  531. value |= value >> 1;
  532. value |= value >> 2;
  533. value |= value >> 4;
  534. value |= value >> 8;
  535. value |= value >> 16;
  536. return 32 - PopulationCount(value); // 32 = bits in uint
  537. }
  538. private static int LeadingZeroCount(ulong value)
  539. {
  540. value |= value >> 1;
  541. value |= value >> 2;
  542. value |= value >> 4;
  543. value |= value >> 8;
  544. value |= value >> 16;
  545. value |= value >> 32;
  546. return 64 - PopulationCount(value); // 64 = bits in ulong
  547. }
  548. private static double BuildDouble(int sign, ulong mantissa, int exponent)
  549. {
  550. const int exponentBias = 1023;
  551. const int mantissaLength = 52;
  552. const int exponentLength = 11;
  553. const int maxExponent = 2046;
  554. const long mantissaMask = 0xfffffffffffffL;
  555. const long exponentMask = 0x7ffL;
  556. const ulong negativeMark = 0x8000000000000000uL;
  557. if (sign == 0 || mantissa == 0)
  558. {
  559. return 0.0;
  560. }
  561. exponent += exponentBias + mantissaLength;
  562. var offset = LeadingZeroCount(mantissa) - exponentLength;
  563. if (exponent - offset > maxExponent)
  564. {
  565. return sign > 0 ? double.PositiveInfinity : double.NegativeInfinity;
  566. }
  567. if (offset < 0)
  568. {
  569. mantissa >>= -offset;
  570. exponent += -offset;
  571. }
  572. else if (offset >= exponent)
  573. {
  574. mantissa <<= exponent - 1;
  575. exponent = 0;
  576. }
  577. else
  578. {
  579. mantissa <<= offset;
  580. exponent -= offset;
  581. }
  582. mantissa &= mantissaMask;
  583. if ((exponent & exponentMask) == exponent)
  584. {
  585. unchecked
  586. {
  587. var bits = mantissa | ((ulong)exponent << mantissaLength);
  588. if (sign < 0)
  589. {
  590. bits |= negativeMark;
  591. }
  592. return BitConverter.Int64BitsToDouble((long)bits);
  593. }
  594. }
  595. return sign > 0 ? double.PositiveInfinity : double.NegativeInfinity;
  596. }
  597. /// <summary>
  598. /// Gets a value Indicating whether the value of the current <see cref="BigInteger"/> object is a power of two.
  599. /// </summary>
  600. /// <value>
  601. /// <see langword="true"/> if the value of the <see cref="BigInteger"/> object is a power of two;
  602. /// otherwise, <see langword="false"/>.
  603. /// </value>
  604. public readonly bool IsPowerOfTwo
  605. {
  606. get
  607. {
  608. if (_sign != 1)
  609. {
  610. return false;
  611. }
  612. var foundBit = false;
  613. // This function is pop count == 1 for positive numbers
  614. foreach (var bit in _data)
  615. {
  616. var p = PopulationCount(bit);
  617. if (p > 0)
  618. {
  619. if (p > 1 || foundBit)
  620. {
  621. return false;
  622. }
  623. foundBit = true;
  624. }
  625. }
  626. return foundBit;
  627. }
  628. }
  629. /// <summary>
  630. /// Gets a value indicating whether the value of the current <see cref="BigInteger"/> object is <see cref="Zero"/>.
  631. /// </summary>
  632. /// <value>
  633. /// <see langword="true"/> if the value of the <see cref="BigInteger"/> object is <see cref="Zero"/>;
  634. /// otherwise, <see langword="false"/>.
  635. /// </value>
  636. public readonly bool IsZero
  637. {
  638. get { return _sign == 0; }
  639. }
  640. /// <summary>
  641. /// Gets a number that indicates the sign (negative, positive, or zero) of the current <see cref="BigInteger"/> object.
  642. /// </summary>
  643. /// <value>
  644. /// A number that indicates the sign of the <see cref="BigInteger"/> object.
  645. /// </value>
  646. public readonly int Sign
  647. {
  648. get { return _sign; }
  649. }
  650. /// <summary>
  651. /// Gets a value that represents the number negative one (-1).
  652. /// </summary>
  653. /// <value>
  654. /// An integer whose value is negative one (-1).
  655. /// </value>
  656. public static BigInteger MinusOne
  657. {
  658. get { return MinusOneSingleton; }
  659. }
  660. /// <summary>
  661. /// Gets a value that represents the number one (1).
  662. /// </summary>
  663. /// <value>
  664. /// An object whose value is one (1).
  665. /// </value>
  666. public static BigInteger One
  667. {
  668. get { return OneSingleton; }
  669. }
  670. /// <summary>
  671. /// Gets a value that represents the number 0 (zero).
  672. /// </summary>
  673. /// <value>
  674. /// An integer whose value is 0 (zero).
  675. /// </value>
  676. public static BigInteger Zero
  677. {
  678. get { return ZeroSingleton; }
  679. }
  680. /// <summary>
  681. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a 32-bit signed integer value.
  682. /// </summary>
  683. /// <param name="value">The value to convert to a 32-bit signed integer.</param>
  684. /// <returns>
  685. /// An object that contains the value of the <paramref name="value"/> parameter.
  686. /// </returns>
  687. #pragma warning disable CA2225 // Operator overloads have named alternates
  688. public static explicit operator int(BigInteger value)
  689. #pragma warning restore CA2225 // Operator overloads have named alternates
  690. {
  691. if (value._data is null)
  692. {
  693. return 0;
  694. }
  695. if (value._data.Length > 1)
  696. {
  697. throw new OverflowException();
  698. }
  699. var data = value._data[0];
  700. if (value._sign == 1)
  701. {
  702. if (data > (uint)int.MaxValue)
  703. {
  704. throw new OverflowException();
  705. }
  706. return (int)data;
  707. }
  708. if (value._sign == -1)
  709. {
  710. if (data > 0x80000000u)
  711. {
  712. throw new OverflowException();
  713. }
  714. return -(int)data;
  715. }
  716. return 0;
  717. }
  718. /// <summary>
  719. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to an unsigned 32-bit integer value.
  720. /// </summary>
  721. /// <param name="value">The value to convert to an unsigned 32-bit integer.</param>
  722. /// <returns>
  723. /// An object that contains the value of the <paramref name="value"/> parameter.
  724. /// </returns>
  725. [CLSCompliant(false)]
  726. #pragma warning disable CA2225 // Operator overloads have named alternates
  727. public static explicit operator uint(BigInteger value)
  728. #pragma warning restore CA2225 // Operator overloads have named alternates
  729. {
  730. if (value._data is null)
  731. {
  732. return 0;
  733. }
  734. if (value._data.Length > 1 || value._sign == -1)
  735. {
  736. throw new OverflowException();
  737. }
  738. return value._data[0];
  739. }
  740. /// <summary>
  741. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a 16-bit signed integer value.
  742. /// </summary>
  743. /// <param name="value">The value to convert to a 16-bit signed integer.</param>
  744. /// <returns>
  745. /// An object that contains the value of the <paramref name="value"/> parameter.
  746. /// </returns>
  747. #pragma warning disable CA2225 // Operator overloads have named alternates
  748. public static explicit operator short(BigInteger value)
  749. #pragma warning restore CA2225 // Operator overloads have named alternates
  750. {
  751. var val = (int)value;
  752. if (val is < short.MinValue or > short.MaxValue)
  753. {
  754. throw new OverflowException();
  755. }
  756. return (short)val;
  757. }
  758. /// <summary>
  759. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a 16-bit unsigned integer value.
  760. /// </summary>
  761. /// <param name="value">The value to convert to a 16-bit unsigned integer.</param>
  762. /// <returns>
  763. /// An object that contains the value of the <paramref name="value"/> parameter.
  764. /// </returns>
  765. [CLSCompliant(false)]
  766. #pragma warning disable CA2225 // Operator overloads have named alternates
  767. public static explicit operator ushort(BigInteger value)
  768. #pragma warning restore CA2225 // Operator overloads have named alternates
  769. {
  770. var val = (uint)value;
  771. if (val > ushort.MaxValue)
  772. {
  773. throw new OverflowException();
  774. }
  775. return (ushort)val;
  776. }
  777. /// <summary>
  778. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to an unsigned byte value.
  779. /// </summary>
  780. /// <param name="value">The value to convert to a <see cref="byte"/>.</param>
  781. /// <returns>
  782. /// An object that contains the value of the <paramref name="value"/> parameter.
  783. /// </returns>
  784. #pragma warning disable CA2225 // Operator overloads have named alternates
  785. public static explicit operator byte(BigInteger value)
  786. #pragma warning restore CA2225 // Operator overloads have named alternates
  787. {
  788. var val = (uint)value;
  789. if (val > byte.MaxValue)
  790. {
  791. throw new OverflowException();
  792. }
  793. return (byte)val;
  794. }
  795. /// <summary>
  796. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a signed 8-bit value.
  797. /// </summary>
  798. /// <param name="value">The value to convert to a signed 8-bit value.</param>
  799. /// <returns>
  800. /// An object that contains the value of the <paramref name="value"/> parameter.
  801. /// </returns>
  802. [CLSCompliant(false)]
  803. #pragma warning disable CA2225 // Operator overloads have named alternates
  804. public static explicit operator sbyte(BigInteger value)
  805. #pragma warning restore CA2225 // Operator overloads have named alternates
  806. {
  807. var val = (int)value;
  808. if (val is < sbyte.MinValue or > sbyte.MaxValue)
  809. {
  810. throw new OverflowException();
  811. }
  812. return (sbyte)val;
  813. }
  814. /// <summary>
  815. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a 64-bit signed integer value.
  816. /// </summary>
  817. /// <param name="value">The value to convert to a 64-bit signed integer.</param>
  818. /// <returns>
  819. /// An object that contains the value of the <paramref name="value"/> parameter.
  820. /// </returns>
  821. #pragma warning disable CA2225 // Operator overloads have named alternates
  822. public static explicit operator long(BigInteger value)
  823. #pragma warning restore CA2225 // Operator overloads have named alternates
  824. {
  825. if (value._data is null)
  826. {
  827. return 0;
  828. }
  829. if (value._data.Length > 2)
  830. {
  831. throw new OverflowException();
  832. }
  833. var low = value._data[0];
  834. if (value._data.Length == 1)
  835. {
  836. if (value._sign == 1)
  837. {
  838. return (long)low;
  839. }
  840. var res = (long)low;
  841. return -res;
  842. }
  843. var high = value._data[1];
  844. if (value._sign == 1)
  845. {
  846. if (high >= 0x80000000u)
  847. {
  848. throw new OverflowException();
  849. }
  850. return (((long)high) << 32) | low;
  851. }
  852. /*
  853. We cannot represent negative numbers smaller than long.MinValue.
  854. Those values are encoded into what look negative numbers, so negating
  855. them produces a positive value, that's why it's safe to check for that
  856. condition.
  857. long.MinValue works fine since it's bigint encoding looks like a negative
  858. number, but since long.MinValue == -long.MinValue, we're good.
  859. */
  860. var result = -((((long)high) << 32) | (long)low);
  861. if (result > 0)
  862. {
  863. throw new OverflowException();
  864. }
  865. return result;
  866. }
  867. /// <summary>
  868. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to an unsigned 64-bit integer value.
  869. /// </summary>
  870. /// <param name="value">The value to convert to an unsigned 64-bit integer.</param>
  871. /// <returns>
  872. /// An object that contains the value of the <paramref name="value"/> parameter.
  873. /// </returns>
  874. [CLSCompliant(false)]
  875. #pragma warning disable CA2225 // Operator overloads have named alternates
  876. public static explicit operator ulong(BigInteger value)
  877. #pragma warning restore CA2225 // Operator overloads have named alternates
  878. {
  879. if (value._data is null)
  880. {
  881. return 0;
  882. }
  883. if (value._data.Length > 2 || value._sign == -1)
  884. {
  885. throw new OverflowException();
  886. }
  887. var low = value._data[0];
  888. if (value._data.Length == 1)
  889. {
  890. return low;
  891. }
  892. var high = value._data[1];
  893. return (((ulong)high) << 32) | low;
  894. }
  895. /// <summary>
  896. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a <see cref="double"/> value.
  897. /// </summary>
  898. /// <param name="value">The value to convert to a <see cref="double"/>.</param>
  899. /// <returns>
  900. /// An object that contains the value of the <paramref name="value"/> parameter.
  901. /// </returns>
  902. #pragma warning disable CA2225 // Operator overloads have named alternates
  903. public static explicit operator double(BigInteger value)
  904. #pragma warning restore CA2225 // Operator overloads have named alternates
  905. {
  906. if (value._data is null)
  907. {
  908. return 0.0;
  909. }
  910. switch (value._data.Length)
  911. {
  912. case 1:
  913. return BuildDouble(value._sign, value._data[0], 0);
  914. case 2:
  915. return BuildDouble(value._sign, (ulong)value._data[1] << 32 | (ulong)value._data[0], 0);
  916. default:
  917. var index = value._data.Length - 1;
  918. var word = value._data[index];
  919. var mantissa = ((ulong)word << 32) | value._data[index - 1];
  920. var missing = LeadingZeroCount(word) - 11; // 11 = bits in exponent
  921. if (missing > 0)
  922. {
  923. // add the missing bits from the next word
  924. mantissa = (mantissa << missing) | (value._data[index - 2] >> (32 - missing));
  925. }
  926. else
  927. {
  928. mantissa >>= -missing;
  929. }
  930. return BuildDouble(value._sign, mantissa, ((value._data.Length - 2) * 32) - missing);
  931. }
  932. }
  933. /// <summary>
  934. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a single-precision floating-point value.
  935. /// </summary>
  936. /// <param name="value">The value to convert to a single-precision floating-point value.</param>
  937. /// <returns>
  938. /// An object that contains the value of the <paramref name="value"/> parameter.
  939. /// </returns>
  940. #pragma warning disable CA2225 // Operator overloads have named alternates
  941. public static explicit operator float(BigInteger value)
  942. #pragma warning restore CA2225 // Operator overloads have named alternates
  943. {
  944. return (float)(double)value;
  945. }
  946. /// <summary>
  947. /// Defines an explicit conversion of a <see cref="BigInteger"/> object to a <see cref="decimal"/> value.
  948. /// </summary>
  949. /// <param name="value">The value to convert to a <see cref="decimal"/>.</param>
  950. /// <returns>
  951. /// An object that contains the value of the <paramref name="value"/> parameter.
  952. /// </returns>
  953. #pragma warning disable CA2225 // Operator overloads have named alternates
  954. public static explicit operator decimal(BigInteger value)
  955. #pragma warning restore CA2225 // Operator overloads have named alternates
  956. {
  957. if (value._data is null)
  958. {
  959. return decimal.Zero;
  960. }
  961. var data = value._data;
  962. if (data.Length > 3)
  963. {
  964. throw new OverflowException();
  965. }
  966. int lo = 0, mi = 0, hi = 0;
  967. if (data.Length > 2)
  968. {
  969. hi = (int)data[2];
  970. }
  971. if (data.Length > 1)
  972. {
  973. mi = (int)data[1];
  974. }
  975. if (data.Length > 0)
  976. {
  977. lo = (int)data[0];
  978. }
  979. return new decimal(lo, mi, hi, value._sign < 0, 0);
  980. }
  981. /// <summary>
  982. /// Defines an implicit conversion of a signed 32-bit integer to a <see cref="BigInteger"/> value.
  983. /// </summary>
  984. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  985. /// <returns>
  986. /// An object that contains the value of the <paramref name="value"/> parameter.
  987. /// </returns>
  988. #pragma warning disable CA2225 // Operator overloads have named alternates
  989. public static implicit operator BigInteger(int value)
  990. #pragma warning restore CA2225 // Operator overloads have named alternates
  991. {
  992. return new BigInteger(value);
  993. }
  994. /// <summary>
  995. /// Defines an implicit conversion of a 32-bit unsigned integer to a <see cref="BigInteger"/> value.
  996. /// </summary>
  997. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  998. /// <returns>
  999. /// An object that contains the value of the <paramref name="value"/> parameter.
  1000. /// </returns>
  1001. [CLSCompliant(false)]
  1002. #pragma warning disable CA2225 // Operator overloads have named alternates
  1003. public static implicit operator BigInteger(uint value)
  1004. #pragma warning restore CA2225 // Operator overloads have named alternates
  1005. {
  1006. return new BigInteger(value);
  1007. }
  1008. /// <summary>
  1009. /// Defines an implicit conversion of a signed 16-bit integer to a BigInteger value.
  1010. /// </summary>
  1011. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1012. /// <returns>
  1013. /// An object that contains the value of the <paramref name="value"/> parameter.
  1014. /// </returns>
  1015. #pragma warning disable CA2225 // Operator overloads have named alternates
  1016. public static implicit operator BigInteger(short value)
  1017. #pragma warning restore CA2225 // Operator overloads have named alternates
  1018. {
  1019. return new BigInteger(value);
  1020. }
  1021. /// <summary>
  1022. /// Defines an implicit conversion of a 16-bit unsigned integer to a <see cref="BigInteger"/> value.
  1023. /// </summary>
  1024. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1025. /// <returns>
  1026. /// An object that contains the value of the <paramref name="value"/> parameter.
  1027. /// </returns>
  1028. [CLSCompliant(false)]
  1029. #pragma warning disable CA2225 // Operator overloads have named alternates
  1030. public static implicit operator BigInteger(ushort value)
  1031. #pragma warning restore CA2225 // Operator overloads have named alternates
  1032. {
  1033. return new BigInteger(value);
  1034. }
  1035. /// <summary>
  1036. /// Defines an implicit conversion of an unsigned byte to a <see cref="BigInteger"/> value.
  1037. /// </summary>
  1038. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1039. /// <returns>
  1040. /// An object that contains the value of the <paramref name="value"/> parameter.
  1041. /// </returns>
  1042. #pragma warning disable CA2225 // Operator overloads have named alternates
  1043. public static implicit operator BigInteger(byte value)
  1044. #pragma warning restore CA2225 // Operator overloads have named alternates
  1045. {
  1046. return new BigInteger(value);
  1047. }
  1048. /// <summary>
  1049. /// Defines an implicit conversion of a signed byte to a <see cref="BigInteger"/> value.
  1050. /// </summary>
  1051. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1052. /// <returns>
  1053. /// An object that contains the value of the <paramref name="value"/> parameter.
  1054. /// </returns>
  1055. [CLSCompliant(false)]
  1056. #pragma warning disable CA2225 // Operator overloads have named alternates
  1057. public static implicit operator BigInteger(sbyte value)
  1058. #pragma warning restore CA2225 // Operator overloads have named alternates
  1059. {
  1060. return new BigInteger(value);
  1061. }
  1062. /// <summary>
  1063. /// Defines an implicit conversion of a signed 64-bit integer to a <see cref="BigInteger"/> value.
  1064. /// </summary>
  1065. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1066. /// <returns>
  1067. /// An object that contains the value of the <paramref name="value"/> parameter.
  1068. /// </returns>
  1069. #pragma warning disable CA2225 // Operator overloads have named alternates
  1070. public static implicit operator BigInteger(long value)
  1071. #pragma warning restore CA2225 // Operator overloads have named alternates
  1072. {
  1073. return new BigInteger(value);
  1074. }
  1075. /// <summary>
  1076. /// Defines an implicit conversion of a 64-bit unsigned integer to a <see cref="BigInteger"/> value.
  1077. /// </summary>
  1078. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1079. /// <returns>
  1080. /// An object that contains the value of the <paramref name="value"/> parameter.
  1081. /// </returns>
  1082. [CLSCompliant(false)]
  1083. #pragma warning disable CA2225 // Operator overloads have named alternates
  1084. public static implicit operator BigInteger(ulong value)
  1085. #pragma warning restore CA2225 // Operator overloads have named alternates
  1086. {
  1087. return new BigInteger(value);
  1088. }
  1089. /// <summary>
  1090. /// Defines an explicit conversion of a <see cref="double"/> value to a <see cref="BigInteger"/> value.
  1091. /// </summary>
  1092. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1093. /// <returns>
  1094. /// An object that contains the value of the <paramref name="value"/> parameter.
  1095. /// </returns>
  1096. #pragma warning disable CA2225 // Operator overloads have named alternates
  1097. public static explicit operator BigInteger(double value)
  1098. #pragma warning restore CA2225 // Operator overloads have named alternates
  1099. {
  1100. return new BigInteger(value);
  1101. }
  1102. /// <summary>
  1103. /// Defines an explicit conversion of a <see cref="float"/> object to a <see cref="BigInteger"/> value.
  1104. /// </summary>
  1105. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1106. /// <returns>
  1107. /// An object that contains the value of the <paramref name="value"/> parameter.
  1108. /// </returns>
  1109. #pragma warning disable CA2225 // Operator overloads have named alternates
  1110. public static explicit operator BigInteger(float value)
  1111. #pragma warning restore CA2225 // Operator overloads have named alternates
  1112. {
  1113. return new BigInteger(value);
  1114. }
  1115. /// <summary>
  1116. /// Defines an explicit conversion of a <see cref="decimal"/> object to a <see cref="BigInteger"/> value.
  1117. /// </summary>
  1118. /// <param name="value">The value to convert to a <see cref="BigInteger"/>.</param>
  1119. /// <returns>
  1120. /// An object that contains the value of the <paramref name="value"/> parameter.
  1121. /// </returns>
  1122. #pragma warning disable CA2225 // Operator overloads have named alternates
  1123. public static explicit operator BigInteger(decimal value)
  1124. #pragma warning restore CA2225 // Operator overloads have named alternates
  1125. {
  1126. return new BigInteger(value);
  1127. }
  1128. /// <summary>
  1129. /// Adds the values of two specified <see cref="BigInteger"/> objects.
  1130. /// </summary>
  1131. /// <param name="left">The first value to add.</param>
  1132. /// <param name="right">The second value to add.</param>
  1133. /// <returns>
  1134. /// The sum of <paramref name="left"/> and <paramref name="right"/>.
  1135. /// </returns>
  1136. public static BigInteger operator +(BigInteger left, BigInteger right)
  1137. {
  1138. if (left._sign == 0)
  1139. {
  1140. return right;
  1141. }
  1142. if (right._sign == 0)
  1143. {
  1144. return left;
  1145. }
  1146. if (left._sign == right._sign)
  1147. {
  1148. return new BigInteger(left._sign, CoreAdd(left._data, right._data));
  1149. }
  1150. var r = CoreCompare(left._data, right._data);
  1151. if (r == 0)
  1152. {
  1153. return Zero;
  1154. }
  1155. if (r > 0)
  1156. {
  1157. // left > right
  1158. return new BigInteger(left._sign, CoreSub(left._data, right._data));
  1159. }
  1160. return new BigInteger(right._sign, CoreSub(right._data, left._data));
  1161. }
  1162. /// <summary>
  1163. /// Subtracts a <see cref="BigInteger"/> value from another <see cref="BigInteger"/> value.
  1164. /// </summary>
  1165. /// <param name="left">The value to subtract from (the minuend).</param>
  1166. /// <param name="right">The value to subtract (the subtrahend).</param>
  1167. /// <returns>
  1168. /// The result of subtracting <paramref name="right"/> from <paramref name="left"/>.
  1169. /// </returns>
  1170. public static BigInteger operator -(BigInteger left, BigInteger right)
  1171. {
  1172. if (right._sign == 0)
  1173. {
  1174. return left;
  1175. }
  1176. if (left._sign == 0)
  1177. {
  1178. return new BigInteger((short)-right._sign, right._data);
  1179. }
  1180. if (left._sign == right._sign)
  1181. {
  1182. var r = CoreCompare(left._data, right._data);
  1183. if (r == 0)
  1184. {
  1185. return Zero;
  1186. }
  1187. if (r > 0)
  1188. {
  1189. // left > right
  1190. return new BigInteger(left._sign, CoreSub(left._data, right._data));
  1191. }
  1192. return new BigInteger((short)-right._sign, CoreSub(right._data, left._data));
  1193. }
  1194. return new BigInteger(left._sign, CoreAdd(left._data, right._data));
  1195. }
  1196. /// <summary>
  1197. /// Multiplies two specified <see cref="BigInteger"/> values.
  1198. /// </summary>
  1199. /// <param name="left">The first value to multiply.</param>
  1200. /// <param name="right">The second value to multiply.</param>
  1201. /// <returns>
  1202. /// The product of left and right.
  1203. /// </returns>
  1204. public static BigInteger operator *(BigInteger left, BigInteger right)
  1205. {
  1206. if (left._sign == 0 || right._sign == 0)
  1207. {
  1208. return Zero;
  1209. }
  1210. if (left._data[0] == 1 && left._data.Length == 1)
  1211. {
  1212. if (left._sign == 1)
  1213. {
  1214. return right;
  1215. }
  1216. return new BigInteger((short)-right._sign, right._data);
  1217. }
  1218. if (right._data[0] == 1 && right._data.Length == 1)
  1219. {
  1220. if (right._sign == 1)
  1221. {
  1222. return left;
  1223. }
  1224. return new BigInteger((short)-left._sign, left._data);
  1225. }
  1226. var a = left._data;
  1227. var b = right._data;
  1228. var res = new uint[a.Length + b.Length];
  1229. for (var i = 0; i < a.Length; ++i)
  1230. {
  1231. var ai = a[i];
  1232. var k = i;
  1233. ulong carry = 0;
  1234. for (var j = 0; j < b.Length; ++j)
  1235. {
  1236. carry = carry + (((ulong)ai) * b[j]) + res[k];
  1237. res[k++] = (uint)carry;
  1238. carry >>= 32;
  1239. }
  1240. while (carry != 0)
  1241. {
  1242. carry += res[k];
  1243. res[k++] = (uint)carry;
  1244. carry >>= 32;
  1245. }
  1246. }
  1247. int m;
  1248. for (m = res.Length - 1; m >= 0 && res[m] == 0; --m)
  1249. {
  1250. // Intentionally empty block
  1251. }
  1252. if (m < res.Length - 1)
  1253. {
  1254. Array.Resize(ref res, m + 1);
  1255. }
  1256. return new BigInteger((short)(left._sign * right._sign), res);
  1257. }
  1258. /// <summary>
  1259. /// Divides a specified <see cref="BigInteger"/> value by another specified <see cref="BigInteger"/> value by using
  1260. /// integer division.
  1261. /// </summary>
  1262. /// <param name="dividend">The value to be divided.</param>
  1263. /// <param name="divisor">The value to divide by.</param>
  1264. /// <returns>
  1265. /// The integral result of the division.
  1266. /// </returns>
  1267. public static BigInteger operator /(BigInteger dividend, BigInteger divisor)
  1268. {
  1269. if (divisor._sign == 0)
  1270. {
  1271. throw new DivideByZeroException();
  1272. }
  1273. if (dividend._sign == 0)
  1274. {
  1275. return dividend;
  1276. }
  1277. DivModUnsigned(dividend._data, divisor._data, out var quotient, out _);
  1278. int i;
  1279. for (i = quotient.Length - 1; i >= 0 && quotient[i] == 0; --i)
  1280. {
  1281. // Intentionally empty block
  1282. }
  1283. if (i == -1)
  1284. {
  1285. return Zero;
  1286. }
  1287. if (i < quotient.Length - 1)
  1288. {
  1289. Array.Resize(ref quotient, i + 1);
  1290. }
  1291. return new BigInteger((short)(dividend._sign * divisor._sign), quotient);
  1292. }
  1293. /// <summary>
  1294. /// Returns the remainder that results from division with two specified <see cref="BigInteger"/> values.
  1295. /// </summary>
  1296. /// <param name="dividend">The value to be divided.</param>
  1297. /// <param name="divisor">The value to divide by.</param>
  1298. /// <returns>
  1299. /// The remainder that results from the division.
  1300. /// </returns>
  1301. public static BigInteger operator %(BigInteger dividend, BigInteger divisor)
  1302. {
  1303. if (divisor._sign == 0)
  1304. {
  1305. throw new DivideByZeroException();
  1306. }
  1307. if (dividend._sign == 0)
  1308. {
  1309. return dividend;
  1310. }
  1311. DivModUnsigned(dividend._data, divisor._data, out _, out var remainderValue);
  1312. int i;
  1313. for (i = remainderValue.Length - 1; i >= 0 && remainderValue[i] == 0; --i)
  1314. {
  1315. // Intentionally empty block
  1316. }
  1317. if (i == -1)
  1318. {
  1319. return Zero;
  1320. }
  1321. if (i < remainderValue.Length - 1)
  1322. {
  1323. Array.Resize(ref remainderValue, i + 1);
  1324. }
  1325. return new BigInteger(dividend._sign, remainderValue);
  1326. }
  1327. /// <summary>
  1328. /// Negates a specified <see cref="BigInteger"/> value.
  1329. /// </summary>
  1330. /// <param name="value">The value to negate.</param>
  1331. /// <returns>
  1332. /// The result of the <paramref name="value"/> parameter multiplied by negative one (-1).
  1333. /// </returns>
  1334. public static BigInteger operator -(BigInteger value)
  1335. {
  1336. if (value._data is null)
  1337. {
  1338. return value;
  1339. }
  1340. return new BigInteger((short)-value._sign, value._data);
  1341. }
  1342. /// <summary>
  1343. /// Returns the value of the <see cref="BigInteger"/> operand.
  1344. /// </summary>
  1345. /// <param name="value">An integer value.</param>
  1346. /// <returns>
  1347. /// The value of the <paramref name="value"/> operand.
  1348. /// </returns>
  1349. /// <remarks>
  1350. /// The sign of the operand is unchanged.
  1351. /// </remarks>
  1352. #pragma warning disable CA2225 // Operator overloads have named alternates
  1353. public static BigInteger operator +(BigInteger value)
  1354. #pragma warning restore CA2225 // Operator overloads have named alternates
  1355. {
  1356. return value;
  1357. }
  1358. /// <summary>
  1359. /// Increments a <see cref="BigInteger"/> value by 1.
  1360. /// </summary>
  1361. /// <param name="value">The value to increment.</param>
  1362. /// <returns>
  1363. /// The value of the <paramref name="value"/> parameter incremented by 1.
  1364. /// </returns>
  1365. #pragma warning disable CA2225 // Operator overloads have named alternates
  1366. public static BigInteger operator ++(BigInteger value)
  1367. #pragma warning restore CA2225 // Operator overloads have named alternates
  1368. {
  1369. if (value._data is null)
  1370. {
  1371. return One;
  1372. }
  1373. var sign = value._sign;
  1374. var data = value._data;
  1375. if (data.Length == 1)
  1376. {
  1377. if (sign == -1 && data[0] == 1)
  1378. {
  1379. return Zero;
  1380. }
  1381. if (sign == 0)
  1382. {
  1383. return One;
  1384. }
  1385. }
  1386. data = sign == -1 ? CoreSub(data, 1) : CoreAdd(data, 1);
  1387. return new BigInteger(sign, data);
  1388. }
  1389. /// <summary>
  1390. /// Decrements a <see cref="BigInteger"/> value by 1.
  1391. /// </summary>
  1392. /// <param name="value">The value to decrement.</param>
  1393. /// <returns>
  1394. /// The value of the <paramref name="value"/> parameter decremented by 1.
  1395. /// </returns>
  1396. #pragma warning disable CA2225 // Operator overloads have named alternates
  1397. public static BigInteger operator --(BigInteger value)
  1398. #pragma warning restore CA2225 // Operator overloads have named alternates
  1399. {
  1400. if (value._data is null)
  1401. {
  1402. return MinusOne;
  1403. }
  1404. var sign = value._sign;
  1405. var data = value._data;
  1406. if (data.Length == 1)
  1407. {
  1408. if (sign == 1 && data[0] == 1)
  1409. {
  1410. return Zero;
  1411. }
  1412. if (sign == 0)
  1413. {
  1414. return MinusOne;
  1415. }
  1416. }
  1417. data = sign == -1 ? CoreAdd(data, 1) : CoreSub(data, 1);
  1418. return new BigInteger(sign, data);
  1419. }
  1420. /// <summary>
  1421. /// Performs a bitwise <c>And</c> operation on two <see cref="BigInteger"/> values.
  1422. /// </summary>
  1423. /// <param name="left">The first value.</param>
  1424. /// <param name="right">The second value.</param>
  1425. /// <returns>
  1426. /// The result of the bitwise <c>And</c> operation.
  1427. /// </returns>
  1428. #pragma warning disable CA2225 // Operator overloads have named alternates
  1429. public static BigInteger operator &(BigInteger left, BigInteger right)
  1430. #pragma warning restore CA2225 // Operator overloads have named alternates
  1431. {
  1432. if (left._sign == 0)
  1433. {
  1434. return left;
  1435. }
  1436. if (right._sign == 0)
  1437. {
  1438. return right;
  1439. }
  1440. var a = left._data;
  1441. var b = right._data;
  1442. int ls = left._sign;
  1443. int rs = right._sign;
  1444. var negRes = (ls == rs) && (ls == -1);
  1445. var result = new uint[Math.Max(a.Length, b.Length)];
  1446. ulong ac = 1, bc = 1, borrow = 1;
  1447. int i;
  1448. for (i = 0; i < result.Length; ++i)
  1449. {
  1450. uint va = 0;
  1451. if (i < a.Length)
  1452. {
  1453. va = a[i];
  1454. }
  1455. if (ls == -1)
  1456. {
  1457. ac = ~va + ac;
  1458. va = (uint)ac;
  1459. ac = (uint)(ac >> 32);
  1460. }
  1461. uint vb = 0;
  1462. if (i < b.Length)
  1463. {
  1464. vb = b[i];
  1465. }
  1466. if (rs == -1)
  1467. {
  1468. bc = ~vb + bc;
  1469. vb = (uint)bc;
  1470. bc = (uint)(bc >> 32);
  1471. }
  1472. var word = va & vb;
  1473. if (negRes)
  1474. {
  1475. borrow = word - borrow;
  1476. word = ~(uint)borrow;
  1477. borrow = (uint)(borrow >> 32) & 0x1u;
  1478. }
  1479. result[i] = word;
  1480. }
  1481. for (i = result.Length - 1; i >= 0 && result[i] == 0; --i)
  1482. {
  1483. // Intentionally empty block
  1484. }
  1485. if (i == -1)
  1486. {
  1487. return Zero;
  1488. }
  1489. if (i < result.Length - 1)
  1490. {
  1491. Array.Resize(ref result, i + 1);
  1492. }
  1493. return new BigInteger(negRes ? (short)-1 : (short)1, result);
  1494. }
  1495. /// <summary>
  1496. /// Performs a bitwise <c>Or</c> operation on two <see cref="BigInteger"/> values.
  1497. /// </summary>
  1498. /// <param name="left">The first value.</param>
  1499. /// <param name="right">The second value.</param>
  1500. /// <returns>
  1501. /// The result of the bitwise <c>Or</c> operation.
  1502. /// </returns>
  1503. #pragma warning disable CA2225 // Operator overloads have named alternates
  1504. public static BigInteger operator |(BigInteger left, BigInteger right)
  1505. #pragma warning restore CA2225 // Operator overloads have named alternates
  1506. {
  1507. if (left._sign == 0)
  1508. {
  1509. return right;
  1510. }
  1511. if (right._sign == 0)
  1512. {
  1513. return left;
  1514. }
  1515. var a = left._data;
  1516. var b = right._data;
  1517. int ls = left._sign;
  1518. int rs = right._sign;
  1519. var negRes = (ls == -1) || (rs == -1);
  1520. var result = new uint[Math.Max(a.Length, b.Length)];
  1521. ulong ac = 1, bc = 1, borrow = 1;
  1522. int i;
  1523. for (i = 0; i < result.Length; ++i)
  1524. {
  1525. uint va = 0;
  1526. if (i < a.Length)
  1527. {
  1528. va = a[i];
  1529. }
  1530. if (ls == -1)
  1531. {
  1532. ac = ~va + ac;
  1533. va = (uint)ac;
  1534. ac = (uint)(ac >> 32);
  1535. }
  1536. uint vb = 0;
  1537. if (i < b.Length)
  1538. {
  1539. vb = b[i];
  1540. }
  1541. if (rs == -1)
  1542. {
  1543. bc = ~vb + bc;
  1544. vb = (uint)bc;
  1545. bc = (uint)(bc >> 32);
  1546. }
  1547. var word = va | vb;
  1548. if (negRes)
  1549. {
  1550. borrow = word - borrow;
  1551. word = ~(uint)borrow;
  1552. borrow = (uint)(borrow >> 32) & 0x1u;
  1553. }
  1554. result[i] = word;
  1555. }
  1556. for (i = result.Length - 1; i >= 0 && result[i] == 0; --i)
  1557. {
  1558. // Intentionally empty block
  1559. }
  1560. if (i == -1)
  1561. {
  1562. return Zero;
  1563. }
  1564. if (i < result.Length - 1)
  1565. {
  1566. Array.Resize(ref result, i + 1);
  1567. }
  1568. return new BigInteger(negRes ? (short)-1 : (short)1, result);
  1569. }
  1570. /// <summary>
  1571. /// Performs a bitwise exclusive <c>Or</c> (<c>XOr</c>) operation on two <see cref="BigInteger"/> values.
  1572. /// </summary>
  1573. /// <param name="left">The first value.</param>
  1574. /// <param name="right">The second value.</param>
  1575. /// <returns>
  1576. /// The result of the bitwise <c>Or</c> operation.
  1577. /// </returns>
  1578. #pragma warning disable CA2225 // Operator overloads have named alternates
  1579. public static BigInteger operator ^(BigInteger left, BigInteger right)
  1580. #pragma warning restore CA2225 // Operator overloads have named alternates
  1581. {
  1582. if (left._sign == 0)
  1583. {
  1584. return right;
  1585. }
  1586. if (right._sign == 0)
  1587. {
  1588. return left;
  1589. }
  1590. var a = left._data;
  1591. var b = right._data;
  1592. int ls = left._sign;
  1593. int rs = right._sign;
  1594. var negRes = (ls == -1) ^ (rs == -1);
  1595. var result = new uint[Math.Max(a.Length, b.Length)];
  1596. ulong ac = 1, bc = 1, borrow = 1;
  1597. int i;
  1598. for (i = 0; i < result.Length; ++i)
  1599. {
  1600. uint va = 0;
  1601. if (i < a.Length)
  1602. {
  1603. va = a[i];
  1604. }
  1605. if (ls == -1)
  1606. {
  1607. ac = ~va + ac;
  1608. va = (uint)ac;
  1609. ac = (uint)(ac >> 32);
  1610. }
  1611. uint vb = 0;
  1612. if (i < b.Length)
  1613. {
  1614. vb = b[i];
  1615. }
  1616. if (rs == -1)
  1617. {
  1618. bc = ~vb + bc;
  1619. vb = (uint)bc;
  1620. bc = (uint)(bc >> 32);
  1621. }
  1622. var word = va ^ vb;
  1623. if (negRes)
  1624. {
  1625. borrow = word - borrow;
  1626. word = ~(uint)borrow;
  1627. borrow = (uint)(borrow >> 32) & 0x1u;
  1628. }
  1629. result[i] = word;
  1630. }
  1631. for (i = result.Length - 1; i >= 0 && result[i] == 0; --i)
  1632. {
  1633. // Intentionally empty block
  1634. }
  1635. if (i == -1)
  1636. {
  1637. return Zero;
  1638. }
  1639. if (i < result.Length - 1)
  1640. {
  1641. Array.Resize(ref result, i + 1);
  1642. }
  1643. return new BigInteger(negRes ? (short)-1 : (short)1, result);
  1644. }
  1645. /// <summary>
  1646. /// Returns the bitwise one's complement of a <see cref="BigInteger"/> value.
  1647. /// </summary>
  1648. /// <param name="value">An integer value.</param>
  1649. /// <returns>
  1650. /// The bitwise one's complement of <paramref name="value"/>.
  1651. /// </returns>
  1652. #pragma warning disable CA2225 // Operator overloads have named alternates
  1653. public static BigInteger operator ~(BigInteger value)
  1654. #pragma warning restore CA2225 // Operator overloads have named alternates
  1655. {
  1656. if (value._data is null)
  1657. {
  1658. return MinusOne;
  1659. }
  1660. var data = value._data;
  1661. int sign = value._sign;
  1662. var negRes = sign == 1;
  1663. var result = new uint[data.Length];
  1664. ulong carry = 1, borrow = 1;
  1665. int i;
  1666. for (i = 0; i < result.Length; ++i)
  1667. {
  1668. var word = data[i];
  1669. if (sign == -1)
  1670. {
  1671. carry = ~word + carry;
  1672. word = (uint)carry;
  1673. carry = (uint)(carry >> 32);
  1674. }
  1675. word = ~word;
  1676. if (negRes)
  1677. {
  1678. borrow = word - borrow;
  1679. word = ~(uint)borrow;
  1680. borrow = (uint)(borrow >> 32) & 0x1u;
  1681. }
  1682. result[i] = word;
  1683. }
  1684. for (i = result.Length - 1; i >= 0 && result[i] == 0; --i)
  1685. {
  1686. // Intentionally empty block
  1687. }
  1688. if (i == -1)
  1689. {
  1690. return Zero;
  1691. }
  1692. if (i < result.Length - 1)
  1693. {
  1694. Array.Resize(ref result, i + 1);
  1695. }
  1696. return new BigInteger(negRes ? (short)-1 : (short)1, result);
  1697. }
  1698. /// <summary>
  1699. /// Returns the zero-based index of the most significant set bit.
  1700. /// </summary>
  1701. /// <param name="word">The value to scan.</param>
  1702. /// <returns>
  1703. /// The zero-based index of the most significant set bit, or zero if no bit is set.
  1704. /// </returns>
  1705. private static int BitScanBackward(uint word)
  1706. {
  1707. for (var i = 31; i >= 0; --i)
  1708. {
  1709. var mask = 1u << i;
  1710. if ((word & mask) == mask)
  1711. {
  1712. return i;
  1713. }
  1714. }
  1715. return 0;
  1716. }
  1717. /// <summary>
  1718. /// Shifts a <see cref="BigInteger"/> value a specified number of bits to the left.
  1719. /// </summary>
  1720. /// <param name="value">The value whose bits are to be shifted.</param>
  1721. /// <param name="shift">The number of bits to shift value to the left.</param>
  1722. /// <returns>
  1723. /// A value that has been shifted to the left by the specified number of bits.
  1724. /// </returns>
  1725. #pragma warning disable CA2225 // Operator overloads have named alternates
  1726. public static BigInteger operator <<(BigInteger value, int shift)
  1727. #pragma warning restore CA2225 // Operator overloads have named alternates
  1728. {
  1729. if (shift == 0 || value._data is null)
  1730. {
  1731. return value;
  1732. }
  1733. if (shift < 0)
  1734. {
  1735. return value >> -shift;
  1736. }
  1737. var data = value._data;
  1738. int sign = value._sign;
  1739. var topMostIdx = BitScanBackward(data[data.Length - 1]);
  1740. var bits = shift - (31 - topMostIdx);
  1741. var extraWords = (bits >> 5) + ((bits & 0x1F) != 0 ? 1 : 0);
  1742. var res = new uint[data.Length + extraWords];
  1743. var idxShift = shift >> 5;
  1744. var bitShift = shift & 0x1F;
  1745. var carryShift = 32 - bitShift;
  1746. if (carryShift == 32)
  1747. {
  1748. for (var i = 0; i < data.Length; ++i)
  1749. {
  1750. var word = data[i];
  1751. res[i + idxShift] |= word << bitShift;
  1752. }
  1753. }
  1754. else
  1755. {
  1756. for (var i = 0; i < data.Length; ++i)
  1757. {
  1758. var word = data[i];
  1759. res[i + idxShift] |= word << bitShift;
  1760. if (i + idxShift + 1 < res.Length)
  1761. {
  1762. res[i + idxShift + 1] = word >> carryShift;
  1763. }
  1764. }
  1765. }
  1766. return new BigInteger((short)sign, res);
  1767. }
  1768. /// <summary>
  1769. /// Shifts a <see cref="BigInteger"/> value a specified number of bits to the right.
  1770. /// </summary>
  1771. /// <param name="value">The value whose bits are to be shifted.</param>
  1772. /// <param name="shift">The number of bits to shift value to the right.</param>
  1773. /// <returns>
  1774. /// A value that has been shifted to the right by the specified number of bits.
  1775. /// </returns>
  1776. #pragma warning disable CA2225 // Operator overloads have named alternates
  1777. public static BigInteger operator >>(BigInteger value, int shift)
  1778. #pragma warning restore CA2225 // Operator overloads have named alternates
  1779. {
  1780. if (shift == 0 || value._sign == 0)
  1781. {
  1782. return value;
  1783. }
  1784. if (shift < 0)
  1785. {
  1786. return value << -shift;
  1787. }
  1788. var data = value._data;
  1789. int sign = value._sign;
  1790. var topMostIdx = BitScanBackward(data[data.Length - 1]);
  1791. var idxShift = shift >> 5;
  1792. var bitShift = shift & 0x1F;
  1793. var extraWords = idxShift;
  1794. if (bitShift > topMostIdx)
  1795. {
  1796. ++extraWords;
  1797. }
  1798. var size = data.Length - extraWords;
  1799. if (size <= 0)
  1800. {
  1801. return sign == 1 ? Zero : MinusOne;
  1802. }
  1803. var res = new uint[size];
  1804. var carryShift = 32 - bitShift;
  1805. if (carryShift == 32)
  1806. {
  1807. for (var i = data.Length - 1; i >= idxShift; --i)
  1808. {
  1809. var word = data[i];
  1810. if (i - idxShift < res.Length)
  1811. {
  1812. res[i - idxShift] |= word >> bitShift;
  1813. }
  1814. }
  1815. }
  1816. else
  1817. {
  1818. for (var i = data.Length - 1; i >= idxShift; --i)
  1819. {
  1820. var word = data[i];
  1821. if (i - idxShift < res.Length)
  1822. {
  1823. res[i - idxShift] |= word >> bitShift;
  1824. }
  1825. if (i - idxShift - 1 >= 0)
  1826. {
  1827. res[i - idxShift - 1] = word << carryShift;
  1828. }
  1829. }
  1830. }
  1831. // Round down instead of toward zero
  1832. if (sign == -1)
  1833. {
  1834. for (var i = 0; i < idxShift; i++)
  1835. {
  1836. if (data[i] != 0u)
  1837. {
  1838. var tmp = new BigInteger((short)sign, res);
  1839. --tmp;
  1840. return tmp;
  1841. }
  1842. }
  1843. if (bitShift > 0 && (data[idxShift] << carryShift) != 0u)
  1844. {
  1845. var tmp = new BigInteger((short)sign, res);
  1846. --tmp;
  1847. return tmp;
  1848. }
  1849. }
  1850. return new BigInteger((short)sign, res);
  1851. }
  1852. /// <summary>
  1853. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is less than another
  1854. /// <see cref="BigInteger"/> value.
  1855. /// </summary>
  1856. /// <param name="left">The first value to compare.</param>
  1857. /// <param name="right">The second value to compare.</param>
  1858. /// <returns>
  1859. /// <see langword="true"/> if <paramref name="left"/> is less than <paramref name="right"/>; otherwise, <see langword="false"/>.
  1860. /// </returns>
  1861. public static bool operator <(BigInteger left, BigInteger right)
  1862. {
  1863. return Compare(left, right) < 0;
  1864. }
  1865. /// <summary>
  1866. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is less than a 64-bit signed integer.
  1867. /// </summary>
  1868. /// <param name="left">The first value to compare.</param>
  1869. /// <param name="right">The second value to compare.</param>
  1870. /// <returns>
  1871. /// <see langword="true"/> if left is <paramref name="left"/> than <paramref name="right"/>; otherwise, <see langword="false"/>.
  1872. /// </returns>
  1873. public static bool operator <(BigInteger left, long right)
  1874. {
  1875. return left.CompareTo(right) < 0;
  1876. }
  1877. /// <summary>
  1878. /// Returns a value that indicates whether a 64-bit signed integer is less than a <see cref="BigInteger"/> value.
  1879. /// </summary>
  1880. /// <param name="left">The first value to compare.</param>
  1881. /// <param name="right">The second value to compare.</param>
  1882. /// <returns>
  1883. /// <see langword="true"/> if <paramref name="left"/> is less than <paramref name="right"/>;
  1884. /// otherwise, <see langword="false"/>.
  1885. /// </returns>
  1886. public static bool operator <(long left, BigInteger right)
  1887. {
  1888. return right.CompareTo(left) > 0;
  1889. }
  1890. /// <summary>
  1891. /// Returns a value that indicates whether a 64-bit signed integer is less than a <see cref="BigInteger"/> value.
  1892. /// </summary>
  1893. /// <param name="left">The first value to compare.</param>
  1894. /// <param name="right">The second value to compare.</param>
  1895. /// <returns>
  1896. /// <see langword="true"/> if <paramref name="left"/> is less than <paramref name="right"/>; otherwise, <see langword="false"/>.
  1897. /// </returns>
  1898. [CLSCompliant(false)]
  1899. public static bool operator <(BigInteger left, ulong right)
  1900. {
  1901. return left.CompareTo(right) < 0;
  1902. }
  1903. /// <summary>
  1904. /// Returns a value that indicates whether a 64-bit unsigned integer is less than a <see cref="BigInteger"/> value.
  1905. /// </summary>
  1906. /// <param name="left">The first value to compare.</param>
  1907. /// <param name="right">The second value to compare.</param>
  1908. /// <returns>
  1909. /// <see langword="true"/> if <paramref name="left"/> is less than <paramref name="right"/>; otherwise, <see langword="false"/>.
  1910. /// </returns>
  1911. [CLSCompliant(false)]
  1912. public static bool operator <(ulong left, BigInteger right)
  1913. {
  1914. return right.CompareTo(left) > 0;
  1915. }
  1916. /// <summary>
  1917. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is less than or equal
  1918. /// to another <see cref="BigInteger"/> value.
  1919. /// </summary>
  1920. /// <param name="left">The first value to compare.</param>
  1921. /// <param name="right">The second value to compare.</param>
  1922. /// <returns>
  1923. /// <see langword="true"/> if <paramref name="left"/> is less than or equal to <paramref name="right"/>;
  1924. /// otherwise, <see langword="false"/>.
  1925. /// </returns>
  1926. public static bool operator <=(BigInteger left, BigInteger right)
  1927. {
  1928. return Compare(left, right) <= 0;
  1929. }
  1930. /// <summary>
  1931. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is less than or equal
  1932. /// to a 64-bit signed integer.
  1933. /// </summary>
  1934. /// <param name="left">The first value to compare.</param>
  1935. /// <param name="right">The second value to compare.</param>
  1936. /// <returns>
  1937. /// <see langword="true"/> if <paramref name="left"/> is less than or equal to <paramref name="right"/>;
  1938. /// otherwise, <see langword="false"/>.
  1939. /// </returns>
  1940. public static bool operator <=(BigInteger left, long right)
  1941. {
  1942. return left.CompareTo(right) <= 0;
  1943. }
  1944. /// <summary>
  1945. /// Returns a value that indicates whether a 64-bit signed integer is less than or equal to a <see cref="BigInteger"/> value.
  1946. /// </summary>
  1947. /// <param name="left">The first value to compare.</param>
  1948. /// <param name="right">The second value to compare.</param>
  1949. /// <returns>
  1950. /// <see langword="true"/> if <paramref name="left"/> is less than or equal to <paramref name="right"/>;
  1951. /// otherwise, <see langword="false"/>.
  1952. /// </returns>
  1953. public static bool operator <=(long left, BigInteger right)
  1954. {
  1955. return right.CompareTo(left) >= 0;
  1956. }
  1957. /// <summary>
  1958. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is less than or equal to
  1959. /// a 64-bit unsigned integer.
  1960. /// </summary>
  1961. /// <param name="left">The first value to compare.</param>
  1962. /// <param name="right">The second value to compare.</param>
  1963. /// <returns>
  1964. /// <see langword="true"/> if <paramref name="left"/> is less than or equal to <paramref name="right"/>;
  1965. /// otherwise, <see langword="false"/>.
  1966. /// </returns>
  1967. [CLSCompliant(false)]
  1968. public static bool operator <=(BigInteger left, ulong right)
  1969. {
  1970. return left.CompareTo(right) <= 0;
  1971. }
  1972. /// <summary>
  1973. /// Returns a value that indicates whether a 64-bit unsigned integer is less than or equal to a
  1974. /// <see cref="BigInteger"/> value.
  1975. /// </summary>
  1976. /// <param name="left">The first value to compare.</param>
  1977. /// <param name="right">The second value to compare.</param>
  1978. /// <returns>
  1979. /// <see langword="true"/> if <paramref name="left"/> is less than or equal to <paramref name="right"/>;
  1980. /// otherwise, <see langword="false"/>.
  1981. /// </returns>
  1982. [CLSCompliant(false)]
  1983. public static bool operator <=(ulong left, BigInteger right)
  1984. {
  1985. return right.CompareTo(left) >= 0;
  1986. }
  1987. /// <summary>
  1988. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is greater than another
  1989. /// <see cref="BigInteger"/> value.
  1990. /// </summary>
  1991. /// <param name="left">The first value to compare.</param>
  1992. /// <param name="right">The second value to compare.</param>
  1993. /// <returns>
  1994. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  1995. /// otherwise, <see langword="false"/>.
  1996. /// </returns>
  1997. public static bool operator >(BigInteger left, BigInteger right)
  1998. {
  1999. return Compare(left, right) > 0;
  2000. }
  2001. /// <summary>
  2002. /// Returns a value that indicates whether a <see cref="BigInteger"/> is greater than a 64-bit signed integer value.
  2003. /// </summary>
  2004. /// <param name="left">The first value to compare.</param>
  2005. /// <param name="right">The second value to compare.</param>
  2006. /// <returns>
  2007. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2008. /// otherwise, <see langword="false"/>.
  2009. /// </returns>
  2010. public static bool operator >(BigInteger left, long right)
  2011. {
  2012. return left.CompareTo(right) > 0;
  2013. }
  2014. /// <summary>
  2015. /// Returns a value that indicates whether a 64-bit signed integer is greater than a <see cref="BigInteger"/> value.
  2016. /// </summary>
  2017. /// <param name="left">The first value to compare.</param>
  2018. /// <param name="right">The second value to compare.</param>
  2019. /// <returns>
  2020. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2021. /// otherwise, <see langword="false"/>.
  2022. /// </returns>
  2023. public static bool operator >(long left, BigInteger right)
  2024. {
  2025. return right.CompareTo(left) < 0;
  2026. }
  2027. /// <summary>
  2028. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is greater than a 64-bit unsigned integer.
  2029. /// </summary>
  2030. /// <param name="left">The first value to compare.</param>
  2031. /// <param name="right">The second value to compare.</param>
  2032. /// <returns>
  2033. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2034. /// otherwise, <see langword="false"/>.
  2035. /// </returns>
  2036. [CLSCompliant(false)]
  2037. public static bool operator >(BigInteger left, ulong right)
  2038. {
  2039. return left.CompareTo(right) > 0;
  2040. }
  2041. /// <summary>
  2042. /// Returns a value that indicates whether a 64-bit unsigned integer is greater than a <see cref="BigInteger"/> value.
  2043. /// </summary>
  2044. /// <param name="left">The first value to compare.</param>
  2045. /// <param name="right">The second value to compare.</param>
  2046. /// <returns>
  2047. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2048. /// otherwise, <see langword="false"/>.
  2049. /// </returns>
  2050. [CLSCompliant(false)]
  2051. public static bool operator >(ulong left, BigInteger right)
  2052. {
  2053. return right.CompareTo(left) < 0;
  2054. }
  2055. /// <summary>
  2056. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is greater than or equal
  2057. /// to another <see cref="BigInteger"/> value.
  2058. /// </summary>
  2059. /// <param name="left">The first value to compare.</param>
  2060. /// <param name="right">The second value to compare.</param>
  2061. /// <returns>
  2062. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2063. /// otherwise, <see langword="false"/>.
  2064. /// </returns>
  2065. public static bool operator >=(BigInteger left, BigInteger right)
  2066. {
  2067. return Compare(left, right) >= 0;
  2068. }
  2069. /// <summary>
  2070. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is greater than or equal
  2071. /// to a 64-bit signed integer value.
  2072. /// </summary>
  2073. /// <param name="left">The first value to compare.</param>
  2074. /// <param name="right">The second value to compare.</param>
  2075. /// <returns>
  2076. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2077. /// otherwise, <see langword="false"/>.
  2078. /// </returns>
  2079. public static bool operator >=(BigInteger left, long right)
  2080. {
  2081. return left.CompareTo(right) >= 0;
  2082. }
  2083. /// <summary>
  2084. /// Returns a value that indicates whether a 64-bit signed integer is greater than or equal to a
  2085. /// <see cref="BigInteger"/> value.
  2086. /// </summary>
  2087. /// <param name="left">The first value to compare.</param>
  2088. /// <param name="right">The second value to compare.</param>
  2089. /// <returns>
  2090. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2091. /// otherwise, <see langword="false"/>.
  2092. /// </returns>
  2093. public static bool operator >=(long left, BigInteger right)
  2094. {
  2095. return right.CompareTo(left) <= 0;
  2096. }
  2097. /// <summary>
  2098. /// Returns a value that indicates whether a <see cref="BigInteger"/> value is greater than or equal to a
  2099. /// 64-bit unsigned integer value.
  2100. /// </summary>
  2101. /// <param name="left">The first value to compare.</param>
  2102. /// <param name="right">The second value to compare.</param>
  2103. /// <returns>
  2104. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2105. /// otherwise, <see langword="false"/>.
  2106. /// </returns>
  2107. [CLSCompliant(false)]
  2108. public static bool operator >=(BigInteger left, ulong right)
  2109. {
  2110. return left.CompareTo(right) >= 0;
  2111. }
  2112. /// <summary>
  2113. /// Returns a value that indicates whether a 64-bit unsigned integer is greater than or equal to a
  2114. /// <see cref="BigInteger"/> value.
  2115. /// </summary>
  2116. /// <param name="left">The first value to compare.</param>
  2117. /// <param name="right">The second value to compare.</param>
  2118. /// <returns>
  2119. /// <see langword="true"/> if <paramref name="left"/> is greater than <paramref name="right"/>;
  2120. /// otherwise, <see langword="false"/>.
  2121. /// </returns>
  2122. [CLSCompliant(false)]
  2123. public static bool operator >=(ulong left, BigInteger right)
  2124. {
  2125. return right.CompareTo(left) <= 0;
  2126. }
  2127. /// <summary>
  2128. /// Returns a value that indicates whether the values of two <see cref="BigInteger"/> objects are equal.
  2129. /// </summary>
  2130. /// <param name="left">The first value to compare.</param>
  2131. /// <param name="right">The second value to compare.</param>
  2132. /// <returns>
  2133. /// <see langword="true"/> if the <paramref name="left"/> and <paramref name="right"/> parameters have the same value;
  2134. /// otherwise, <see langword="false"/>.
  2135. /// </returns>
  2136. public static bool operator ==(BigInteger left, BigInteger right)
  2137. {
  2138. return Compare(left, right) == 0;
  2139. }
  2140. /// <summary>
  2141. /// Returns a value that indicates whether a <see cref="BigInteger"/> value and a signed long integer value are equal.
  2142. /// </summary>
  2143. /// <param name="left">The first value to compare.</param>
  2144. /// <param name="right">The second value to compare.</param>
  2145. /// <returns>
  2146. /// <see langword="true"/> if the <paramref name="left"/> and <paramref name="right"/> parameters have the same value;
  2147. /// otherwise, <see langword="false"/>.
  2148. /// </returns>
  2149. public static bool operator ==(BigInteger left, long right)
  2150. {
  2151. return left.CompareTo(right) == 0;
  2152. }
  2153. /// <summary>
  2154. /// Returns a value that indicates whether a signed long integer value and a <see cref="BigInteger"/> value are equal.
  2155. /// </summary>
  2156. /// <param name="left">The first value to compare.</param>
  2157. /// <param name="right">The second value to compare.</param>
  2158. /// <returns>
  2159. /// <see langword="true"/> if the <paramref name="left"/> and <paramref name="right"/> parameters have the same value;
  2160. /// otherwise, <see langword="false"/>.
  2161. /// </returns>
  2162. public static bool operator ==(long left, BigInteger right)
  2163. {
  2164. return right.CompareTo(left) == 0;
  2165. }
  2166. /// <summary>
  2167. /// Returns a value that indicates whether a <see cref="BigInteger"/> value and an unsigned long integer value are equal.
  2168. /// </summary>
  2169. /// <param name="left">The first value to compare.</param>
  2170. /// <param name="right">The second value to compare.</param>
  2171. /// <returns>
  2172. /// <see langword="true"/> if the <paramref name="left"/> and <paramref name="right"/> parameters have the same value;
  2173. /// otherwise, <see langword="false"/>.
  2174. /// </returns>
  2175. [CLSCompliant(false)]
  2176. public static bool operator ==(BigInteger left, ulong right)
  2177. {
  2178. return left.CompareTo(right) == 0;
  2179. }
  2180. /// <summary>
  2181. /// Returns a value that indicates whether an unsigned long integer value and a <see cref="BigInteger"/> value are equal.
  2182. /// </summary>
  2183. /// <param name="left">The first value to compare.</param>
  2184. /// <param name="right">The second value to compare.</param>
  2185. /// <returns>
  2186. /// <see langword="true"/> if the <paramref name="left"/> and <paramref name="right"/> parameters have the same value;
  2187. /// otherwise, <see langword="false"/>.
  2188. /// </returns>
  2189. [CLSCompliant(false)]
  2190. public static bool operator ==(ulong left, BigInteger right)
  2191. {
  2192. return right.CompareTo(left) == 0;
  2193. }
  2194. /// <summary>
  2195. /// Returns a value that indicates whether two <see cref="BigInteger"/> objects have different values.
  2196. /// </summary>
  2197. /// <param name="left">The first value to compare.</param>
  2198. /// <param name="right">The second value to compare.</param>
  2199. /// <returns>
  2200. /// <see langword="true"/> if <paramref name="left"/> and <paramref name="right"/> are not equal;
  2201. /// otherwise, <see langword="false"/>.
  2202. /// </returns>
  2203. public static bool operator !=(BigInteger left, BigInteger right)
  2204. {
  2205. return Compare(left, right) != 0;
  2206. }
  2207. /// <summary>
  2208. /// Returns a value that indicates whether a <see cref="BigInteger"/> value and a 64-bit signed integer are not equal.
  2209. /// </summary>
  2210. /// <param name="left">The first value to compare.</param>
  2211. /// <param name="right">The second value to compare.</param>
  2212. /// <returns>
  2213. /// <see langword="true"/> if <paramref name="left"/> and <paramref name="right"/> are not equal;
  2214. /// otherwise, <see langword="false"/>.
  2215. /// </returns>
  2216. public static bool operator !=(BigInteger left, long right)
  2217. {
  2218. return left.CompareTo(right) != 0;
  2219. }
  2220. /// <summary>
  2221. /// Returns a value that indicates whether a 64-bit signed integer and a <see cref="BigInteger"/> value are not equal.
  2222. /// </summary>
  2223. /// <param name="left">The first value to compare.</param>
  2224. /// <param name="right">The second value to compare.</param>
  2225. /// <returns>
  2226. /// <see langword="true"/> if <paramref name="left"/> and <paramref name="right"/> are not equal;
  2227. /// otherwise, <see langword="false"/>.
  2228. /// </returns>
  2229. public static bool operator !=(long left, BigInteger right)
  2230. {
  2231. return right.CompareTo(left) != 0;
  2232. }
  2233. /// <summary>
  2234. /// Returns a value that indicates whether a <see cref="BigInteger"/> value and a 64-bit unsigned integer are not equal.
  2235. /// </summary>
  2236. /// <param name="left">The first value to compare.</param>
  2237. /// <param name="right">The second value to compare.</param>
  2238. /// <returns>
  2239. /// <see langword="true"/> if <paramref name="left"/> and <paramref name="right"/> are not equal;
  2240. /// otherwise, <see langword="false"/>.
  2241. /// </returns>
  2242. [CLSCompliant(false)]
  2243. public static bool operator !=(BigInteger left, ulong right)
  2244. {
  2245. return left.CompareTo(right) != 0;
  2246. }
  2247. /// <summary>
  2248. /// Returns a value that indicates whether a 64-bit unsigned integer and a <see cref="BigInteger"/> value are not equal.
  2249. /// </summary>
  2250. /// <param name="left">The first value to compare.</param>
  2251. /// <param name="right">The second value to compare.</param>
  2252. /// <returns>
  2253. /// <see langword="true"/> if <paramref name="left"/> and <paramref name="right"/> are not equal;
  2254. /// otherwise, <see langword="false"/>.
  2255. /// </returns>
  2256. [CLSCompliant(false)]
  2257. public static bool operator !=(ulong left, BigInteger right)
  2258. {
  2259. return right.CompareTo(left) != 0;
  2260. }
  2261. /// <summary>
  2262. /// Returns a value that indicates whether the current instance and a specified object have the same value.
  2263. /// </summary>
  2264. /// <param name="obj">The object to compare.</param>
  2265. /// <returns>
  2266. /// <see langword="true"/> if the <paramref name="obj"/> parameter is a <see cref="BigInteger"/> object or a type capable
  2267. /// of implicit conversion to a <see cref="BigInteger"/> value, and its value is equal to the value of the
  2268. /// current <see cref="BigInteger"/> object; otherwise, <see langword="false"/>.
  2269. /// </returns>
  2270. public override readonly bool Equals(object obj)
  2271. {
  2272. if (obj is not BigInteger other)
  2273. {
  2274. return false;
  2275. }
  2276. return Equals(other);
  2277. }
  2278. /// <summary>
  2279. /// Returns a value that indicates whether the current instance and a specified <see cref="BigInteger"/> object
  2280. /// have the same value.
  2281. /// </summary>
  2282. /// <param name="other">The object to compare.</param>
  2283. /// <returns>
  2284. /// <see langword="true"/> if this <see cref="BigInteger"/> object and <paramref name="other"/> have the same value;
  2285. /// otherwise, <see langword="false"/>.
  2286. /// </returns>
  2287. public readonly bool Equals(BigInteger other)
  2288. {
  2289. if (_sign != other._sign)
  2290. {
  2291. return false;
  2292. }
  2293. var alen = _data != null ? _data.Length : 0;
  2294. var blen = other._data != null ? other._data.Length : 0;
  2295. if (alen != blen)
  2296. {
  2297. return false;
  2298. }
  2299. for (var i = 0; i < alen; ++i)
  2300. {
  2301. if (_data[i] != other._data[i])
  2302. {
  2303. return false;
  2304. }
  2305. }
  2306. return true;
  2307. }
  2308. /// <summary>
  2309. /// Returns a value that indicates whether the current instance and a signed 64-bit integer have the same value.
  2310. /// </summary>
  2311. /// <param name="other">The signed 64-bit integer value to compare.</param>
  2312. /// <returns>
  2313. /// <see langword="true"/> if the signed 64-bit integer and the current instance have the same value; otherwise, <see langword="false"/>.
  2314. /// </returns>
  2315. public readonly bool Equals(long other)
  2316. {
  2317. return CompareTo(other) == 0;
  2318. }
  2319. /// <summary>
  2320. /// Returns a value that indicates whether the current instance and an unsigned 64-bit integer have the same value.
  2321. /// </summary>
  2322. /// <param name="other">The unsigned 64-bit integer to compare.</param>
  2323. /// <returns>
  2324. /// <see langword="true"/> if the current instance and the unsigned 64-bit integer have the same value; otherwise, <see langword="false"/>.
  2325. /// </returns>
  2326. [CLSCompliant(false)]
  2327. public readonly bool Equals(ulong other)
  2328. {
  2329. return CompareTo(other) == 0;
  2330. }
  2331. /// <summary>
  2332. /// Converts the numeric value of the current <see cref="BigInteger"/> object to its equivalent string representation.
  2333. /// </summary>
  2334. /// <returns>
  2335. /// The string representation of the current <see cref="BigInteger"/> value.
  2336. /// </returns>
  2337. public override readonly string ToString()
  2338. {
  2339. return ToString(10, provider: null);
  2340. }
  2341. /// <summary>
  2342. /// Converts the numeric value of the current <see cref="BigInteger"/> object to its equivalent string representation
  2343. /// by using the specified format.
  2344. /// </summary>
  2345. /// <param name="format">A standard or custom numeric format string.</param>
  2346. /// <returns>
  2347. /// The string representation of the current <see cref="BigInteger"/> value in the format specified by the
  2348. /// <paramref name="format"/> parameter.
  2349. /// </returns>
  2350. /// <exception cref="FormatException"><paramref name="format"/> is not a valid format string.</exception>
  2351. public readonly string ToString(string format)
  2352. {
  2353. return ToString(format, formatProvider: null);
  2354. }
  2355. /// <summary>
  2356. /// Converts the numeric value of the current <see cref="BigInteger"/> object to its equivalent string representation
  2357. /// by using the specified culture-specific formatting information.
  2358. /// </summary>
  2359. /// <param name="provider">An object that supplies culture-specific formatting information.</param>
  2360. /// <returns>
  2361. /// The string representation of the current <see cref="BigInteger"/> value in the format specified by the
  2362. /// <paramref name="provider"/> parameter.
  2363. /// </returns>
  2364. public readonly string ToString(IFormatProvider provider)
  2365. {
  2366. return ToString(format: null, provider);
  2367. }
  2368. /// <summary>
  2369. /// Converts the numeric value of the current <see cref="BigInteger"/> object to its equivalent string representation
  2370. /// by using the specified format and culture-specific format information.
  2371. /// </summary>
  2372. /// <param name="format">A standard or custom numeric format string.</param>
  2373. /// <param name="formatProvider">An object that supplies culture-specific formatting information.</param>
  2374. /// <returns>
  2375. /// The string representation of the current <see cref="BigInteger"/> value as specified by the <paramref name="format"/>
  2376. /// and <paramref name="formatProvider"/> parameters.
  2377. /// </returns>
  2378. public readonly string ToString(string format, IFormatProvider formatProvider)
  2379. {
  2380. if (string.IsNullOrEmpty(format))
  2381. {
  2382. return ToString(10, formatProvider);
  2383. }
  2384. switch (format[0])
  2385. {
  2386. case 'd':
  2387. case 'D':
  2388. case 'g':
  2389. case 'G':
  2390. case 'r':
  2391. case 'R':
  2392. return ToStringWithPadding(format, 10, formatProvider);
  2393. case 'x':
  2394. case 'X':
  2395. return ToStringWithPadding(format, 16, provider: null);
  2396. default:
  2397. throw new FormatException(string.Format("format '{0}' not implemented", format));
  2398. }
  2399. }
  2400. private readonly string ToStringWithPadding(string format, uint radix, IFormatProvider provider)
  2401. {
  2402. if (format.Length > 1)
  2403. {
  2404. var precision = Convert.ToInt32(format.Substring(1), CultureInfo.InvariantCulture.NumberFormat);
  2405. var baseStr = ToString(radix, provider);
  2406. if (baseStr.Length < precision)
  2407. {
  2408. var additional = new string('0', precision - baseStr.Length);
  2409. if (baseStr[0] != '-')
  2410. {
  2411. return additional + baseStr;
  2412. }
  2413. #if NET
  2414. return string.Concat("-", additional, baseStr.AsSpan(1));
  2415. #else
  2416. return "-" + additional + baseStr.Substring(1);
  2417. #endif // NET
  2418. }
  2419. return baseStr;
  2420. }
  2421. return ToString(radix, provider);
  2422. }
  2423. private static uint[] MakeTwoComplement(uint[] v)
  2424. {
  2425. var res = new uint[v.Length];
  2426. ulong carry = 1;
  2427. for (var i = 0; i < v.Length; ++i)
  2428. {
  2429. var word = v[i];
  2430. carry = (ulong)~word + carry;
  2431. word = (uint)carry;
  2432. carry = (uint)(carry >> 32);
  2433. res[i] = word;
  2434. }
  2435. var last = res[res.Length - 1];
  2436. var idx = FirstNonFfByte(last);
  2437. uint mask = 0xFF;
  2438. for (var i = 1; i < idx; ++i)
  2439. {
  2440. mask = (mask << 8) | 0xFF;
  2441. }
  2442. res[res.Length - 1] = last & mask;
  2443. return res;
  2444. }
  2445. private readonly string ToString(uint radix, IFormatProvider provider)
  2446. {
  2447. const string characterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  2448. if (characterSet.Length < radix)
  2449. {
  2450. throw new ArgumentException("charSet length less than radix", nameof(radix));
  2451. }
  2452. if (radix == 1)
  2453. {
  2454. throw new ArgumentException("There is no such thing as radix one notation", nameof(radix));
  2455. }
  2456. if (_sign == 0)
  2457. {
  2458. return "0";
  2459. }
  2460. if (_data.Length == 1 && _data[0] == 1)
  2461. {
  2462. return _sign == 1 ? "1" : "-1";
  2463. }
  2464. var digits = new List<char>(1 + ((_data.Length * 3) / 10));
  2465. BigInteger a;
  2466. if (_sign == 1)
  2467. {
  2468. a = this;
  2469. }
  2470. else
  2471. {
  2472. var dt = _data;
  2473. if (radix > 10)
  2474. {
  2475. dt = MakeTwoComplement(dt);
  2476. }
  2477. a = new BigInteger(1, dt);
  2478. }
  2479. while (a != 0)
  2480. {
  2481. a = DivRem(a, radix, out var rem);
  2482. digits.Add(characterSet[(int)rem]);
  2483. }
  2484. if (_sign == -1 && radix == 10)
  2485. {
  2486. NumberFormatInfo info = null;
  2487. if (provider != null)
  2488. {
  2489. info = provider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
  2490. }
  2491. if (info != null)
  2492. {
  2493. var str = info.NegativeSign;
  2494. for (var i = str.Length - 1; i >= 0; --i)
  2495. {
  2496. digits.Add(str[i]);
  2497. }
  2498. }
  2499. else
  2500. {
  2501. digits.Add('-');
  2502. }
  2503. }
  2504. var last = digits[digits.Count - 1];
  2505. if (_sign == 1 && radix > 10 && (last < '0' || last > '9'))
  2506. {
  2507. digits.Add('0');
  2508. }
  2509. digits.Reverse();
  2510. return new string(digits.ToArray());
  2511. }
  2512. /// <summary>
  2513. /// Converts the string representation of a number to its <see cref="BigInteger"/> equivalent.
  2514. /// </summary>
  2515. /// <param name="value">A string that contains the number to convert.</param>
  2516. /// <returns>
  2517. /// A value that is equivalent to the number specified in the <paramref name="value"/> parameter.
  2518. /// </returns>
  2519. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  2520. /// <exception cref="FormatException"><paramref name="value"/> is not in the correct format.</exception>
  2521. public static BigInteger Parse(string value)
  2522. {
  2523. if (!Parse(value, tryParse: false, out var result, out var ex))
  2524. {
  2525. throw ex;
  2526. }
  2527. return result;
  2528. }
  2529. /// <summary>
  2530. /// Converts the string representation of a number in a specified style to its <see cref="BigInteger"/> equivalent.
  2531. /// </summary>
  2532. /// <param name="value">A string that contains a number to convert.</param>
  2533. /// <param name="style">A bitwise combination of the enumeration values that specify the permitted format of <paramref name="value"/>.</param>
  2534. /// <returns>
  2535. /// A value that is equivalent to the number specified in the <paramref name="value"/> parameter.
  2536. /// </returns>
  2537. /// <exception cref="ArgumentException">
  2538. /// <para><paramref name="style"/> is not a <see cref="NumberStyles"/> value.</para>
  2539. /// <para>-or-</para>
  2540. /// <para><paramref name="style"/> includes the <see cref="NumberStyles.AllowHexSpecifier"/> or <see cref="NumberStyles.HexNumber"/> flag along with another value.</para>
  2541. /// </exception>
  2542. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  2543. /// <exception cref="FormatException"><paramref name="value"/> does not comply with the input pattern specified by <see cref="NumberStyles"/>.</exception>
  2544. public static BigInteger Parse(string value, NumberStyles style)
  2545. {
  2546. return Parse(value, style, provider: null);
  2547. }
  2548. /// <summary>
  2549. /// Converts the string representation of a number in a specified style to its <see cref="BigInteger"/> equivalent.
  2550. /// </summary>
  2551. /// <param name="value">A string that contains a number to convert.</param>
  2552. /// <param name="provider">An object that provides culture-specific formatting information about <paramref name="value"/>.</param>
  2553. /// <returns>
  2554. /// A value that is equivalent to the number specified in the <paramref name="value"/> parameter.
  2555. /// </returns>
  2556. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  2557. /// <exception cref="FormatException"><paramref name="value"/> is not in the correct format.</exception>
  2558. public static BigInteger Parse(string value, IFormatProvider provider)
  2559. {
  2560. return Parse(value, NumberStyles.Integer, provider);
  2561. }
  2562. /// <summary>
  2563. /// Converts the string representation of a number in a specified style and culture-specific format to its <see cref="BigInteger"/> equivalent.
  2564. /// </summary>
  2565. /// <param name="value">A string that contains a number to convert.</param>
  2566. /// <param name="style">A bitwise combination of the enumeration values that specify the permitted format of <paramref name="value"/>.</param>
  2567. /// <param name="provider">An object that provides culture-specific formatting information about <paramref name="value"/>.</param>
  2568. /// <returns>
  2569. /// A value that is equivalent to the number specified in the <paramref name="value"/> parameter.
  2570. /// </returns>
  2571. /// <exception cref="ArgumentException">
  2572. /// <para><paramref name="style"/> is not a <see cref="NumberStyles"/> value.</para>
  2573. /// <para>-or-</para>
  2574. /// <para><paramref name="style"/> includes the <see cref="NumberStyles.AllowHexSpecifier"/> or <see cref="NumberStyles.HexNumber"/> flag along with another value.</para>
  2575. /// </exception>
  2576. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  2577. /// <exception cref="FormatException"><paramref name="value"/> does not comply with the input pattern specified by <see cref="NumberStyles"/>.</exception>
  2578. public static BigInteger Parse(string value, NumberStyles style, IFormatProvider provider)
  2579. {
  2580. if (!Parse(value, style, provider, tryParse: false, out var res, out var exc))
  2581. {
  2582. throw exc;
  2583. }
  2584. return res;
  2585. }
  2586. /// <summary>
  2587. /// Tries to convert the string representation of a number to its <see cref="BigInteger"/> equivalent, and
  2588. /// returns a value that indicates whether the conversion succeeded.
  2589. /// </summary>
  2590. /// <param name="value">The string representation of a number.</param>
  2591. /// <param name="result">When this method returns, contains the <see cref="BigInteger"/> equivalent to the number that is contained in value, or zero (0) if the conversion fails. The conversion fails if the <paramref name="value"/> parameter is <see langword="null"/> or is not of the correct format. This parameter is passed uninitialized.</param>
  2592. /// <returns>
  2593. /// <see langword="true"/> if <paramref name="value"/> was converted successfully; otherwise, <see langword="false"/>.
  2594. /// </returns>
  2595. /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
  2596. public static bool TryParse(string value, out BigInteger result)
  2597. {
  2598. return Parse(value, tryParse: true, out result, out _);
  2599. }
  2600. /// <summary>
  2601. /// Tries to convert the string representation of a number in a specified style and culture-specific format to its
  2602. /// <see cref="BigInteger"/> equivalent, and returns a value that indicates whether the conversion succeeded.
  2603. /// </summary>
  2604. /// <param name="value">The string representation of a number.</param>
  2605. /// <param name="style">A bitwise combination of enumeration values that indicates the style elements that can be present in <paramref name="value"/>.</param>
  2606. /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="value"/>.</param>
  2607. /// <param name="result">When this method returns, contains the <see cref="BigInteger"/> equivalent to the number that is contained in value, or <see cref="Zero"/> if the conversion fails. The conversion fails if the <paramref name="value"/> parameter is <see langword="null"/> or is not of the correct format. This parameter is passed uninitialized.</param>
  2608. /// <returns>
  2609. /// <see langword="true"/> if <paramref name="value"/> was converted successfully; otherwise, <see langword="false"/>.
  2610. /// </returns>
  2611. /// <exception cref="ArgumentException">
  2612. /// <para><paramref name="style"/> is not a <see cref="NumberStyles"/> value.</para>
  2613. /// <para>-or-</para>
  2614. /// <para><paramref name="style"/> includes the <see cref="NumberStyles.AllowHexSpecifier"/> or <see cref="NumberStyles.HexNumber"/> flag along with another value.</para>
  2615. /// </exception>
  2616. public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out BigInteger result)
  2617. {
  2618. if (!Parse(value, style, provider, tryParse: true, out result, out _))
  2619. {
  2620. result = Zero;
  2621. return false;
  2622. }
  2623. return true;
  2624. }
  2625. #pragma warning disable S4136 // Method overloads should be grouped together
  2626. private static bool Parse(string value, NumberStyles style, IFormatProvider fp, bool tryParse, out BigInteger result, out Exception exc)
  2627. #pragma warning restore S4136 // Method overloads should be grouped together
  2628. {
  2629. result = Zero;
  2630. exc = null;
  2631. if (value is null)
  2632. {
  2633. if (!tryParse)
  2634. {
  2635. exc = new ArgumentNullException(nameof(value));
  2636. }
  2637. return false;
  2638. }
  2639. if (value.Length == 0)
  2640. {
  2641. if (!tryParse)
  2642. {
  2643. exc = GetFormatException();
  2644. }
  2645. return false;
  2646. }
  2647. NumberFormatInfo nfi = null;
  2648. if (fp != null)
  2649. {
  2650. var typeNfi = typeof(NumberFormatInfo);
  2651. nfi = (NumberFormatInfo)fp.GetFormat(typeNfi);
  2652. }
  2653. nfi ??= NumberFormatInfo.CurrentInfo;
  2654. if (!CheckStyle(style, tryParse, ref exc))
  2655. {
  2656. return false;
  2657. }
  2658. var allowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) == NumberStyles.AllowCurrencySymbol;
  2659. var allowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) == NumberStyles.AllowHexSpecifier;
  2660. var allowThousands = (style & NumberStyles.AllowThousands) == NumberStyles.AllowThousands;
  2661. var allowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) == NumberStyles.AllowDecimalPoint;
  2662. var allowParentheses = (style & NumberStyles.AllowParentheses) == NumberStyles.AllowParentheses;
  2663. var allowTrailingSign = (style & NumberStyles.AllowTrailingSign) == NumberStyles.AllowTrailingSign;
  2664. var allowLeadingSign = (style & NumberStyles.AllowLeadingSign) == NumberStyles.AllowLeadingSign;
  2665. var allowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) == NumberStyles.AllowTrailingWhite;
  2666. var allowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) == NumberStyles.AllowLeadingWhite;
  2667. var allowExponent = (style & NumberStyles.AllowExponent) == NumberStyles.AllowExponent;
  2668. var pos = 0;
  2669. if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2670. {
  2671. return false;
  2672. }
  2673. var foundOpenParentheses = false;
  2674. var negative = false;
  2675. var foundSign = false;
  2676. var foundCurrency = false;
  2677. // Pre-number stuff
  2678. if (allowParentheses && value[pos] == '(')
  2679. {
  2680. foundOpenParentheses = true;
  2681. foundSign = true;
  2682. negative = true; // MS always make the number negative when there parentheses, even when NumberFormatInfo.NumberNegativePattern != 0
  2683. pos++;
  2684. if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2685. {
  2686. return false;
  2687. }
  2688. if (value.Substring(pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
  2689. {
  2690. if (!tryParse)
  2691. {
  2692. exc = GetFormatException();
  2693. }
  2694. return false;
  2695. }
  2696. if (value.Substring(pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
  2697. {
  2698. if (!tryParse)
  2699. {
  2700. exc = GetFormatException();
  2701. }
  2702. return false;
  2703. }
  2704. }
  2705. if (allowLeadingSign && !foundSign)
  2706. {
  2707. // Sign + Currency
  2708. FindSign(ref pos, value, nfi, ref foundSign, ref negative);
  2709. if (foundSign)
  2710. {
  2711. if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2712. {
  2713. return false;
  2714. }
  2715. if (allowCurrencySymbol)
  2716. {
  2717. FindCurrency(ref pos, value, nfi, ref foundCurrency);
  2718. if (foundCurrency && allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2719. {
  2720. return false;
  2721. }
  2722. }
  2723. }
  2724. }
  2725. if (allowCurrencySymbol && !foundCurrency)
  2726. {
  2727. // Currency + sign
  2728. FindCurrency(ref pos, value, nfi, ref foundCurrency);
  2729. if (foundCurrency)
  2730. {
  2731. if (allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2732. {
  2733. return false;
  2734. }
  2735. if (foundCurrency)
  2736. {
  2737. if (!foundSign && allowLeadingSign)
  2738. {
  2739. FindSign(ref pos, value, nfi, ref foundSign, ref negative);
  2740. if (foundSign && allowLeadingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2741. {
  2742. return false;
  2743. }
  2744. }
  2745. }
  2746. }
  2747. }
  2748. var number = Zero;
  2749. var nDigits = 0;
  2750. var decimalPointPos = -1;
  2751. var firstHexDigit = true;
  2752. // Number stuff
  2753. while (pos < value.Length)
  2754. {
  2755. if (!ValidDigit(value[pos], allowHexSpecifier))
  2756. {
  2757. if (allowThousands &&
  2758. (FindOther(ref pos, value, nfi.NumberGroupSeparator)
  2759. || FindOther(ref pos, value, nfi.CurrencyGroupSeparator)))
  2760. {
  2761. continue;
  2762. }
  2763. if (allowDecimalPoint && decimalPointPos < 0 &&
  2764. (FindOther(ref pos, value, nfi.NumberDecimalSeparator)
  2765. || FindOther(ref pos, value, nfi.CurrencyDecimalSeparator)))
  2766. {
  2767. decimalPointPos = nDigits;
  2768. continue;
  2769. }
  2770. break;
  2771. }
  2772. nDigits++;
  2773. if (allowHexSpecifier)
  2774. {
  2775. var hexDigit = value[pos++];
  2776. byte digitValue;
  2777. if (char.IsDigit(hexDigit))
  2778. {
  2779. digitValue = (byte)(hexDigit - '0');
  2780. }
  2781. else if (char.IsLower(hexDigit))
  2782. {
  2783. digitValue = (byte)(hexDigit - 'a' + 10);
  2784. }
  2785. else
  2786. {
  2787. digitValue = (byte)(hexDigit - 'A' + 10);
  2788. }
  2789. if (firstHexDigit && digitValue >= 8)
  2790. {
  2791. negative = true;
  2792. }
  2793. number = (number * 16) + digitValue;
  2794. firstHexDigit = false;
  2795. continue;
  2796. }
  2797. number = (number * 10) + (byte)(value[pos++] - '0');
  2798. }
  2799. // Post number stuff
  2800. if (nDigits == 0)
  2801. {
  2802. if (!tryParse)
  2803. {
  2804. exc = GetFormatException();
  2805. }
  2806. return false;
  2807. }
  2808. // Signed hex value (Two's Complement)
  2809. if (allowHexSpecifier && negative)
  2810. {
  2811. var mask = Pow(16, nDigits) - 1;
  2812. number = (number ^ mask) + 1;
  2813. }
  2814. var exponent = 0;
  2815. if (allowExponent)
  2816. {
  2817. if (FindExponent(ref pos, value, ref exponent, tryParse, ref exc) && exc != null)
  2818. {
  2819. return false;
  2820. }
  2821. }
  2822. if (allowTrailingSign && !foundSign)
  2823. {
  2824. // Sign + Currency
  2825. FindSign(ref pos, value, nfi, ref foundSign, ref negative);
  2826. if (foundSign && pos < value.Length)
  2827. {
  2828. if (allowTrailingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2829. {
  2830. return false;
  2831. }
  2832. }
  2833. }
  2834. if (allowCurrencySymbol && !foundCurrency)
  2835. {
  2836. if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, reportError: false, tryParse, ref exc))
  2837. {
  2838. return false;
  2839. }
  2840. // Currency + sign
  2841. FindCurrency(ref pos, value, nfi, ref foundCurrency);
  2842. if (foundCurrency && pos < value.Length)
  2843. {
  2844. if (allowTrailingWhite && !JumpOverWhitespace(ref pos, value, reportError: true, tryParse, ref exc))
  2845. {
  2846. return false;
  2847. }
  2848. if (!foundSign && allowTrailingSign)
  2849. {
  2850. FindSign(ref pos, value, nfi, ref foundSign, ref negative);
  2851. }
  2852. }
  2853. }
  2854. if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, reportError: false, tryParse, ref exc))
  2855. {
  2856. return false;
  2857. }
  2858. if (foundOpenParentheses)
  2859. {
  2860. if (pos >= value.Length || value[pos++] != ')')
  2861. {
  2862. if (!tryParse)
  2863. {
  2864. exc = GetFormatException();
  2865. }
  2866. return false;
  2867. }
  2868. if (allowTrailingWhite && pos < value.Length && !JumpOverWhitespace(ref pos, value, reportError: false, tryParse, ref exc))
  2869. {
  2870. return false;
  2871. }
  2872. }
  2873. if (pos < value.Length && value[pos] != '\u0000')
  2874. {
  2875. if (!tryParse)
  2876. {
  2877. exc = GetFormatException();
  2878. }
  2879. return false;
  2880. }
  2881. if (decimalPointPos >= 0)
  2882. {
  2883. exponent = exponent - nDigits + decimalPointPos;
  2884. }
  2885. if (exponent < 0)
  2886. {
  2887. // Any non-zero values after decimal point are not allowed
  2888. number = DivRem(number, Pow(10, -exponent), out var remainder);
  2889. if (!remainder.IsZero)
  2890. {
  2891. if (!tryParse)
  2892. {
  2893. exc = new OverflowException(string.Format(CultureInfo.InvariantCulture,
  2894. "Value too large or too small. exp= {0} rem = {1} pow = {2}",
  2895. exponent,
  2896. remainder,
  2897. Pow(10, -exponent)));
  2898. }
  2899. return false;
  2900. }
  2901. }
  2902. else if (exponent > 0)
  2903. {
  2904. number = Pow(10, exponent) * number;
  2905. }
  2906. if (number._sign == 0)
  2907. {
  2908. result = number;
  2909. }
  2910. else if (negative)
  2911. {
  2912. result = new BigInteger(-1, number._data);
  2913. }
  2914. else
  2915. {
  2916. result = new BigInteger(1, number._data);
  2917. }
  2918. return true;
  2919. }
  2920. private static bool CheckStyle(NumberStyles style, bool tryParse, ref Exception exc)
  2921. {
  2922. if ((style & NumberStyles.AllowHexSpecifier) == NumberStyles.AllowHexSpecifier)
  2923. {
  2924. var ne = style ^ NumberStyles.AllowHexSpecifier;
  2925. if ((ne & NumberStyles.AllowLeadingWhite) == NumberStyles.AllowLeadingWhite)
  2926. {
  2927. ne ^= NumberStyles.AllowLeadingWhite;
  2928. }
  2929. if ((ne & NumberStyles.AllowTrailingWhite) == NumberStyles.AllowTrailingWhite)
  2930. {
  2931. ne ^= NumberStyles.AllowTrailingWhite;
  2932. }
  2933. if (ne != NumberStyles.None)
  2934. {
  2935. if (!tryParse)
  2936. {
  2937. exc = new ArgumentException("With AllowHexSpecifier only " +
  2938. "AllowLeadingWhite and AllowTrailingWhite " +
  2939. "are permitted.");
  2940. }
  2941. return false;
  2942. }
  2943. }
  2944. else if ((uint)style > (uint)NumberStyles.Any)
  2945. {
  2946. if (!tryParse)
  2947. {
  2948. exc = new ArgumentException("Not a valid number style");
  2949. }
  2950. return false;
  2951. }
  2952. return true;
  2953. }
  2954. private static bool JumpOverWhitespace(ref int pos, string s, bool reportError, bool tryParse, ref Exception exc)
  2955. {
  2956. while (pos < s.Length && char.IsWhiteSpace(s[pos]))
  2957. {
  2958. pos++;
  2959. }
  2960. if (reportError && pos >= s.Length)
  2961. {
  2962. if (!tryParse)
  2963. {
  2964. exc = GetFormatException();
  2965. }
  2966. return false;
  2967. }
  2968. return true;
  2969. }
  2970. private static void FindSign(ref int pos, string s, NumberFormatInfo nfi, ref bool foundSign, ref bool negative)
  2971. {
  2972. if ((pos + nfi.NegativeSign.Length) <= s.Length &&
  2973. string.CompareOrdinal(s, pos, nfi.NegativeSign, 0, nfi.NegativeSign.Length) == 0)
  2974. {
  2975. negative = true;
  2976. foundSign = true;
  2977. pos += nfi.NegativeSign.Length;
  2978. }
  2979. else if ((pos + nfi.PositiveSign.Length) <= s.Length &&
  2980. string.CompareOrdinal(s, pos, nfi.PositiveSign, 0, nfi.PositiveSign.Length) == 0)
  2981. {
  2982. negative = false;
  2983. pos += nfi.PositiveSign.Length;
  2984. foundSign = true;
  2985. }
  2986. }
  2987. private static void FindCurrency(ref int pos, string s, NumberFormatInfo nfi, ref bool foundCurrency)
  2988. {
  2989. if ((pos + nfi.CurrencySymbol.Length) <= s.Length &&
  2990. s.Substring(pos, nfi.CurrencySymbol.Length) == nfi.CurrencySymbol)
  2991. {
  2992. foundCurrency = true;
  2993. pos += nfi.CurrencySymbol.Length;
  2994. }
  2995. }
  2996. private static bool FindExponent(ref int pos, string s, ref int exponent, bool tryParse, ref Exception exc)
  2997. {
  2998. exponent = 0;
  2999. if (pos >= s.Length || (s[pos] != 'e' && s[pos] != 'E'))
  3000. {
  3001. exc = null;
  3002. return false;
  3003. }
  3004. var i = pos + 1;
  3005. if (i == s.Length)
  3006. {
  3007. exc = tryParse ? null : GetFormatException();
  3008. return true;
  3009. }
  3010. var negative = false;
  3011. if (s[i] == '-')
  3012. {
  3013. negative = true;
  3014. if (++i == s.Length)
  3015. {
  3016. exc = tryParse ? null : GetFormatException();
  3017. return true;
  3018. }
  3019. }
  3020. if (s[i] == '+' && ++i == s.Length)
  3021. {
  3022. exc = tryParse ? null : GetFormatException();
  3023. return true;
  3024. }
  3025. long exp = 0; // temp long value
  3026. for (; i < s.Length; i++)
  3027. {
  3028. if (!char.IsDigit(s[i]))
  3029. {
  3030. exc = tryParse ? null : GetFormatException();
  3031. return true;
  3032. }
  3033. // Reduce the risk of throwing an overflow exc
  3034. exp = checked((exp * 10) - (s[i] - '0'));
  3035. if (exp is < int.MinValue or > int.MaxValue)
  3036. {
  3037. exc = tryParse ? null : new OverflowException("Value too large or too small.");
  3038. return true;
  3039. }
  3040. }
  3041. // exp value saved as negative
  3042. if (!negative)
  3043. {
  3044. exp = -exp;
  3045. }
  3046. exc = null;
  3047. exponent = (int)exp;
  3048. pos = i;
  3049. return true;
  3050. }
  3051. private static bool FindOther(ref int pos, string s, string other)
  3052. {
  3053. if ((pos + other.Length) <= s.Length &&
  3054. s.Substring(pos, other.Length) == other)
  3055. {
  3056. pos += other.Length;
  3057. return true;
  3058. }
  3059. return false;
  3060. }
  3061. private static bool ValidDigit(char e, bool allowHex)
  3062. {
  3063. if (allowHex)
  3064. {
  3065. return char.IsDigit(e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
  3066. }
  3067. return char.IsDigit(e);
  3068. }
  3069. private static FormatException GetFormatException()
  3070. {
  3071. return new FormatException("Input string was not in the correct format");
  3072. }
  3073. private static bool ProcessTrailingWhitespace(bool tryParse, string s, int position, ref Exception exc)
  3074. {
  3075. var len = s.Length;
  3076. for (var i = position; i < len; i++)
  3077. {
  3078. var c = s[i];
  3079. if (c != 0 && !char.IsWhiteSpace(c))
  3080. {
  3081. if (!tryParse)
  3082. {
  3083. exc = GetFormatException();
  3084. }
  3085. return false;
  3086. }
  3087. }
  3088. return true;
  3089. }
  3090. private static bool Parse(string value, bool tryParse, out BigInteger result, out Exception exc)
  3091. {
  3092. int i, sign = 1;
  3093. var digitsSeen = false;
  3094. result = Zero;
  3095. exc = null;
  3096. if (value is null)
  3097. {
  3098. if (!tryParse)
  3099. {
  3100. exc = new ArgumentNullException(nameof(value));
  3101. }
  3102. return false;
  3103. }
  3104. var len = value.Length;
  3105. char c;
  3106. for (i = 0; i < len; i++)
  3107. {
  3108. c = value[i];
  3109. if (!char.IsWhiteSpace(c))
  3110. {
  3111. break;
  3112. }
  3113. }
  3114. if (i == len)
  3115. {
  3116. if (!tryParse)
  3117. {
  3118. exc = GetFormatException();
  3119. }
  3120. return false;
  3121. }
  3122. var info = NumberFormatInfo.CurrentInfo;
  3123. var negative = info.NegativeSign;
  3124. var positive = info.PositiveSign;
  3125. if (string.CompareOrdinal(value, i, positive, 0, positive.Length) == 0)
  3126. {
  3127. i += positive.Length;
  3128. }
  3129. else if (string.CompareOrdinal(value, i, negative, 0, negative.Length) == 0)
  3130. {
  3131. sign = -1;
  3132. i += negative.Length;
  3133. }
  3134. var val = Zero;
  3135. for (; i < len; i++)
  3136. {
  3137. c = value[i];
  3138. if (c == '\0')
  3139. {
  3140. i = len;
  3141. continue;
  3142. }
  3143. if (c is >= '0' and <= '9')
  3144. {
  3145. var d = (byte)(c - '0');
  3146. val = (val * 10) + d;
  3147. digitsSeen = true;
  3148. }
  3149. else if (!ProcessTrailingWhitespace(tryParse, value, i, ref exc))
  3150. {
  3151. return false;
  3152. }
  3153. }
  3154. if (!digitsSeen)
  3155. {
  3156. if (!tryParse)
  3157. {
  3158. exc = GetFormatException();
  3159. }
  3160. return false;
  3161. }
  3162. if (val._sign == 0)
  3163. {
  3164. result = val;
  3165. }
  3166. #pragma warning disable CA1508 // Avoid dead conditional code | this is the following bug in the analyzer rule: https://github.com/dotnet/roslyn-analyzers/issues/6991
  3167. else if (sign == -1)
  3168. #pragma warning restore CA1508 // Avoid dead conditional code
  3169. {
  3170. result = new BigInteger(-1, val._data);
  3171. }
  3172. else
  3173. {
  3174. result = new BigInteger(1, val._data);
  3175. }
  3176. return true;
  3177. }
  3178. /// <summary>
  3179. /// Returns the smaller of two <see cref="BigInteger"/> values.
  3180. /// </summary>
  3181. /// <param name="left">The first value to compare.</param>
  3182. /// <param name="right">The second value to compare.</param>
  3183. /// <returns>
  3184. /// The <paramref name="left"/> or <paramref name="right"/> parameter, whichever is smaller.
  3185. /// </returns>
  3186. public static BigInteger Min(BigInteger left, BigInteger right)
  3187. {
  3188. int ls = left._sign;
  3189. int rs = right._sign;
  3190. if (ls < rs)
  3191. {
  3192. return left;
  3193. }
  3194. if (rs < ls)
  3195. {
  3196. return right;
  3197. }
  3198. var r = CoreCompare(left._data, right._data);
  3199. if (ls == -1)
  3200. {
  3201. r = -r;
  3202. }
  3203. if (r <= 0)
  3204. {
  3205. return left;
  3206. }
  3207. return right;
  3208. }
  3209. /// <summary>
  3210. /// Returns the larger of two <see cref="BigInteger"/> values.
  3211. /// </summary>
  3212. /// <param name="left">The first value to compare.</param>
  3213. /// <param name="right">The second value to compare.</param>
  3214. /// <returns>
  3215. /// The <paramref name="left"/> or <paramref name="right"/> parameter, whichever is larger.
  3216. /// </returns>
  3217. public static BigInteger Max(BigInteger left, BigInteger right)
  3218. {
  3219. int ls = left._sign;
  3220. int rs = right._sign;
  3221. if (ls > rs)
  3222. {
  3223. return left;
  3224. }
  3225. if (rs > ls)
  3226. {
  3227. return right;
  3228. }
  3229. var r = CoreCompare(left._data, right._data);
  3230. if (ls == -1)
  3231. {
  3232. r = -r;
  3233. }
  3234. if (r >= 0)
  3235. {
  3236. return left;
  3237. }
  3238. return right;
  3239. }
  3240. /// <summary>
  3241. /// Gets the absolute value of a <see cref="BigInteger"/> object.
  3242. /// </summary>
  3243. /// <param name="value">A number.</param>
  3244. /// <returns>
  3245. /// The absolute value of <paramref name="value"/>.
  3246. /// </returns>
  3247. public static BigInteger Abs(BigInteger value)
  3248. {
  3249. return new BigInteger(Math.Abs(value._sign), value._data);
  3250. }
  3251. /// <summary>
  3252. /// Divides one <see cref="BigInteger"/> value by another, returns the result, and returns the remainder in
  3253. /// an output parameter.
  3254. /// </summary>
  3255. /// <param name="dividend">The value to be divided.</param>
  3256. /// <param name="divisor">The value to divide by.</param>
  3257. /// <param name="remainder">When this method returns, contains a <see cref="BigInteger"/> value that represents the remainder from the division. This parameter is passed uninitialized.</param>
  3258. /// <returns>
  3259. /// The quotient of the division.
  3260. /// </returns>
  3261. public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
  3262. {
  3263. if (divisor._sign == 0)
  3264. {
  3265. throw new DivideByZeroException();
  3266. }
  3267. if (dividend._sign == 0)
  3268. {
  3269. remainder = dividend;
  3270. return dividend;
  3271. }
  3272. DivModUnsigned(dividend._data, divisor._data, out var quotient, out var remainderValue);
  3273. int i;
  3274. for (i = remainderValue.Length - 1; i >= 0 && remainderValue[i] == 0; --i)
  3275. {
  3276. // Intentionally empty block
  3277. }
  3278. if (i == -1)
  3279. {
  3280. remainder = Zero;
  3281. }
  3282. else
  3283. {
  3284. if (i < remainderValue.Length - 1)
  3285. {
  3286. Array.Resize(ref remainderValue, i + 1);
  3287. }
  3288. remainder = new BigInteger(dividend._sign, remainderValue);
  3289. }
  3290. for (i = quotient.Length - 1; i >= 0 && quotient[i] == 0; --i)
  3291. {
  3292. // Intentionally empty block
  3293. }
  3294. if (i == -1)
  3295. {
  3296. return Zero;
  3297. }
  3298. if (i < quotient.Length - 1)
  3299. {
  3300. Array.Resize(ref quotient, i + 1);
  3301. }
  3302. return new BigInteger((short)(dividend._sign * divisor._sign), quotient);
  3303. }
  3304. /// <summary>
  3305. /// Raises a <see cref="BigInteger"/> value to the power of a specified value.
  3306. /// </summary>
  3307. /// <param name="value">The number to raise to the <paramref name="exponent"/> power.</param>
  3308. /// <param name="exponent">The exponent to raise <paramref name="value"/> by.</param>
  3309. /// <returns>
  3310. /// The result of raising <paramref name="value"/> to the <paramref name="exponent"/> power.
  3311. /// </returns>
  3312. public static BigInteger Pow(BigInteger value, int exponent)
  3313. {
  3314. if (exponent < 0)
  3315. {
  3316. throw new ArgumentOutOfRangeException(nameof(exponent), "exp must be >= 0");
  3317. }
  3318. if (exponent == 0)
  3319. {
  3320. return One;
  3321. }
  3322. if (exponent == 1)
  3323. {
  3324. return value;
  3325. }
  3326. var result = One;
  3327. while (exponent != 0)
  3328. {
  3329. if ((exponent & 1) != 0)
  3330. {
  3331. result *= value;
  3332. }
  3333. if (exponent == 1)
  3334. {
  3335. break;
  3336. }
  3337. value *= value;
  3338. exponent >>= 1;
  3339. }
  3340. return result;
  3341. }
  3342. /// <summary>
  3343. /// Performs modulus division on a number raised to the power of another number.
  3344. /// </summary>
  3345. /// <param name="value">The number to raise to the <paramref name="exponent"/> power.</param>
  3346. /// <param name="exponent">The exponent to raise <paramref name="value"/> by.</param>
  3347. /// <param name="modulus">The number by which to divide <paramref name="value"/> raised to the <paramref name="exponent"/> power.</param>
  3348. /// <returns>
  3349. /// The remainder after dividing <paramref name="value"/> raised by <paramref name="exponent"/> by
  3350. /// <paramref name="modulus"/>.
  3351. /// </returns>
  3352. /// <exception cref="ArgumentOutOfRangeException"><paramref name="exponent"/> is negative.</exception>
  3353. public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus)
  3354. {
  3355. if (exponent._sign == -1)
  3356. {
  3357. throw new ArgumentOutOfRangeException(nameof(exponent), "power must be >= 0");
  3358. }
  3359. if (modulus._sign == 0)
  3360. {
  3361. throw new DivideByZeroException();
  3362. }
  3363. var result = One % modulus;
  3364. while (exponent._sign != 0)
  3365. {
  3366. if (!exponent.IsEven)
  3367. {
  3368. result *= value;
  3369. result %= modulus;
  3370. }
  3371. if (exponent.IsOne)
  3372. {
  3373. break;
  3374. }
  3375. value *= value;
  3376. value %= modulus;
  3377. exponent >>= 1;
  3378. }
  3379. return result;
  3380. }
  3381. /// <summary>
  3382. /// Finds the greatest common divisor of two <see cref="BigInteger"/> values.
  3383. /// </summary>
  3384. /// <param name="left">The first value.</param>
  3385. /// <param name="right">The second value.</param>
  3386. /// <returns>
  3387. /// The greatest common divisor of <paramref name="left"/> and <paramref name="right"/>.
  3388. /// </returns>
  3389. public static BigInteger GreatestCommonDivisor(BigInteger left, BigInteger right)
  3390. {
  3391. if (left._sign != 0 && left._data.Length == 1 && left._data[0] == 1)
  3392. {
  3393. return One;
  3394. }
  3395. if (right._sign != 0 && right._data.Length == 1 && right._data[0] == 1)
  3396. {
  3397. return One;
  3398. }
  3399. if (left.IsZero)
  3400. {
  3401. return Abs(right);
  3402. }
  3403. if (right.IsZero)
  3404. {
  3405. return Abs(left);
  3406. }
  3407. var x = new BigInteger(1, left._data);
  3408. var y = new BigInteger(1, right._data);
  3409. var g = y;
  3410. while (x._data.Length > 1)
  3411. {
  3412. g = x;
  3413. x = y % x;
  3414. y = g;
  3415. }
  3416. if (x.IsZero)
  3417. {
  3418. return g;
  3419. }
  3420. // TODO: should we have something here if we can convert to long?
  3421. /*
  3422. * Now we can just do it with single precision. I am using the binary gcd method,
  3423. * as it should be faster.
  3424. */
  3425. var yy = x._data[0];
  3426. var xx = (uint)(y % yy);
  3427. var t = 0;
  3428. while (((xx | yy) & 1) == 0)
  3429. {
  3430. xx >>= 1;
  3431. yy >>= 1;
  3432. t++;
  3433. }
  3434. while (xx != 0)
  3435. {
  3436. while ((xx & 1) == 0)
  3437. {
  3438. xx >>= 1;
  3439. }
  3440. while ((yy & 1) == 0)
  3441. {
  3442. yy >>= 1;
  3443. }
  3444. if (xx >= yy)
  3445. {
  3446. xx = (xx - yy) >> 1;
  3447. }
  3448. else
  3449. {
  3450. yy = (yy - xx) >> 1;
  3451. }
  3452. }
  3453. return yy << t;
  3454. }
  3455. /*
  3456. * LAMESPEC Log doesn't specify to how many ulp is has to be precise
  3457. * We are equilavent to MS with about 2 ULP
  3458. */
  3459. /// <summary>
  3460. /// Returns the logarithm of a specified number in a specified base.
  3461. /// </summary>
  3462. /// <param name="value">A number whose logarithm is to be found.</param>
  3463. /// <param name="baseValue">The base of the logarithm.</param>
  3464. /// <returns>
  3465. /// The base <paramref name="baseValue"/> logarithm of value.
  3466. /// </returns>
  3467. /// <exception cref="ArgumentOutOfRangeException">The log of <paramref name="value"/> is out of range of the <see cref="double"/> data type.</exception>
  3468. public static double Log(BigInteger value, double baseValue)
  3469. {
  3470. if (value._sign == -1 || baseValue == 1.0d || baseValue == -1.0d ||
  3471. baseValue == double.NegativeInfinity || double.IsNaN(baseValue))
  3472. {
  3473. return double.NaN;
  3474. }
  3475. if (baseValue is 0.0d or double.PositiveInfinity)
  3476. {
  3477. return value.IsOne ? 0 : double.NaN;
  3478. }
  3479. if (value._data is null)
  3480. {
  3481. return double.NegativeInfinity;
  3482. }
  3483. var length = value._data.Length - 1;
  3484. var bitCount = -1;
  3485. for (var curBit = 31; curBit >= 0; curBit--)
  3486. {
  3487. if ((value._data[length] & (1 << curBit)) != 0)
  3488. {
  3489. bitCount = curBit + (length * 32);
  3490. break;
  3491. }
  3492. }
  3493. long bitlen = bitCount;
  3494. double c = 0, d = 1;
  3495. var testBit = One;
  3496. var tempBitlen = bitlen;
  3497. while (tempBitlen > int.MaxValue)
  3498. {
  3499. testBit <<= int.MaxValue;
  3500. tempBitlen -= int.MaxValue;
  3501. }
  3502. testBit <<= (int)tempBitlen;
  3503. for (var curbit = bitlen; curbit >= 0; --curbit)
  3504. {
  3505. if ((value & testBit)._sign != 0)
  3506. {
  3507. c += d;
  3508. }
  3509. d *= 0.5;
  3510. testBit >>= 1;
  3511. }
  3512. return (Math.Log(c) + (Math.Log(2) * bitlen)) / Math.Log(baseValue);
  3513. }
  3514. /// <summary>
  3515. /// Returns the natural (base <c>e</c>) logarithm of a specified number.
  3516. /// </summary>
  3517. /// <param name="value">The number whose logarithm is to be found.</param>
  3518. /// <returns>
  3519. /// The natural (base <c>e</c>) logarithm of <paramref name="value"/>.
  3520. /// </returns>
  3521. /// <exception cref="ArgumentOutOfRangeException">The base 10 log of value is out of range of the <see cref="double"/> data type.</exception>
  3522. public static double Log(BigInteger value)
  3523. {
  3524. return Log(value, Math.E);
  3525. }
  3526. /// <summary>
  3527. /// Returns the base 10 logarithm of a specified number.
  3528. /// </summary>
  3529. /// <param name="value">A number whose logarithm is to be found.</param>
  3530. /// <returns>
  3531. /// The base 10 logarithm of <paramref name="value"/>.
  3532. /// </returns>
  3533. /// <exception cref="ArgumentOutOfRangeException">The base 10 log of value is out of range of the <see cref="double"/> data type.</exception>
  3534. public static double Log10(BigInteger value)
  3535. {
  3536. return Log(value, 10);
  3537. }
  3538. /// <summary>
  3539. /// Returns the hash code for the current <see cref="BigInteger"/> object.
  3540. /// </summary>
  3541. /// <returns>
  3542. /// A 32-bit signed integer hash code.
  3543. /// </returns>
  3544. public override readonly int GetHashCode()
  3545. {
  3546. var hash = (uint)(_sign * 0x01010101u);
  3547. if (_data != null)
  3548. {
  3549. foreach (var bit in _data)
  3550. {
  3551. hash ^= bit;
  3552. }
  3553. }
  3554. return (int)hash;
  3555. }
  3556. /// <summary>
  3557. /// Adds two <see cref="BigInteger"/> values and returns the result.
  3558. /// </summary>
  3559. /// <param name="left">The first value to add.</param>
  3560. /// <param name="right">The second value to add.</param>
  3561. /// <returns>
  3562. /// The sum of <paramref name="left"/> and <paramref name="right"/>.
  3563. /// </returns>
  3564. public static BigInteger Add(BigInteger left, BigInteger right)
  3565. {
  3566. return left + right;
  3567. }
  3568. /// <summary>
  3569. /// Subtracts one <see cref="BigInteger"/> value from another and returns the result.
  3570. /// </summary>
  3571. /// <param name="left">The value to subtract from (the minuend).</param>
  3572. /// <param name="right">The value to subtract (the subtrahend).</param>
  3573. /// <returns>
  3574. /// The result of subtracting <paramref name="right"/> from <paramref name="left"/>.
  3575. /// </returns>
  3576. public static BigInteger Subtract(BigInteger left, BigInteger right)
  3577. {
  3578. return left - right;
  3579. }
  3580. /// <summary>
  3581. /// Returns the product of two <see cref="BigInteger"/> values.
  3582. /// </summary>
  3583. /// <param name="left">The first number to multiply.</param>
  3584. /// <param name="right">The second number to multiply.</param>
  3585. /// <returns>
  3586. /// The product of the <paramref name="left"/> and <paramref name="right"/> parameters.
  3587. /// </returns>
  3588. public static BigInteger Multiply(BigInteger left, BigInteger right)
  3589. {
  3590. return left * right;
  3591. }
  3592. /// <summary>
  3593. /// Divides one <see cref="BigInteger"/> value by another and returns the result.
  3594. /// </summary>
  3595. /// <param name="dividend">The value to be divided.</param>
  3596. /// <param name="divisor">The value to divide by.</param>
  3597. /// <returns>
  3598. /// The quotient of the division.
  3599. /// </returns>
  3600. public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
  3601. {
  3602. return dividend / divisor;
  3603. }
  3604. /// <summary>
  3605. /// Performs integer division on two <see cref="BigInteger"/> values and returns the remainder.
  3606. /// </summary>
  3607. /// <param name="dividend">The value to be divided.</param>
  3608. /// <param name="divisor">The value to divide by.</param>
  3609. /// <returns>
  3610. /// The remainder after dividing <paramref name="dividend"/> by <paramref name="divisor"/>.
  3611. /// </returns>
  3612. public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
  3613. {
  3614. return dividend % divisor;
  3615. }
  3616. /// <summary>
  3617. /// Negates a specified <see cref="BigInteger"/> value.
  3618. /// </summary>
  3619. /// <param name="value">The value to negate.</param>
  3620. /// <returns>
  3621. /// The result of the <paramref name="value"/> parameter multiplied by negative one (-1).
  3622. /// </returns>
  3623. public static BigInteger Negate(BigInteger value)
  3624. {
  3625. return -value;
  3626. }
  3627. /// <summary>
  3628. /// Compares this instance to a specified object and returns an integer that indicates whether the value of
  3629. /// this instance is less than, equal to, or greater than the value of the specified object.
  3630. /// </summary>
  3631. /// <param name="obj">The object to compare.</param>
  3632. /// <returns>
  3633. /// A signed integer that indicates the relationship of the current instance to the <paramref name="obj"/> parameter,
  3634. /// as shown in the following table.
  3635. /// <list type="table">
  3636. /// <listheader>
  3637. /// <term>Value</term>
  3638. /// <description>Condition</description>
  3639. /// </listheader>
  3640. /// <item>
  3641. /// <term>Less than zero</term>
  3642. /// <description>The current instance is less than <paramref name="obj"/>.</description>
  3643. /// </item>
  3644. /// <item>
  3645. /// <term>Zero</term>
  3646. /// <description>The current instance equals <paramref name="obj"/>.</description>
  3647. /// </item>
  3648. /// <item>
  3649. /// <term>Greater than zero</term>
  3650. /// <description>The current instance is greater than <paramref name="obj"/>.</description>
  3651. /// </item>
  3652. /// </list>
  3653. /// </returns>
  3654. /// <exception cref="ArgumentException"><paramref name="obj"/> is not a <see cref="BigInteger"/>.</exception>
  3655. public readonly int CompareTo(object obj)
  3656. {
  3657. if (obj is null)
  3658. {
  3659. return 1;
  3660. }
  3661. if (obj is not BigInteger other)
  3662. {
  3663. return -1;
  3664. }
  3665. return Compare(this, other);
  3666. }
  3667. /// <summary>
  3668. /// Compares this instance to a second <see cref="BigInteger"/> and returns an integer that indicates whether the
  3669. /// value of this instance is less than, equal to, or greater than the value of the specified object.
  3670. /// </summary>
  3671. /// <param name="other">The object to compare.</param>
  3672. /// <returns>
  3673. /// A signed integer value that indicates the relationship of this instance to <paramref name="other"/>, as
  3674. /// shown in the following table.
  3675. /// <list type="table">
  3676. /// <listheader>
  3677. /// <term>Value</term>
  3678. /// <description>Condition</description>
  3679. /// </listheader>
  3680. /// <item>
  3681. /// <term>Less than zero</term>
  3682. /// <description>The current instance is less than <paramref name="other"/>.</description>
  3683. /// </item>
  3684. /// <item>
  3685. /// <term>Zero</term>
  3686. /// <description>The current instance equals <paramref name="other"/>.</description>
  3687. /// </item>
  3688. /// <item>
  3689. /// <term>Greater than zero</term>
  3690. /// <description>The current instance is greater than <paramref name="other"/>.</description>
  3691. /// </item>
  3692. /// </list>
  3693. /// </returns>
  3694. public readonly int CompareTo(BigInteger other)
  3695. {
  3696. return Compare(this, other);
  3697. }
  3698. /// <summary>
  3699. /// Compares this instance to an unsigned 64-bit integer and returns an integer that indicates whether the value of this
  3700. /// instance is less than, equal to, or greater than the value of the unsigned 64-bit integer.
  3701. /// </summary>
  3702. /// <param name="other">The unsigned 64-bit integer to compare.</param>
  3703. /// <returns>
  3704. /// A signed integer that indicates the relative value of this instance and <paramref name="other"/>, as shown
  3705. /// in the following table.
  3706. /// <list type="table">
  3707. /// <listheader>
  3708. /// <term>Value</term>
  3709. /// <description>Condition</description>
  3710. /// </listheader>
  3711. /// <item>
  3712. /// <term>Less than zero</term>
  3713. /// <description>The current instance is less than <paramref name="other"/>.</description>
  3714. /// </item>
  3715. /// <item>
  3716. /// <term>Zero</term>
  3717. /// <description>The current instance equals <paramref name="other"/>.</description>
  3718. /// </item>
  3719. /// <item>
  3720. /// <term>Greater than zero</term>
  3721. /// <description>The current instance is greater than <paramref name="other"/>.</description>
  3722. /// </item>
  3723. /// </list>
  3724. /// </returns>
  3725. [CLSCompliant(false)]
  3726. public readonly int CompareTo(ulong other)
  3727. {
  3728. if (_sign < 0)
  3729. {
  3730. return -1;
  3731. }
  3732. if (_sign == 0)
  3733. {
  3734. return other == 0 ? 0 : -1;
  3735. }
  3736. if (_data.Length > 2)
  3737. {
  3738. return 1;
  3739. }
  3740. var high = (uint)(other >> 32);
  3741. var low = (uint)other;
  3742. return LongCompare(low, high);
  3743. }
  3744. /// <summary>
  3745. /// Compares this instance to a signed 64-bit integer and returns an integer that indicates whether the value of this
  3746. /// instance is less than, equal to, or greater than the value of the signed 64-bit integer.
  3747. /// </summary>
  3748. /// <param name="other">The signed 64-bit integer to compare.</param>
  3749. /// <returns>
  3750. /// A signed integer that indicates the relative value of this instance and <paramref name="other"/>, as shown
  3751. /// in the following table.
  3752. /// <list type="table">
  3753. /// <listheader>
  3754. /// <term>Value</term>
  3755. /// <description>Condition</description>
  3756. /// </listheader>
  3757. /// <item>
  3758. /// <term>Less than zero</term>
  3759. /// <description>The current instance is less than <paramref name="other"/>.</description>
  3760. /// </item>
  3761. /// <item>
  3762. /// <term>Zero</term>
  3763. /// <description>The current instance equals <paramref name="other"/>.</description>
  3764. /// </item>
  3765. /// <item>
  3766. /// <term>Greater than zero</term>
  3767. /// <description>The current instance is greater than <paramref name="other"/>.</description>
  3768. /// </item>
  3769. /// </list>
  3770. /// </returns>
  3771. public readonly int CompareTo(long other)
  3772. {
  3773. int ls = _sign;
  3774. var rs = Math.Sign(other);
  3775. if (ls != rs)
  3776. {
  3777. return ls > rs ? 1 : -1;
  3778. }
  3779. if (ls == 0)
  3780. {
  3781. return 0;
  3782. }
  3783. if (_data.Length > 2)
  3784. {
  3785. return _sign;
  3786. }
  3787. if (other < 0)
  3788. {
  3789. other = -other;
  3790. }
  3791. var low = (uint)other;
  3792. var high = (uint)((ulong)other >> 32);
  3793. var r = LongCompare(low, high);
  3794. if (ls == -1)
  3795. {
  3796. r = -r;
  3797. }
  3798. return r;
  3799. }
  3800. private readonly int LongCompare(uint low, uint high)
  3801. {
  3802. uint h = 0;
  3803. if (_data.Length > 1)
  3804. {
  3805. h = _data[1];
  3806. }
  3807. if (h > high)
  3808. {
  3809. return 1;
  3810. }
  3811. if (h < high)
  3812. {
  3813. return -1;
  3814. }
  3815. var l = _data[0];
  3816. if (l > low)
  3817. {
  3818. return 1;
  3819. }
  3820. if (l < low)
  3821. {
  3822. return -1;
  3823. }
  3824. return 0;
  3825. }
  3826. /// <summary>
  3827. /// Compares two <see cref="BigInteger"/> values and returns an integer that indicates whether the first value is less than, equal to, or greater than the second value.
  3828. /// </summary>
  3829. /// <param name="left">The first value to compare.</param>
  3830. /// <param name="right">The second value to compare.</param>
  3831. /// <returns>
  3832. /// A signed integer that indicates the relative values of left and right, as shown in the following table.
  3833. /// <list type="table">
  3834. /// <listheader>
  3835. /// <term>Value</term>
  3836. /// <description>Condition</description>
  3837. /// </listheader>
  3838. /// <item>
  3839. /// <term>Less than zero</term>
  3840. /// <description><paramref name="left"/> is less than <paramref name="right"/>.</description>
  3841. /// </item>
  3842. /// <item>
  3843. /// <term>Zero</term>
  3844. /// <description><paramref name="left"/> equals <paramref name="right"/>.</description>
  3845. /// </item>
  3846. /// <item>
  3847. /// <term>Greater than zero</term>
  3848. /// <description><paramref name="left"/> is greater than <paramref name="right"/>.</description>
  3849. /// </item>
  3850. /// </list>
  3851. /// </returns>
  3852. public static int Compare(BigInteger left, BigInteger right)
  3853. {
  3854. int ls = left._sign;
  3855. int rs = right._sign;
  3856. if (ls != rs)
  3857. {
  3858. return ls > rs ? 1 : -1;
  3859. }
  3860. var r = CoreCompare(left._data, right._data);
  3861. if (ls < 0)
  3862. {
  3863. r = -r;
  3864. }
  3865. return r;
  3866. }
  3867. private static int TopByte(uint x)
  3868. {
  3869. if ((x & 0xFFFF0000u) != 0)
  3870. {
  3871. if ((x & 0xFF000000u) != 0)
  3872. {
  3873. return 4;
  3874. }
  3875. return 3;
  3876. }
  3877. if ((x & 0xFF00u) != 0)
  3878. {
  3879. return 2;
  3880. }
  3881. return 1;
  3882. }
  3883. private static int FirstNonFfByte(uint word)
  3884. {
  3885. if ((word & 0xFF000000u) != 0xFF000000u)
  3886. {
  3887. return 4;
  3888. }
  3889. if ((word & 0xFF0000u) != 0xFF0000u)
  3890. {
  3891. return 3;
  3892. }
  3893. if ((word & 0xFF00u) != 0xFF00u)
  3894. {
  3895. return 2;
  3896. }
  3897. return 1;
  3898. }
  3899. /// <summary>
  3900. /// Converts a <see cref="BigInteger"/> value to a byte array.
  3901. /// </summary>
  3902. /// <returns>
  3903. /// The value of the current <see cref="BigInteger"/> object converted to an array of bytes.
  3904. /// </returns>
  3905. public readonly byte[] ToByteArray()
  3906. {
  3907. if (_sign == 0)
  3908. {
  3909. return new byte[1];
  3910. }
  3911. // number of bytes not counting upper word
  3912. var bytes = (_data.Length - 1) * 4;
  3913. var needExtraZero = false;
  3914. var topWord = _data[_data.Length - 1];
  3915. int extra;
  3916. // if the topmost bit is set we need an extra
  3917. if (_sign == 1)
  3918. {
  3919. extra = TopByte(topWord);
  3920. var mask = 0x80u << ((extra - 1) * 8);
  3921. if ((topWord & mask) != 0)
  3922. {
  3923. needExtraZero = true;
  3924. }
  3925. }
  3926. else
  3927. {
  3928. extra = TopByte(topWord);
  3929. }
  3930. var res = new byte[bytes + extra + (needExtraZero ? 1 : 0)];
  3931. if (_sign == 1)
  3932. {
  3933. var j = 0;
  3934. var end = _data.Length - 1;
  3935. for (var i = 0; i < end; ++i)
  3936. {
  3937. var word = _data[i];
  3938. res[j++] = (byte)word;
  3939. res[j++] = (byte)(word >> 8);
  3940. res[j++] = (byte)(word >> 16);
  3941. res[j++] = (byte)(word >> 24);
  3942. }
  3943. while (extra-- > 0)
  3944. {
  3945. res[j++] = (byte)topWord;
  3946. topWord >>= 8;
  3947. }
  3948. }
  3949. else
  3950. {
  3951. var j = 0;
  3952. var end = _data.Length - 1;
  3953. uint carry = 1, word;
  3954. ulong add;
  3955. for (var i = 0; i < end; ++i)
  3956. {
  3957. word = _data[i];
  3958. add = (ulong)~word + carry;
  3959. word = (uint)add;
  3960. carry = (uint)(add >> 32);
  3961. res[j++] = (byte)word;
  3962. res[j++] = (byte)(word >> 8);
  3963. res[j++] = (byte)(word >> 16);
  3964. res[j++] = (byte)(word >> 24);
  3965. }
  3966. add = (ulong)~topWord + carry;
  3967. word = (uint)add;
  3968. carry = (uint)(add >> 32);
  3969. if (carry == 0)
  3970. {
  3971. var ex = FirstNonFfByte(word);
  3972. var needExtra = (word & (1 << ((ex * 8) - 1))) == 0;
  3973. var to = ex + (needExtra ? 1 : 0);
  3974. if (to != extra)
  3975. {
  3976. Array.Resize(ref res, bytes + to);
  3977. }
  3978. while (ex-- > 0)
  3979. {
  3980. res[j++] = (byte)word;
  3981. word >>= 8;
  3982. }
  3983. if (needExtra)
  3984. {
  3985. res[j++] = 0xFF;
  3986. }
  3987. }
  3988. else
  3989. {
  3990. Array.Resize(ref res, bytes + 5);
  3991. res[j++] = (byte)word;
  3992. res[j++] = (byte)(word >> 8);
  3993. res[j++] = (byte)(word >> 16);
  3994. res[j++] = (byte)(word >> 24);
  3995. res[j++] = 0xFF;
  3996. }
  3997. }
  3998. return res;
  3999. }
  4000. private static uint[] CoreAdd(uint[] a, uint[] b)
  4001. {
  4002. if (a.Length < b.Length)
  4003. {
  4004. var tmp = a;
  4005. a = b;
  4006. b = tmp;
  4007. }
  4008. var bl = a.Length;
  4009. var sl = b.Length;
  4010. var res = new uint[bl];
  4011. ulong sum = 0;
  4012. var i = 0;
  4013. for (; i < sl; i++)
  4014. {
  4015. sum = sum + a[i] + b[i];
  4016. res[i] = (uint)sum;
  4017. sum >>= 32;
  4018. }
  4019. for (; i < bl; i++)
  4020. {
  4021. sum += a[i];
  4022. res[i] = (uint)sum;
  4023. sum >>= 32;
  4024. }
  4025. if (sum != 0)
  4026. {
  4027. Array.Resize(ref res, bl + 1);
  4028. res[i] = (uint)sum;
  4029. }
  4030. return res;
  4031. }
  4032. private static uint[] CoreAdd(uint[] a, uint b)
  4033. {
  4034. var len = a.Length;
  4035. var res = new uint[len];
  4036. ulong sum = b;
  4037. int i;
  4038. for (i = 0; i < len; i++)
  4039. {
  4040. sum += a[i];
  4041. res[i] = (uint)sum;
  4042. sum >>= 32;
  4043. }
  4044. if (sum != 0)
  4045. {
  4046. Array.Resize(ref res, len + 1);
  4047. res[i] = (uint)sum;
  4048. }
  4049. return res;
  4050. }
  4051. /*invariant a > b*/
  4052. private static uint[] CoreSub(uint[] a, uint[] b)
  4053. {
  4054. var bl = a.Length;
  4055. var sl = b.Length;
  4056. var res = new uint[bl];
  4057. ulong borrow = 0;
  4058. int i;
  4059. for (i = 0; i < sl; ++i)
  4060. {
  4061. borrow = (ulong)a[i] - b[i] - borrow;
  4062. res[i] = (uint)borrow;
  4063. borrow = (borrow >> 32) & 0x1;
  4064. }
  4065. for (; i < bl; i++)
  4066. {
  4067. borrow = (ulong)a[i] - borrow;
  4068. res[i] = (uint)borrow;
  4069. borrow = (borrow >> 32) & 0x1;
  4070. }
  4071. // remove extra zeroes
  4072. for (i = bl - 1; i >= 0 && res[i] == 0; --i)
  4073. {
  4074. // Intentionally empty block
  4075. }
  4076. if (i < bl - 1)
  4077. {
  4078. Array.Resize(ref res, i + 1);
  4079. }
  4080. return res;
  4081. }
  4082. private static uint[] CoreSub(uint[] a, uint b)
  4083. {
  4084. var len = a.Length;
  4085. var res = new uint[len];
  4086. ulong borrow = b;
  4087. int i;
  4088. for (i = 0; i < len; i++)
  4089. {
  4090. borrow = (ulong)a[i] - borrow;
  4091. res[i] = (uint)borrow;
  4092. borrow = (borrow >> 32) & 0x1;
  4093. }
  4094. // Remove extra zeroes
  4095. for (i = len - 1; i >= 0 && res[i] == 0; --i)
  4096. {
  4097. // Intentionally empty block
  4098. }
  4099. if (i < len - 1)
  4100. {
  4101. Array.Resize(ref res, i + 1);
  4102. }
  4103. return res;
  4104. }
  4105. private static int CoreCompare(uint[] a, uint[] b)
  4106. {
  4107. var al = a != null ? a.Length : 0;
  4108. var bl = b != null ? b.Length : 0;
  4109. if (al > bl)
  4110. {
  4111. return 1;
  4112. }
  4113. if (bl > al)
  4114. {
  4115. return -1;
  4116. }
  4117. for (var i = al - 1; i >= 0; --i)
  4118. {
  4119. var ai = a[i];
  4120. var bi = b[i];
  4121. if (ai > bi)
  4122. {
  4123. return 1;
  4124. }
  4125. if (ai < bi)
  4126. {
  4127. return -1;
  4128. }
  4129. }
  4130. return 0;
  4131. }
  4132. private static int GetNormalizeShift(uint value)
  4133. {
  4134. var shift = 0;
  4135. if ((value & 0xFFFF0000) == 0)
  4136. {
  4137. value <<= 16;
  4138. shift += 16;
  4139. }
  4140. if ((value & 0xFF000000) == 0)
  4141. {
  4142. value <<= 8;
  4143. shift += 8;
  4144. }
  4145. if ((value & 0xF0000000) == 0)
  4146. {
  4147. value <<= 4;
  4148. shift += 4;
  4149. }
  4150. if ((value & 0xC0000000) == 0)
  4151. {
  4152. value <<= 2;
  4153. shift += 2;
  4154. }
  4155. if ((value & 0x80000000) == 0)
  4156. {
  4157. #pragma warning disable IDE0059 // Unnecessary assignment of a value
  4158. value <<= 1;
  4159. #pragma warning restore IDE0059 // Unnecessary assignment of a value
  4160. shift += 1;
  4161. }
  4162. return shift;
  4163. }
  4164. private static void Normalize(uint[] u, int l, uint[] un, int shift)
  4165. {
  4166. uint carry = 0;
  4167. int i;
  4168. if (shift > 0)
  4169. {
  4170. var rshift = 32 - shift;
  4171. for (i = 0; i < l; i++)
  4172. {
  4173. var ui = u[i];
  4174. un[i] = (ui << shift) | carry;
  4175. carry = ui >> rshift;
  4176. }
  4177. }
  4178. else
  4179. {
  4180. for (i = 0; i < l; i++)
  4181. {
  4182. un[i] = u[i];
  4183. }
  4184. }
  4185. while (i < un.Length)
  4186. {
  4187. un[i++] = 0;
  4188. }
  4189. if (carry != 0)
  4190. {
  4191. un[l] = carry;
  4192. }
  4193. }
  4194. private static void Unnormalize(uint[] un, out uint[] r, int shift)
  4195. {
  4196. var length = un.Length;
  4197. r = new uint[length];
  4198. if (shift > 0)
  4199. {
  4200. var lshift = 32 - shift;
  4201. uint carry = 0;
  4202. for (var i = length - 1; i >= 0; i--)
  4203. {
  4204. var uni = un[i];
  4205. r[i] = (uni >> shift) | carry;
  4206. carry = uni << lshift;
  4207. }
  4208. }
  4209. else
  4210. {
  4211. for (var i = 0; i < length; i++)
  4212. {
  4213. r[i] = un[i];
  4214. }
  4215. }
  4216. }
  4217. private static void DivModUnsigned(uint[] u, uint[] v, out uint[] q, out uint[] r)
  4218. {
  4219. var m = u.Length;
  4220. var n = v.Length;
  4221. if (n <= 1)
  4222. {
  4223. // Divide by single digit
  4224. ulong rem = 0;
  4225. var v0 = v[0];
  4226. q = new uint[m];
  4227. r = new uint[1];
  4228. for (var j = m - 1; j >= 0; j--)
  4229. {
  4230. rem *= Base;
  4231. rem += u[j];
  4232. var div = rem / v0;
  4233. rem -= div * v0;
  4234. q[j] = (uint)div;
  4235. }
  4236. r[0] = (uint)rem;
  4237. }
  4238. else if (m >= n)
  4239. {
  4240. var shift = GetNormalizeShift(v[n - 1]);
  4241. var un = new uint[m + 1];
  4242. var vn = new uint[n];
  4243. Normalize(u, m, un, shift);
  4244. Normalize(v, n, vn, shift);
  4245. q = new uint[m - n + 1];
  4246. // Main division loop
  4247. for (var j = m - n; j >= 0; j--)
  4248. {
  4249. int i;
  4250. var rr = (Base * un[j + n]) + un[j + n - 1];
  4251. var qq = rr / vn[n - 1];
  4252. rr -= qq * vn[n - 1];
  4253. for (; ; )
  4254. {
  4255. // Estimate too big ?
  4256. if ((qq >= Base) || (qq * vn[n - 2] > ((rr * Base) + un[j + n - 2])))
  4257. {
  4258. qq--;
  4259. rr += (ulong)vn[n - 1];
  4260. if (rr < Base)
  4261. {
  4262. continue;
  4263. }
  4264. }
  4265. break;
  4266. }
  4267. // Multiply and subtract
  4268. long b = 0;
  4269. long t;
  4270. for (i = 0; i < n; i++)
  4271. {
  4272. var p = vn[i] * qq;
  4273. t = (long)un[i + j] - (long)(uint)p - b;
  4274. un[i + j] = (uint)t;
  4275. p >>= 32;
  4276. t >>= 32;
  4277. b = (long)p - t;
  4278. }
  4279. t = (long)un[j + n] - b;
  4280. un[j + n] = (uint)t;
  4281. // Store the calculated value
  4282. q[j] = (uint)qq;
  4283. // Add back vn[0..n] to un[j..j+n]
  4284. if (t < 0)
  4285. {
  4286. q[j]--;
  4287. ulong c = 0;
  4288. for (i = 0; i < n; i++)
  4289. {
  4290. c = (ulong)vn[i] + un[j + i] + c;
  4291. un[j + i] = (uint)c;
  4292. c >>= 32;
  4293. }
  4294. c += (ulong)un[j + n];
  4295. un[j + n] = (uint)c;
  4296. }
  4297. }
  4298. Unnormalize(un, out r, shift);
  4299. }
  4300. else
  4301. {
  4302. q = new uint[] { 0 };
  4303. r = u;
  4304. }
  4305. }
  4306. }
  4307. }