BigInteger.cs 125 KB

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