2
0

BigInteger.cs 150 KB

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