ttmathuint.h 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126
  1. /*
  2. * This file is a part of TTMath Bignum Library
  3. * and is distributed under the (new) BSD licence.
  4. * Author: Tomasz Sowa <[email protected]>
  5. */
  6. /*
  7. * Copyright (c) 2006-2011, Tomasz Sowa
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * * Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. *
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * * Neither the name Tomasz Sowa nor the names of contributors to this
  21. * project may be used to endorse or promote products derived
  22. * from this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  34. * THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #ifndef headerfilettmathuint
  37. #define headerfilettmathuint
  38. /*!
  39. \file ttmathuint.h
  40. \brief template class UInt<uint>
  41. */
  42. #include <iostream>
  43. #include <iomanip>
  44. #include "ttmathtypes.h"
  45. #include "ttmathmisc.h"
  46. /*!
  47. \brief a namespace for the TTMath library
  48. */
  49. namespace ttmath
  50. {
  51. /*!
  52. \brief UInt implements a big integer value without a sign
  53. value_size - how many bytes specify our value
  54. on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
  55. on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
  56. value_size = 1,2,3,4,5,6....
  57. */
  58. template<uint value_size>
  59. class UInt
  60. {
  61. public:
  62. /*!
  63. buffer for the integer value
  64. table[0] - the lowest word of the value
  65. */
  66. uint table[value_size];
  67. /*!
  68. some methods used for debugging purposes
  69. */
  70. /*!
  71. this method is used when macro TTMATH_DEBUG_LOG is defined
  72. */
  73. template<class char_type, class ostream_type>
  74. static void PrintVectorLog(const char_type * msg, ostream_type & output, const uint * vector, uint vector_len)
  75. {
  76. output << msg << std::endl;
  77. for(uint i=0 ; i<vector_len ; ++i)
  78. output << " table[" << i << "]: " << vector[i] << std::endl;
  79. }
  80. /*!
  81. this method is used when macro TTMATH_DEBUG_LOG is defined
  82. */
  83. template<class char_type, class ostream_type>
  84. static void PrintVectorLog(const char_type * msg, uint carry, ostream_type & output, const uint * vector, uint vector_len)
  85. {
  86. PrintVectorLog(msg, output, vector, vector_len);
  87. output << " carry: " << carry << std::endl;
  88. }
  89. /*!
  90. this method is used when macro TTMATH_DEBUG_LOG is defined
  91. */
  92. template<class char_type, class ostream_type>
  93. void PrintLog(const char_type * msg, ostream_type & output) const
  94. {
  95. PrintVectorLog(msg, output, table, value_size);
  96. }
  97. /*!
  98. this method is used when macro TTMATH_DEBUG_LOG is defined
  99. */
  100. template<class char_type, class ostream_type>
  101. void PrintLog(const char_type * msg, uint carry, ostream_type & output) const
  102. {
  103. PrintVectorLog(msg, output, table, value_size);
  104. output << " carry: " << carry << std::endl;
  105. }
  106. /*!
  107. this method returns the size of the table
  108. */
  109. uint Size() const
  110. {
  111. return value_size;
  112. }
  113. /*!
  114. this method sets zero
  115. */
  116. void SetZero()
  117. {
  118. // in the future here can be 'memset'
  119. for(uint i=0 ; i<value_size ; ++i)
  120. table[i] = 0;
  121. TTMATH_LOG("UInt::SetZero")
  122. }
  123. /*!
  124. this method sets one
  125. */
  126. void SetOne()
  127. {
  128. SetZero();
  129. table[0] = 1;
  130. TTMATH_LOG("UInt::SetOne")
  131. }
  132. /*!
  133. this method sets the max value which this class can hold
  134. (all bits will be one)
  135. */
  136. void SetMax()
  137. {
  138. for(uint i=0 ; i<value_size ; ++i)
  139. table[i] = TTMATH_UINT_MAX_VALUE;
  140. TTMATH_LOG("UInt::SetMax")
  141. }
  142. /*!
  143. this method sets the min value which this class can hold
  144. (for an unsigned integer value the zero is the smallest value)
  145. */
  146. void SetMin()
  147. {
  148. SetZero();
  149. TTMATH_LOG("UInt::SetMin")
  150. }
  151. /*!
  152. this method swappes this for an argument
  153. */
  154. void Swap(UInt<value_size> & ss2)
  155. {
  156. for(uint i=0 ; i<value_size ; ++i)
  157. {
  158. uint temp = table[i];
  159. table[i] = ss2.table[i];
  160. ss2.table[i] = temp;
  161. }
  162. }
  163. #ifdef TTMATH_PLATFORM32
  164. /*!
  165. this method copies the value stored in an another table
  166. (warning: first values in temp_table are the highest words -- it's different
  167. from our table)
  168. we copy as many words as it is possible
  169. if temp_table_len is bigger than value_size we'll try to round
  170. the lowest word from table depending on the last not used bit in temp_table
  171. (this rounding isn't a perfect rounding -- look at the description below)
  172. and if temp_table_len is smaller than value_size we'll clear the rest words
  173. in the table
  174. */
  175. void SetFromTable(const uint * temp_table, uint temp_table_len)
  176. {
  177. uint temp_table_index = 0;
  178. sint i; // 'i' with a sign
  179. for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
  180. table[i] = temp_table[ temp_table_index ];
  181. // rounding mantissa
  182. if( temp_table_index < temp_table_len )
  183. {
  184. if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
  185. {
  186. /*
  187. very simply rounding
  188. if the bit from not used last word from temp_table is set to one
  189. we're rouding the lowest word in the table
  190. in fact there should be a normal addition but
  191. we don't use Add() or AddTwoInts() because these methods
  192. can set a carry and then there'll be a small problem
  193. for optimization
  194. */
  195. if( table[0] != TTMATH_UINT_MAX_VALUE )
  196. ++table[0];
  197. }
  198. }
  199. // cleaning the rest of the mantissa
  200. for( ; i>=0 ; --i)
  201. table[i] = 0;
  202. TTMATH_LOG("UInt::SetFromTable")
  203. }
  204. #endif
  205. #ifdef TTMATH_PLATFORM64
  206. /*!
  207. this method copies the value stored in an another table
  208. (warning: first values in temp_table are the highest words -- it's different
  209. from our table)
  210. ***this method is created only on a 64bit platform***
  211. we copy as many words as it is possible
  212. if temp_table_len is bigger than value_size we'll try to round
  213. the lowest word from table depending on the last not used bit in temp_table
  214. (this rounding isn't a perfect rounding -- look at the description below)
  215. and if temp_table_len is smaller than value_size we'll clear the rest words
  216. in the table
  217. warning: we're using 'temp_table' as a pointer at 32bit words
  218. */
  219. void SetFromTable(const unsigned int * temp_table, uint temp_table_len)
  220. {
  221. uint temp_table_index = 0;
  222. sint i; // 'i' with a sign
  223. for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
  224. {
  225. table[i] = uint(temp_table[ temp_table_index ]) << 32;
  226. ++temp_table_index;
  227. if( temp_table_index<temp_table_len )
  228. table[i] |= temp_table[ temp_table_index ];
  229. }
  230. // rounding mantissa
  231. if( temp_table_index < temp_table_len )
  232. {
  233. if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
  234. {
  235. /*
  236. very simply rounding
  237. if the bit from not used last word from temp_table is set to one
  238. we're rouding the lowest word in the table
  239. in fact there should be a normal addition but
  240. we don't use Add() or AddTwoInts() because these methods
  241. can set a carry and then there'll be a small problem
  242. for optimization
  243. */
  244. if( table[0] != TTMATH_UINT_MAX_VALUE )
  245. ++table[0];
  246. }
  247. }
  248. // cleaning the rest of the mantissa
  249. for( ; i >= 0 ; --i)
  250. table[i] = 0;
  251. TTMATH_LOG("UInt::SetFromTable")
  252. }
  253. #endif
  254. /*!
  255. *
  256. * basic mathematic functions
  257. *
  258. */
  259. /*!
  260. this method adds one to the existing value
  261. */
  262. uint AddOne()
  263. {
  264. return AddInt(1);
  265. }
  266. /*!
  267. this method subtracts one from the existing value
  268. */
  269. uint SubOne()
  270. {
  271. return SubInt(1);
  272. }
  273. private:
  274. /*!
  275. an auxiliary method for moving bits into the left hand side
  276. this method moves only words
  277. */
  278. void RclMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
  279. {
  280. rest_bits = bits % TTMATH_BITS_PER_UINT;
  281. uint all_words = bits / TTMATH_BITS_PER_UINT;
  282. uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
  283. if( all_words >= value_size )
  284. {
  285. if( all_words == value_size && rest_bits == 0 )
  286. last_c = table[0] & 1;
  287. // else: last_c is default set to 0
  288. // clearing
  289. for(uint i = 0 ; i<value_size ; ++i)
  290. table[i] = mask;
  291. rest_bits = 0;
  292. }
  293. else
  294. if( all_words > 0 )
  295. {
  296. // 0 < all_words < value_size
  297. sint first, second;
  298. last_c = table[value_size - all_words] & 1; // all_words is greater than 0
  299. // copying the first part of the value
  300. for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
  301. table[first] = table[second];
  302. // setting the rest to 'c'
  303. for( ; first>=0 ; --first )
  304. table[first] = mask;
  305. }
  306. TTMATH_LOG("UInt::RclMoveAllWords")
  307. }
  308. public:
  309. /*!
  310. moving all bits into the left side 'bits' times
  311. return value <- this <- C
  312. bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
  313. or it can be even bigger then all bits will be set to 'c'
  314. the value c will be set into the lowest bits
  315. and the method returns state of the last moved bit
  316. */
  317. uint Rcl(uint bits, uint c=0)
  318. {
  319. uint last_c = 0;
  320. uint rest_bits = bits;
  321. if( bits == 0 )
  322. return 0;
  323. if( bits >= TTMATH_BITS_PER_UINT )
  324. RclMoveAllWords(rest_bits, last_c, bits, c);
  325. if( rest_bits == 0 )
  326. {
  327. TTMATH_LOG("UInt::Rcl")
  328. return last_c;
  329. }
  330. // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
  331. if( rest_bits == 1 )
  332. {
  333. last_c = Rcl2_one(c);
  334. }
  335. else if( rest_bits == 2 )
  336. {
  337. // performance tests showed that for rest_bits==2 it's better to use Rcl2_one twice instead of Rcl2(2,c)
  338. Rcl2_one(c);
  339. last_c = Rcl2_one(c);
  340. }
  341. else
  342. {
  343. last_c = Rcl2(rest_bits, c);
  344. }
  345. TTMATH_LOGC("UInt::Rcl", last_c)
  346. return last_c;
  347. }
  348. private:
  349. /*!
  350. an auxiliary method for moving bits into the right hand side
  351. this method moves only words
  352. */
  353. void RcrMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
  354. {
  355. rest_bits = bits % TTMATH_BITS_PER_UINT;
  356. uint all_words = bits / TTMATH_BITS_PER_UINT;
  357. uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
  358. if( all_words >= value_size )
  359. {
  360. if( all_words == value_size && rest_bits == 0 )
  361. last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
  362. // else: last_c is default set to 0
  363. // clearing
  364. for(uint i = 0 ; i<value_size ; ++i)
  365. table[i] = mask;
  366. rest_bits = 0;
  367. }
  368. else if( all_words > 0 )
  369. {
  370. // 0 < all_words < value_size
  371. uint first, second;
  372. last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
  373. // copying the first part of the value
  374. for(first=0, second=all_words ; second<value_size ; ++first, ++second)
  375. table[first] = table[second];
  376. // setting the rest to 'c'
  377. for( ; first<value_size ; ++first )
  378. table[first] = mask;
  379. }
  380. TTMATH_LOG("UInt::RcrMoveAllWords")
  381. }
  382. public:
  383. /*!
  384. moving all bits into the right side 'bits' times
  385. c -> this -> return value
  386. bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
  387. or it can be even bigger then all bits will be set to 'c'
  388. the value c will be set into the highest bits
  389. and the method returns state of the last moved bit
  390. */
  391. uint Rcr(uint bits, uint c=0)
  392. {
  393. uint last_c = 0;
  394. uint rest_bits = bits;
  395. if( bits == 0 )
  396. return 0;
  397. if( bits >= TTMATH_BITS_PER_UINT )
  398. RcrMoveAllWords(rest_bits, last_c, bits, c);
  399. if( rest_bits == 0 )
  400. {
  401. TTMATH_LOG("UInt::Rcr")
  402. return last_c;
  403. }
  404. // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
  405. if( rest_bits == 1 )
  406. {
  407. last_c = Rcr2_one(c);
  408. }
  409. else if( rest_bits == 2 )
  410. {
  411. // performance tests showed that for rest_bits==2 it's better to use Rcr2_one twice instead of Rcr2(2,c)
  412. Rcr2_one(c);
  413. last_c = Rcr2_one(c);
  414. }
  415. else
  416. {
  417. last_c = Rcr2(rest_bits, c);
  418. }
  419. TTMATH_LOGC("UInt::Rcr", last_c)
  420. return last_c;
  421. }
  422. /*!
  423. this method moves all bits into the left side
  424. (it returns value how many bits have been moved)
  425. */
  426. uint CompensationToLeft()
  427. {
  428. uint moving = 0;
  429. // a - index a last word which is different from zero
  430. sint a;
  431. for(a=value_size-1 ; a>=0 && table[a]==0 ; --a);
  432. if( a < 0 )
  433. return moving; // all words in table have zero
  434. if( a != value_size-1 )
  435. {
  436. moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT;
  437. // moving all words
  438. sint i;
  439. for(i=value_size-1 ; a>=0 ; --i, --a)
  440. table[i] = table[a];
  441. // setting the rest word to zero
  442. for(; i>=0 ; --i)
  443. table[i] = 0;
  444. }
  445. uint moving2 = FindLeadingBitInWord( table[value_size-1] );
  446. // moving2 is different from -1 because the value table[value_size-1]
  447. // is not zero
  448. moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
  449. Rcl(moving2);
  450. TTMATH_LOG("UInt::CompensationToLeft")
  451. return moving + moving2;
  452. }
  453. /*!
  454. this method looks for the highest set bit
  455. result:
  456. if 'this' is not zero:
  457. return value - true
  458. 'table_id' - the index of a word <0..value_size-1>
  459. 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
  460. if 'this' is zero:
  461. return value - false
  462. both 'table_id' and 'index' are zero
  463. */
  464. bool FindLeadingBit(uint & table_id, uint & index) const
  465. {
  466. for(table_id=value_size-1 ; table_id!=0 && table[table_id]==0 ; --table_id);
  467. if( table_id==0 && table[table_id]==0 )
  468. {
  469. // is zero
  470. index = 0;
  471. return false;
  472. }
  473. // table[table_id] is different from 0
  474. index = FindLeadingBitInWord( table[table_id] );
  475. return true;
  476. }
  477. /*!
  478. this method looks for the smallest set bit
  479. result:
  480. if 'this' is not zero:
  481. return value - true
  482. 'table_id' - the index of a word <0..value_size-1>
  483. 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
  484. if 'this' is zero:
  485. return value - false
  486. both 'table_id' and 'index' are zero
  487. */
  488. bool FindLowestBit(uint & table_id, uint & index) const
  489. {
  490. for(table_id=0 ; table_id<value_size && table[table_id]==0 ; ++table_id);
  491. if( table_id >= value_size )
  492. {
  493. // is zero
  494. index = 0;
  495. table_id = 0;
  496. return false;
  497. }
  498. // table[table_id] is different from 0
  499. index = FindLowestBitInWord( table[table_id] );
  500. return true;
  501. }
  502. /*!
  503. getting the 'bit_index' bit
  504. bit_index bigger or equal zero
  505. */
  506. uint GetBit(uint bit_index) const
  507. {
  508. TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
  509. uint index = bit_index / TTMATH_BITS_PER_UINT;
  510. uint bit = bit_index % TTMATH_BITS_PER_UINT;
  511. uint temp = table[index];
  512. uint res = SetBitInWord(temp, bit);
  513. return res;
  514. }
  515. /*!
  516. setting the 'bit_index' bit
  517. and returning the last state of the bit
  518. bit_index bigger or equal zero
  519. */
  520. uint SetBit(uint bit_index)
  521. {
  522. TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
  523. uint index = bit_index / TTMATH_BITS_PER_UINT;
  524. uint bit = bit_index % TTMATH_BITS_PER_UINT;
  525. uint res = SetBitInWord(table[index], bit);
  526. TTMATH_LOG("UInt::SetBit")
  527. return res;
  528. }
  529. /*!
  530. this method performs a bitwise operation AND
  531. */
  532. void BitAnd(const UInt<value_size> & ss2)
  533. {
  534. for(uint x=0 ; x<value_size ; ++x)
  535. table[x] &= ss2.table[x];
  536. TTMATH_LOG("UInt::BitAnd")
  537. }
  538. /*!
  539. this method performs a bitwise operation OR
  540. */
  541. void BitOr(const UInt<value_size> & ss2)
  542. {
  543. for(uint x=0 ; x<value_size ; ++x)
  544. table[x] |= ss2.table[x];
  545. TTMATH_LOG("UInt::BitOr")
  546. }
  547. /*!
  548. this method performs a bitwise operation XOR
  549. */
  550. void BitXor(const UInt<value_size> & ss2)
  551. {
  552. for(uint x=0 ; x<value_size ; ++x)
  553. table[x] ^= ss2.table[x];
  554. TTMATH_LOG("UInt::BitXor")
  555. }
  556. /*!
  557. this method performs a bitwise operation NOT
  558. */
  559. void BitNot()
  560. {
  561. for(uint x=0 ; x<value_size ; ++x)
  562. table[x] = ~table[x];
  563. TTMATH_LOG("UInt::BitNot")
  564. }
  565. /*!
  566. this method performs a bitwise operation NOT but only
  567. on the range of <0, leading_bit>
  568. for example:
  569. BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7
  570. */
  571. void BitNot2()
  572. {
  573. uint table_id, index;
  574. if( FindLeadingBit(table_id, index) )
  575. {
  576. for(uint x=0 ; x<table_id ; ++x)
  577. table[x] = ~table[x];
  578. uint mask = TTMATH_UINT_MAX_VALUE;
  579. uint shift = TTMATH_BITS_PER_UINT - index - 1;
  580. if(shift)
  581. mask >>= shift;
  582. table[table_id] ^= mask;
  583. }
  584. else
  585. table[0] = 1;
  586. TTMATH_LOG("UInt::BitNot2")
  587. }
  588. /*!
  589. *
  590. * Multiplication
  591. *
  592. *
  593. */
  594. public:
  595. /*!
  596. multiplication: this = this * ss2
  597. it can return a carry
  598. */
  599. uint MulInt(uint ss2)
  600. {
  601. uint r1, r2, x1;
  602. uint c = 0;
  603. UInt<value_size> u(*this);
  604. SetZero();
  605. if( ss2 == 0 )
  606. {
  607. TTMATH_LOGC("UInt::MulInt(uint)", 0)
  608. return 0;
  609. }
  610. for(x1=0 ; x1<value_size-1 ; ++x1)
  611. {
  612. MulTwoWords(u.table[x1], ss2, &r2, &r1);
  613. c += AddTwoInts(r2,r1,x1);
  614. }
  615. // x1 = value_size-1 (last word)
  616. MulTwoWords(u.table[x1], ss2, &r2, &r1);
  617. c += (r2!=0) ? 1 : 0;
  618. c += AddInt(r1, x1);
  619. TTMATH_LOGC("UInt::MulInt(uint)", c)
  620. return (c==0)? 0 : 1;
  621. }
  622. /*!
  623. multiplication: result = this * ss2
  624. we're using this method only when result_size is greater than value_size
  625. if so there will not be a carry
  626. */
  627. template<uint result_size>
  628. void MulInt(uint ss2, UInt<result_size> & result) const
  629. {
  630. TTMATH_ASSERT( result_size > value_size )
  631. uint r2,r1;
  632. uint x1size=value_size;
  633. uint x1start=0;
  634. result.SetZero();
  635. if( ss2 == 0 )
  636. {
  637. TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
  638. return;
  639. }
  640. if( value_size > 2 )
  641. {
  642. // if the value_size is smaller than or equal to 2
  643. // there is no sense to set x1size and x1start to another values
  644. for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
  645. if( x1size == 0 )
  646. {
  647. TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
  648. return;
  649. }
  650. for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
  651. }
  652. for(uint x1=x1start ; x1<x1size ; ++x1)
  653. {
  654. MulTwoWords(table[x1], ss2, &r2, &r1 );
  655. result.AddTwoInts(r2,r1,x1);
  656. }
  657. TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
  658. return;
  659. }
  660. /*!
  661. the multiplication 'this' = 'this' * ss2
  662. algorithm: 100 - means automatically choose the fastest algorithm
  663. */
  664. uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
  665. {
  666. switch( algorithm )
  667. {
  668. case 1:
  669. return Mul1(ss2);
  670. case 2:
  671. return Mul2(ss2);
  672. case 3:
  673. return Mul3(ss2);
  674. case 100:
  675. default:
  676. return MulFastest(ss2);
  677. }
  678. }
  679. /*!
  680. the multiplication 'result' = 'this' * ss2
  681. since the 'result' is twice bigger than 'this' and 'ss2'
  682. this method never returns a carry
  683. algorithm: 100 - means automatically choose the fastest algorithm
  684. */
  685. void MulBig(const UInt<value_size> & ss2,
  686. UInt<value_size*2> & result,
  687. uint algorithm = 100)
  688. {
  689. switch( algorithm )
  690. {
  691. case 1:
  692. return Mul1Big(ss2, result);
  693. case 2:
  694. return Mul2Big(ss2, result);
  695. case 3:
  696. return Mul3Big(ss2, result);
  697. case 100:
  698. default:
  699. return MulFastestBig(ss2, result);
  700. }
  701. }
  702. /*!
  703. the first version of the multiplication algorithm
  704. */
  705. private:
  706. /*!
  707. multiplication: this = this * ss2
  708. it returns carry if it has been
  709. */
  710. uint Mul1Ref(const UInt<value_size> & ss2)
  711. {
  712. TTMATH_REFERENCE_ASSERT( ss2 )
  713. UInt<value_size> ss1( *this );
  714. SetZero();
  715. for(uint i=0; i < value_size*TTMATH_BITS_PER_UINT ; ++i)
  716. {
  717. if( Add(*this) )
  718. {
  719. TTMATH_LOGC("UInt::Mul1", 1)
  720. return 1;
  721. }
  722. if( ss1.Rcl(1) )
  723. if( Add(ss2) )
  724. {
  725. TTMATH_LOGC("UInt::Mul1", 1)
  726. return 1;
  727. }
  728. }
  729. TTMATH_LOGC("UInt::Mul1", 0)
  730. return 0;
  731. }
  732. public:
  733. /*!
  734. multiplication: this = this * ss2
  735. can return carry
  736. */
  737. uint Mul1(const UInt<value_size> & ss2)
  738. {
  739. if( this == &ss2 )
  740. {
  741. UInt<value_size> copy_ss2(ss2);
  742. return Mul1Ref(copy_ss2);
  743. }
  744. else
  745. {
  746. return Mul1Ref(ss2);
  747. }
  748. }
  749. /*!
  750. multiplication: result = this * ss2
  751. result is twice bigger than 'this' and 'ss2'
  752. this method never returns carry
  753. */
  754. void Mul1Big(const UInt<value_size> & ss2_, UInt<value_size*2> & result)
  755. {
  756. UInt<value_size*2> ss2;
  757. uint i;
  758. // copying *this into result and ss2_ into ss2
  759. for(i=0 ; i<value_size ; ++i)
  760. {
  761. result.table[i] = table[i];
  762. ss2.table[i] = ss2_.table[i];
  763. }
  764. // cleaning the highest bytes in result and ss2
  765. for( ; i < value_size*2 ; ++i)
  766. {
  767. result.table[i] = 0;
  768. ss2.table[i] = 0;
  769. }
  770. // multiply
  771. // (there will not be a carry)
  772. result.Mul1( ss2 );
  773. TTMATH_LOG("UInt::Mul1Big")
  774. }
  775. /*!
  776. the second version of the multiplication algorithm
  777. this algorithm is similar to the 'schoolbook method' which is done by hand
  778. */
  779. /*!
  780. multiplication: this = this * ss2
  781. it returns carry if it has been
  782. */
  783. uint Mul2(const UInt<value_size> & ss2)
  784. {
  785. UInt<value_size*2> result;
  786. uint i, c = 0;
  787. Mul2Big(ss2, result);
  788. // copying result
  789. for(i=0 ; i<value_size ; ++i)
  790. table[i] = result.table[i];
  791. // testing carry
  792. for( ; i<value_size*2 ; ++i)
  793. if( result.table[i] != 0 )
  794. {
  795. c = 1;
  796. break;
  797. }
  798. TTMATH_LOGC("UInt::Mul2", c)
  799. return c;
  800. }
  801. /*!
  802. multiplication: result = this * ss2
  803. result is twice bigger than this and ss2
  804. this method never returns carry
  805. */
  806. void Mul2Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
  807. {
  808. Mul2Big2<value_size>(table, ss2.table, result);
  809. TTMATH_LOG("UInt::Mul2Big")
  810. }
  811. private:
  812. /*!
  813. an auxiliary method for calculating the multiplication
  814. arguments we're taking as pointers (this is to improve the Mul3Big2()- avoiding
  815. unnecessary copying objects), the result should be taken as a pointer too,
  816. but at the moment there is no method AddTwoInts() which can operate on pointers
  817. */
  818. template<uint ss_size>
  819. void Mul2Big2(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result)
  820. {
  821. uint x1size = ss_size, x2size = ss_size;
  822. uint x1start = 0, x2start = 0;
  823. if( ss_size > 2 )
  824. {
  825. // if the ss_size is smaller than or equal to 2
  826. // there is no sense to set x1size (and others) to another values
  827. for(x1size=ss_size ; x1size>0 && ss1[x1size-1]==0 ; --x1size);
  828. for(x2size=ss_size ; x2size>0 && ss2[x2size-1]==0 ; --x2size);
  829. for(x1start=0 ; x1start<x1size && ss1[x1start]==0 ; ++x1start);
  830. for(x2start=0 ; x2start<x2size && ss2[x2start]==0 ; ++x2start);
  831. }
  832. Mul2Big3<ss_size>(ss1, ss2, result, x1start, x1size, x2start, x2size);
  833. }
  834. /*!
  835. an auxiliary method for calculating the multiplication
  836. */
  837. template<uint ss_size>
  838. void Mul2Big3(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result, uint x1start, uint x1size, uint x2start, uint x2size)
  839. {
  840. uint r2, r1;
  841. result.SetZero();
  842. if( x1size==0 || x2size==0 )
  843. return;
  844. for(uint x1=x1start ; x1<x1size ; ++x1)
  845. {
  846. for(uint x2=x2start ; x2<x2size ; ++x2)
  847. {
  848. MulTwoWords(ss1[x1], ss2[x2], &r2, &r1);
  849. result.AddTwoInts(r2, r1, x2+x1);
  850. // here will never be a carry
  851. }
  852. }
  853. }
  854. public:
  855. /*!
  856. multiplication: this = this * ss2
  857. This is Karatsuba Multiplication algorithm, we're using it when value_size is greater than
  858. or equal to TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE macro (defined in ttmathuint.h).
  859. If value_size is smaller then we're using Mul2Big() instead.
  860. Karatsuba multiplication:
  861. Assume we have:
  862. this = x = x1*B^m + x0
  863. ss2 = y = y1*B^m + y0
  864. where x0 and y0 are less than B^m
  865. the product from multiplication we can show as:
  866. x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
  867. where
  868. z2 = x1*y1
  869. z1 = x1*y0 + x0*y1
  870. z0 = x0*y0
  871. this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form:
  872. z1 = (x1 + x0)*(y1 + y0) - z2 - z0 / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 /
  873. and to calculate the multiplication we need only three multiplications (with some additions and subtractions)
  874. Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication.
  875. Karatsuba multiplication has O( n^(ln(3)/ln(2)) )
  876. */
  877. uint Mul3(const UInt<value_size> & ss2)
  878. {
  879. UInt<value_size*2> result;
  880. uint i, c = 0;
  881. Mul3Big(ss2, result);
  882. // copying result
  883. for(i=0 ; i<value_size ; ++i)
  884. table[i] = result.table[i];
  885. // testing carry
  886. for( ; i<value_size*2 ; ++i)
  887. if( result.table[i] != 0 )
  888. {
  889. c = 1;
  890. break;
  891. }
  892. TTMATH_LOGC("UInt::Mul3", c)
  893. return c;
  894. }
  895. /*!
  896. multiplication: result = this * ss2
  897. result is twice bigger than this and ss2,
  898. this method never returns carry,
  899. (Karatsuba multiplication)
  900. */
  901. void Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
  902. {
  903. Mul3Big2<value_size>(table, ss2.table, result.table);
  904. TTMATH_LOG("UInt::Mul3Big")
  905. }
  906. private:
  907. /*!
  908. an auxiliary method for calculating the Karatsuba multiplication
  909. result_size is equal ss_size*2
  910. */
  911. template<uint ss_size>
  912. void Mul3Big2(const uint * ss1, const uint * ss2, uint * result)
  913. {
  914. const uint * x1, * x0, * y1, * y0;
  915. if( ss_size>1 && ss_size<TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
  916. {
  917. UInt<ss_size*2> res;
  918. Mul2Big2<ss_size>(ss1, ss2, res);
  919. #ifdef __clang__
  920. #pragma clang diagnostic push
  921. #pragma clang diagnostic ignored "-Wtautological-compare"
  922. #endif
  923. for(uint i=0 ; i<ss_size*2 ; ++i)
  924. result[i] = res.table[i];
  925. #ifdef __clang__
  926. #pragma clang diagnostic pop
  927. #endif
  928. return;
  929. }
  930. else
  931. if( ss_size == 1 )
  932. {
  933. return MulTwoWords(*ss1, *ss2, &result[1], &result[0]);
  934. }
  935. if( (ss_size & 1) == 1 )
  936. {
  937. // ss_size is odd
  938. x0 = ss1;
  939. y0 = ss2;
  940. x1 = ss1 + ss_size / 2 + 1;
  941. y1 = ss2 + ss_size / 2 + 1;
  942. // the second vectors (x1 and y1) are smaller about one from the first ones (x0 and y0)
  943. Mul3Big3<ss_size/2 + 1, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
  944. }
  945. else
  946. {
  947. // ss_size is even
  948. x0 = ss1;
  949. y0 = ss2;
  950. x1 = ss1 + ss_size / 2;
  951. y1 = ss2 + ss_size / 2;
  952. // all four vectors (x0 x1 y0 y1) are equal in size
  953. Mul3Big3<ss_size/2, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
  954. }
  955. }
  956. #ifdef _MSC_VER
  957. #pragma warning (disable : 4717)
  958. //warning C4717: recursive on all control paths, function will cause runtime stack overflow
  959. //we have the stop point in Mul3Big2() method
  960. #endif
  961. /*!
  962. an auxiliary method for calculating the Karatsuba multiplication
  963. x = x1*B^m + x0
  964. y = y1*B^m + y0
  965. first_size - is the size of vectors: x0 and y0
  966. second_size - is the size of vectors: x1 and y1 (can be either equal first_size or smaller about one from first_size)
  967. x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
  968. where
  969. z0 = x0*y0
  970. z2 = x1*y1
  971. z1 = (x1 + x0)*(y1 + y0) - z2 - z0
  972. */
  973. template<uint first_size, uint second_size, uint result_size>
  974. uint Mul3Big3(const uint * x1, const uint * x0, const uint * y1, const uint * y0, uint * result)
  975. {
  976. uint i, c, xc, yc;
  977. UInt<first_size> temp, temp2;
  978. UInt<first_size*3> z1;
  979. // z0 and z2 we store directly in the result (we don't use any temporary variables)
  980. Mul3Big2<first_size>(x0, y0, result); // z0
  981. Mul3Big2<second_size>(x1, y1, result+first_size*2); // z2
  982. // now we calculate z1
  983. // temp = (x0 + x1)
  984. // temp2 = (y0 + y1)
  985. // we're using temp and temp2 with UInt<first_size>, although there can be a carry but
  986. // we simple remember it in xc and yc (xc and yc can be either 0 or 1),
  987. // and (x0 + x1)*(y0 + y1) we calculate in this way (schoolbook algorithm):
  988. //
  989. // xc | temp
  990. // yc | temp2
  991. // --------------------
  992. // (temp * temp2)
  993. // xc*temp2 |
  994. // yc*temp |
  995. // xc*yc |
  996. // ---------- z1 --------
  997. //
  998. // and the result is never larger in size than 3*first_size
  999. xc = AddVector(x0, x1, first_size, second_size, temp.table);
  1000. yc = AddVector(y0, y1, first_size, second_size, temp2.table);
  1001. Mul3Big2<first_size>(temp.table, temp2.table, z1.table);
  1002. #ifdef __clang__
  1003. #pragma clang diagnostic push
  1004. #pragma clang diagnostic ignored "-Wtautological-compare"
  1005. #endif
  1006. // clearing the rest of z1
  1007. for(i=first_size*2 ; i<first_size*3 ; ++i)
  1008. z1.table[i] = 0;
  1009. #ifdef __clang__
  1010. #pragma clang diagnostic pop
  1011. #endif
  1012. if( xc )
  1013. {
  1014. c = AddVector(z1.table+first_size, temp2.table, first_size*3-first_size, first_size, z1.table+first_size);
  1015. TTMATH_ASSERT( c==0 )
  1016. }
  1017. if( yc )
  1018. {
  1019. c = AddVector(z1.table+first_size, temp.table, first_size*3-first_size, first_size, z1.table+first_size);
  1020. TTMATH_ASSERT( c==0 )
  1021. }
  1022. if( xc && yc )
  1023. {
  1024. #ifdef __clang__
  1025. #pragma clang diagnostic push
  1026. #pragma clang diagnostic ignored "-Wtautological-compare"
  1027. #endif
  1028. for( i=first_size*2 ; i<first_size*3 ; ++i )
  1029. if( ++z1.table[i] != 0 )
  1030. break; // break if there was no carry
  1031. #ifdef __clang__
  1032. #pragma clang diagnostic pop
  1033. #endif
  1034. }
  1035. // z1 = z1 - z2
  1036. c = SubVector(z1.table, result+first_size*2, first_size*3, second_size*2, z1.table);
  1037. TTMATH_ASSERT(c==0)
  1038. // z1 = z1 - z0
  1039. c = SubVector(z1.table, result, first_size*3, first_size*2, z1.table);
  1040. TTMATH_ASSERT(c==0)
  1041. // here we've calculated the z1
  1042. // now we're adding it to the result
  1043. if( first_size > second_size )
  1044. {
  1045. uint z1_size = result_size - first_size;
  1046. TTMATH_ASSERT( z1_size <= first_size*3 )
  1047. #ifdef __clang__
  1048. #pragma clang diagnostic push
  1049. #pragma clang diagnostic ignored "-Wtautological-compare"
  1050. #endif
  1051. for(i=z1_size ; i<first_size*3 ; ++i)
  1052. {
  1053. TTMATH_ASSERT( z1.table[i] == 0 )
  1054. }
  1055. #ifdef __clang__
  1056. #pragma clang diagnostic pop
  1057. #endif
  1058. c = AddVector(result+first_size, z1.table, result_size-first_size, z1_size, result+first_size);
  1059. TTMATH_ASSERT(c==0)
  1060. }
  1061. else
  1062. {
  1063. c = AddVector(result+first_size, z1.table, result_size-first_size, first_size*3, result+first_size);
  1064. TTMATH_ASSERT(c==0)
  1065. }
  1066. return c;
  1067. }
  1068. #ifdef _MSC_VER
  1069. #pragma warning (default : 4717)
  1070. #endif
  1071. public:
  1072. /*!
  1073. multiplication this = this * ss2
  1074. */
  1075. uint MulFastest(const UInt<value_size> & ss2)
  1076. {
  1077. UInt<value_size*2> result;
  1078. uint i, c = 0;
  1079. MulFastestBig(ss2, result);
  1080. // copying result
  1081. for(i=0 ; i<value_size ; ++i)
  1082. table[i] = result.table[i];
  1083. // testing carry
  1084. for( ; i<value_size*2 ; ++i)
  1085. if( result.table[i] != 0 )
  1086. {
  1087. c = 1;
  1088. break;
  1089. }
  1090. TTMATH_LOGC("UInt::MulFastest", c)
  1091. return c;
  1092. }
  1093. /*!
  1094. multiplication result = this * ss2
  1095. this method is trying to select the fastest algorithm
  1096. (in the future this method can be improved)
  1097. */
  1098. void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
  1099. {
  1100. if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
  1101. return Mul2Big(ss2, result);
  1102. uint x1size = value_size, x2size = value_size;
  1103. uint x1start = 0, x2start = 0;
  1104. for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
  1105. for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size);
  1106. if( x1size==0 || x2size==0 )
  1107. {
  1108. // either 'this' or 'ss2' is equal zero - the result is zero too
  1109. result.SetZero();
  1110. return;
  1111. }
  1112. for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
  1113. for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
  1114. uint distancex1 = x1size - x1start;
  1115. uint distancex2 = x2size - x2start;
  1116. if( distancex1 < 3 || distancex2 < 3 )
  1117. // either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
  1118. // (this condition in the future can be improved)
  1119. return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
  1120. // Karatsuba multiplication
  1121. Mul3Big(ss2, result);
  1122. TTMATH_LOG("UInt::MulFastestBig")
  1123. }
  1124. /*!
  1125. *
  1126. * Division
  1127. *
  1128. *
  1129. */
  1130. public:
  1131. /*!
  1132. division by one unsigned word
  1133. returns 1 when divisor is zero
  1134. */
  1135. uint DivInt(uint divisor, uint * remainder = 0)
  1136. {
  1137. if( divisor == 0 )
  1138. {
  1139. if( remainder )
  1140. *remainder = 0; // this is for convenience, without it the compiler can report that 'remainder' is uninitialized
  1141. TTMATH_LOG("UInt::DivInt")
  1142. return 1;
  1143. }
  1144. if( divisor == 1 )
  1145. {
  1146. if( remainder )
  1147. *remainder = 0;
  1148. TTMATH_LOG("UInt::DivInt")
  1149. return 0;
  1150. }
  1151. UInt<value_size> dividend(*this);
  1152. SetZero();
  1153. sint i; // i must be with a sign
  1154. uint r = 0;
  1155. // we're looking for the last word in ss1
  1156. for(i=value_size-1 ; i>0 && dividend.table[i]==0 ; --i);
  1157. for( ; i>=0 ; --i)
  1158. DivTwoWords(r, dividend.table[i], divisor, &table[i], &r);
  1159. if( remainder )
  1160. *remainder = r;
  1161. TTMATH_LOG("UInt::DivInt")
  1162. return 0;
  1163. }
  1164. uint DivInt(uint divisor, uint & remainder)
  1165. {
  1166. return DivInt(divisor, &remainder);
  1167. }
  1168. /*!
  1169. division this = this / ss2
  1170. return values:
  1171. 0 - ok
  1172. 1 - division by zero
  1173. 'this' will be the quotient
  1174. 'remainder' - remainder
  1175. */
  1176. uint Div( const UInt<value_size> & divisor,
  1177. UInt<value_size> * remainder = 0,
  1178. uint algorithm = 3)
  1179. {
  1180. switch( algorithm )
  1181. {
  1182. case 1:
  1183. return Div1(divisor, remainder);
  1184. case 2:
  1185. return Div2(divisor, remainder);
  1186. case 3:
  1187. default:
  1188. return Div3(divisor, remainder);
  1189. }
  1190. }
  1191. uint Div(const UInt<value_size> & divisor, UInt<value_size> & remainder, uint algorithm = 3)
  1192. {
  1193. return Div(divisor, &remainder, algorithm);
  1194. }
  1195. private:
  1196. /*!
  1197. return values:
  1198. 0 - none has to be done
  1199. 1 - division by zero
  1200. 2 - division should be made
  1201. */
  1202. uint Div_StandardTest( const UInt<value_size> & v,
  1203. uint & m, uint & n,
  1204. UInt<value_size> * remainder = 0)
  1205. {
  1206. switch( Div_CalculatingSize(v, m, n) )
  1207. {
  1208. case 4: // 'this' is equal v
  1209. if( remainder )
  1210. remainder->SetZero();
  1211. SetOne();
  1212. TTMATH_LOG("UInt::Div_StandardTest")
  1213. return 0;
  1214. case 3: // 'this' is smaller than v
  1215. if( remainder )
  1216. *remainder = *this;
  1217. SetZero();
  1218. TTMATH_LOG("UInt::Div_StandardTest")
  1219. return 0;
  1220. case 2: // 'this' is zero
  1221. if( remainder )
  1222. remainder->SetZero();
  1223. SetZero();
  1224. TTMATH_LOG("UInt::Div_StandardTest")
  1225. return 0;
  1226. case 1: // v is zero
  1227. TTMATH_LOG("UInt::Div_StandardTest")
  1228. return 1;
  1229. }
  1230. TTMATH_LOG("UInt::Div_StandardTest")
  1231. return 2;
  1232. }
  1233. /*!
  1234. return values:
  1235. 0 - ok
  1236. 'm' - is the index (from 0) of last non-zero word in table ('this')
  1237. 'n' - is the index (from 0) of last non-zero word in v.table
  1238. 1 - v is zero
  1239. 2 - 'this' is zero
  1240. 3 - 'this' is smaller than v
  1241. 4 - 'this' is equal v
  1242. if the return value is different than zero the 'm' and 'n' are undefined
  1243. */
  1244. uint Div_CalculatingSize(const UInt<value_size> & v, uint & m, uint & n)
  1245. {
  1246. m = n = value_size-1;
  1247. for( ; n!=0 && v.table[n]==0 ; --n);
  1248. if( n==0 && v.table[n]==0 )
  1249. return 1;
  1250. for( ; m!=0 && table[m]==0 ; --m);
  1251. if( m==0 && table[m]==0 )
  1252. return 2;
  1253. if( m < n )
  1254. return 3;
  1255. else
  1256. if( m == n )
  1257. {
  1258. uint i;
  1259. for(i = n ; i!=0 && table[i]==v.table[i] ; --i);
  1260. if( table[i] < v.table[i] )
  1261. return 3;
  1262. else
  1263. if (table[i] == v.table[i] )
  1264. return 4;
  1265. }
  1266. return 0;
  1267. }
  1268. public:
  1269. /*!
  1270. the first division algorithm
  1271. radix 2
  1272. */
  1273. uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
  1274. {
  1275. uint m,n, test;
  1276. test = Div_StandardTest(divisor, m, n, remainder);
  1277. if( test < 2 )
  1278. return test;
  1279. if( !remainder )
  1280. {
  1281. UInt<value_size> rem;
  1282. return Div1_Calculate(divisor, rem);
  1283. }
  1284. return Div1_Calculate(divisor, *remainder);
  1285. }
  1286. /*!
  1287. the first division algorithm
  1288. radix 2
  1289. */
  1290. uint Div1(const UInt<value_size> & divisor, UInt<value_size> & remainder)
  1291. {
  1292. return Div1(divisor, &remainder);
  1293. }
  1294. private:
  1295. uint Div1_Calculate(const UInt<value_size> & divisor, UInt<value_size> & rest)
  1296. {
  1297. if( this == &divisor )
  1298. {
  1299. UInt<value_size> divisor_copy(divisor);
  1300. return Div1_CalculateRef(divisor_copy, rest);
  1301. }
  1302. else
  1303. {
  1304. return Div1_CalculateRef(divisor, rest);
  1305. }
  1306. }
  1307. uint Div1_CalculateRef(const UInt<value_size> & divisor, UInt<value_size> & rest)
  1308. {
  1309. TTMATH_REFERENCE_ASSERT( divisor )
  1310. sint loop;
  1311. sint c;
  1312. rest.SetZero();
  1313. loop = value_size * TTMATH_BITS_PER_UINT;
  1314. c = 0;
  1315. div_a:
  1316. c = Rcl(1, c);
  1317. c = rest.Add(rest,c);
  1318. c = rest.Sub(divisor,c);
  1319. c = !c;
  1320. if(!c)
  1321. goto div_d;
  1322. div_b:
  1323. --loop;
  1324. if(loop)
  1325. goto div_a;
  1326. c = Rcl(1, c);
  1327. TTMATH_LOG("UInt::Div1_Calculate")
  1328. return 0;
  1329. div_c:
  1330. c = Rcl(1, c);
  1331. c = rest.Add(rest,c);
  1332. c = rest.Add(divisor);
  1333. if(c)
  1334. goto div_b;
  1335. div_d:
  1336. --loop;
  1337. if(loop)
  1338. goto div_c;
  1339. c = Rcl(1, c);
  1340. c = rest.Add(divisor);
  1341. TTMATH_LOG("UInt::Div1_Calculate")
  1342. return 0;
  1343. }
  1344. public:
  1345. /*!
  1346. the second division algorithm
  1347. return values:
  1348. 0 - ok
  1349. 1 - division by zero
  1350. */
  1351. uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
  1352. {
  1353. if( this == &divisor )
  1354. {
  1355. UInt<value_size> divisor_copy(divisor);
  1356. return Div2Ref(divisor_copy, remainder);
  1357. }
  1358. else
  1359. {
  1360. return Div2Ref(divisor, remainder);
  1361. }
  1362. }
  1363. /*!
  1364. the second division algorithm
  1365. return values:
  1366. 0 - ok
  1367. 1 - division by zero
  1368. */
  1369. uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
  1370. {
  1371. return Div2(divisor, &remainder);
  1372. }
  1373. private:
  1374. /*!
  1375. the second division algorithm
  1376. return values:
  1377. 0 - ok
  1378. 1 - division by zero
  1379. */
  1380. uint Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
  1381. {
  1382. uint bits_diff;
  1383. uint status = Div2_Calculate(divisor, remainder, bits_diff);
  1384. if( status < 2 )
  1385. return status;
  1386. if( CmpBiggerEqual(divisor) )
  1387. {
  1388. Div2(divisor, remainder);
  1389. SetBit(bits_diff);
  1390. }
  1391. else
  1392. {
  1393. if( remainder )
  1394. *remainder = *this;
  1395. SetZero();
  1396. SetBit(bits_diff);
  1397. }
  1398. TTMATH_LOG("UInt::Div2")
  1399. return 0;
  1400. }
  1401. /*!
  1402. return values:
  1403. 0 - we've calculated the division
  1404. 1 - division by zero
  1405. 2 - we have to still calculate
  1406. */
  1407. uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
  1408. uint & bits_diff)
  1409. {
  1410. uint table_id, index;
  1411. uint divisor_table_id, divisor_index;
  1412. uint status = Div2_FindLeadingBitsAndCheck( divisor, remainder,
  1413. table_id, index,
  1414. divisor_table_id, divisor_index);
  1415. if( status < 2 )
  1416. {
  1417. TTMATH_LOG("UInt::Div2_Calculate")
  1418. return status;
  1419. }
  1420. // here we know that 'this' is greater than divisor
  1421. // then 'index' is greater or equal 'divisor_index'
  1422. bits_diff = index - divisor_index;
  1423. UInt<value_size> divisor_copy(divisor);
  1424. divisor_copy.Rcl(bits_diff, 0);
  1425. if( CmpSmaller(divisor_copy, table_id) )
  1426. {
  1427. divisor_copy.Rcr(1);
  1428. --bits_diff;
  1429. }
  1430. Sub(divisor_copy, 0);
  1431. TTMATH_LOG("UInt::Div2_Calculate")
  1432. return 2;
  1433. }
  1434. /*!
  1435. return values:
  1436. 0 - we've calculated the division
  1437. 1 - division by zero
  1438. 2 - we have to still calculate
  1439. */
  1440. uint Div2_FindLeadingBitsAndCheck( const UInt<value_size> & divisor,
  1441. UInt<value_size> * remainder,
  1442. uint & table_id, uint & index,
  1443. uint & divisor_table_id, uint & divisor_index)
  1444. {
  1445. if( !divisor.FindLeadingBit(divisor_table_id, divisor_index) )
  1446. {
  1447. // division by zero
  1448. TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
  1449. return 1;
  1450. }
  1451. if( !FindLeadingBit(table_id, index) )
  1452. {
  1453. // zero is divided by something
  1454. SetZero();
  1455. if( remainder )
  1456. remainder->SetZero();
  1457. TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
  1458. return 0;
  1459. }
  1460. divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT;
  1461. index += table_id * TTMATH_BITS_PER_UINT;
  1462. if( divisor_table_id == 0 )
  1463. {
  1464. // dividor has only one 32-bit word
  1465. uint r;
  1466. DivInt(divisor.table[0], &r);
  1467. if( remainder )
  1468. {
  1469. remainder->SetZero();
  1470. remainder->table[0] = r;
  1471. }
  1472. TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
  1473. return 0;
  1474. }
  1475. if( Div2_DivisorGreaterOrEqual( divisor, remainder,
  1476. table_id, index,
  1477. divisor_index) )
  1478. {
  1479. TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
  1480. return 0;
  1481. }
  1482. TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
  1483. return 2;
  1484. }
  1485. /*!
  1486. return values:
  1487. true if divisor is equal or greater than 'this'
  1488. */
  1489. bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
  1490. UInt<value_size> * remainder,
  1491. uint table_id, uint index,
  1492. uint divisor_index )
  1493. {
  1494. if( divisor_index > index )
  1495. {
  1496. // divisor is greater than this
  1497. if( remainder )
  1498. *remainder = *this;
  1499. SetZero();
  1500. TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
  1501. return true;
  1502. }
  1503. if( divisor_index == index )
  1504. {
  1505. // table_id == divisor_table_id as well
  1506. uint i;
  1507. for(i = table_id ; i!=0 && table[i]==divisor.table[i] ; --i);
  1508. if( table[i] < divisor.table[i] )
  1509. {
  1510. // divisor is greater than 'this'
  1511. if( remainder )
  1512. *remainder = *this;
  1513. SetZero();
  1514. TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
  1515. return true;
  1516. }
  1517. else
  1518. if( table[i] == divisor.table[i] )
  1519. {
  1520. // divisor is equal 'this'
  1521. if( remainder )
  1522. remainder->SetZero();
  1523. SetOne();
  1524. TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
  1525. return true;
  1526. }
  1527. }
  1528. TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
  1529. return false;
  1530. }
  1531. public:
  1532. /*!
  1533. the third division algorithm
  1534. */
  1535. uint Div3(const UInt<value_size> & ss2, UInt<value_size> * remainder = 0)
  1536. {
  1537. if( this == &ss2 )
  1538. {
  1539. UInt<value_size> copy_ss2(ss2);
  1540. return Div3Ref(copy_ss2, remainder);
  1541. }
  1542. else
  1543. {
  1544. return Div3Ref(ss2, remainder);
  1545. }
  1546. }
  1547. /*!
  1548. the third division algorithm
  1549. */
  1550. uint Div3(const UInt<value_size> & ss2, UInt<value_size> & remainder)
  1551. {
  1552. return Div3(ss2, &remainder);
  1553. }
  1554. private:
  1555. /*!
  1556. the third division algorithm
  1557. this algorithm is described in the following book:
  1558. "The art of computer programming 2" (4.3.1 page 272)
  1559. Donald E. Knuth
  1560. !! give the description here (from the book)
  1561. */
  1562. uint Div3Ref(const UInt<value_size> & v, UInt<value_size> * remainder = 0)
  1563. {
  1564. uint m,n, test;
  1565. test = Div_StandardTest(v, m, n, remainder);
  1566. if( test < 2 )
  1567. return test;
  1568. if( n == 0 )
  1569. {
  1570. uint r;
  1571. DivInt( v.table[0], &r );
  1572. if( remainder )
  1573. {
  1574. remainder->SetZero();
  1575. remainder->table[0] = r;
  1576. }
  1577. TTMATH_LOG("UInt::Div3")
  1578. return 0;
  1579. }
  1580. // we can only use the third division algorithm when
  1581. // the divisor is greater or equal 2^32 (has more than one 32-bit word)
  1582. ++m;
  1583. ++n;
  1584. m = m - n;
  1585. Div3_Division(v, remainder, m, n);
  1586. TTMATH_LOG("UInt::Div3")
  1587. return 0;
  1588. }
  1589. private:
  1590. void Div3_Division(UInt<value_size> v, UInt<value_size> * remainder, uint m, uint n)
  1591. {
  1592. TTMATH_ASSERT( n>=2 )
  1593. UInt<value_size+1> uu, vv;
  1594. UInt<value_size> q;
  1595. uint d, u_value_size, u0, u1, u2, v1, v0, j=m;
  1596. u_value_size = Div3_Normalize(v, n, d);
  1597. if( j+n == value_size )
  1598. u2 = u_value_size;
  1599. else
  1600. u2 = table[j+n];
  1601. Div3_MakeBiggerV(v, vv);
  1602. for(uint i = j+1 ; i<value_size ; ++i)
  1603. q.table[i] = 0;
  1604. while( true )
  1605. {
  1606. u1 = table[j+n-1];
  1607. u0 = table[j+n-2];
  1608. v1 = v.table[n-1];
  1609. v0 = v.table[n-2];
  1610. uint qp = Div3_Calculate(u2,u1,u0, v1,v0);
  1611. Div3_MakeNewU(uu, j, n, u2);
  1612. Div3_MultiplySubtract(uu, vv, qp);
  1613. Div3_CopyNewU(uu, j, n);
  1614. q.table[j] = qp;
  1615. // the next loop
  1616. if( j-- == 0 )
  1617. break;
  1618. u2 = table[j+n];
  1619. }
  1620. if( remainder )
  1621. Div3_Unnormalize(remainder, n, d);
  1622. *this = q;
  1623. TTMATH_LOG("UInt::Div3_Division")
  1624. }
  1625. void Div3_MakeNewU(UInt<value_size+1> & uu, uint j, uint n, uint u_max)
  1626. {
  1627. uint i;
  1628. for(i=0 ; i<n ; ++i, ++j)
  1629. uu.table[i] = table[j];
  1630. // 'n' is from <1..value_size> so and 'i' is from <0..value_size>
  1631. // then table[i] is always correct (look at the declaration of 'uu')
  1632. uu.table[i] = u_max;
  1633. for( ++i ; i<value_size+1 ; ++i)
  1634. uu.table[i] = 0;
  1635. TTMATH_LOG("UInt::Div3_MakeNewU")
  1636. }
  1637. void Div3_CopyNewU(const UInt<value_size+1> & uu, uint j, uint n)
  1638. {
  1639. uint i;
  1640. for(i=0 ; i<n ; ++i)
  1641. table[i+j] = uu.table[i];
  1642. if( i+j < value_size )
  1643. table[i+j] = uu.table[i];
  1644. TTMATH_LOG("UInt::Div3_CopyNewU")
  1645. }
  1646. /*!
  1647. we're making the new 'vv'
  1648. the value is actually the same but the 'table' is bigger (value_size+1)
  1649. */
  1650. void Div3_MakeBiggerV(const UInt<value_size> & v, UInt<value_size+1> & vv)
  1651. {
  1652. for(uint i=0 ; i<value_size ; ++i)
  1653. vv.table[i] = v.table[i];
  1654. vv.table[value_size] = 0;
  1655. TTMATH_LOG("UInt::Div3_MakeBiggerV")
  1656. }
  1657. /*!
  1658. we're moving all bits from 'v' into the left side of the n-1 word
  1659. (the highest bit at v.table[n-1] will be equal one,
  1660. the bits from 'this' we're moving the same times as 'v')
  1661. return values:
  1662. d - how many times we've moved
  1663. return - the next-left value from 'this' (that after table[value_size-1])
  1664. */
  1665. uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
  1666. {
  1667. // v.table[n-1] is != 0
  1668. uint bit = (uint)FindLeadingBitInWord(v.table[n-1]);
  1669. uint move = (TTMATH_BITS_PER_UINT - bit - 1);
  1670. uint res = table[value_size-1];
  1671. d = move;
  1672. if( move > 0 )
  1673. {
  1674. v.Rcl(move, 0);
  1675. Rcl(move, 0);
  1676. res = res >> (bit + 1);
  1677. }
  1678. else
  1679. {
  1680. res = 0;
  1681. }
  1682. TTMATH_LOG("UInt::Div3_Normalize")
  1683. return res;
  1684. }
  1685. void Div3_Unnormalize(UInt<value_size> * remainder, uint n, uint d)
  1686. {
  1687. for(uint i=n ; i<value_size ; ++i)
  1688. table[i] = 0;
  1689. Rcr(d,0);
  1690. *remainder = *this;
  1691. TTMATH_LOG("UInt::Div3_Unnormalize")
  1692. }
  1693. uint Div3_Calculate(uint u2, uint u1, uint u0, uint v1, uint v0)
  1694. {
  1695. UInt<2> u_temp;
  1696. uint rp;
  1697. bool next_test;
  1698. TTMATH_ASSERT( v1 != 0 )
  1699. u_temp.table[1] = u2;
  1700. u_temp.table[0] = u1;
  1701. u_temp.DivInt(v1, &rp);
  1702. TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 )
  1703. do
  1704. {
  1705. bool decrease = false;
  1706. if( u_temp.table[1] == 1 )
  1707. decrease = true;
  1708. else
  1709. {
  1710. UInt<2> temp1, temp2;
  1711. UInt<2>::MulTwoWords(u_temp.table[0], v0, temp1.table+1, temp1.table);
  1712. temp2.table[1] = rp;
  1713. temp2.table[0] = u0;
  1714. if( temp1 > temp2 )
  1715. decrease = true;
  1716. }
  1717. next_test = false;
  1718. if( decrease )
  1719. {
  1720. u_temp.SubOne();
  1721. rp += v1;
  1722. if( rp >= v1 ) // it means that there wasn't a carry (r<b from the book)
  1723. next_test = true;
  1724. }
  1725. }
  1726. while( next_test );
  1727. TTMATH_LOG("UInt::Div3_Calculate")
  1728. return u_temp.table[0];
  1729. }
  1730. void Div3_MultiplySubtract( UInt<value_size+1> & uu,
  1731. const UInt<value_size+1> & vv, uint & qp)
  1732. {
  1733. // D4 (in the book)
  1734. UInt<value_size+1> vv_temp(vv);
  1735. vv_temp.MulInt(qp);
  1736. if( uu.Sub(vv_temp) )
  1737. {
  1738. // there was a carry
  1739. //
  1740. // !!! this part of code was not tested
  1741. //
  1742. --qp;
  1743. uu.Add(vv);
  1744. // can be a carry from this additions but it should be ignored
  1745. // because it cancels with the borrow from uu.Sub(vv_temp)
  1746. }
  1747. TTMATH_LOG("UInt::Div3_MultiplySubtract")
  1748. }
  1749. public:
  1750. /*!
  1751. power this = this ^ pow
  1752. binary algorithm (r-to-l)
  1753. return values:
  1754. 0 - ok
  1755. 1 - carry
  1756. 2 - incorrect argument (0^0)
  1757. */
  1758. uint Pow(UInt<value_size> pow)
  1759. {
  1760. if(pow.IsZero() && IsZero())
  1761. // we don't define zero^zero
  1762. return 2;
  1763. UInt<value_size> start(*this);
  1764. UInt<value_size> result;
  1765. result.SetOne();
  1766. uint c = 0;
  1767. while( !c )
  1768. {
  1769. if( pow.table[0] & 1 )
  1770. c += result.Mul(start);
  1771. pow.Rcr2_one(0);
  1772. if( pow.IsZero() )
  1773. break;
  1774. c += start.Mul(start);
  1775. }
  1776. *this = result;
  1777. TTMATH_LOGC("UInt::Pow(UInt<>)", c)
  1778. return (c==0)? 0 : 1;
  1779. }
  1780. /*!
  1781. square root
  1782. e.g. Sqrt(9) = 3
  1783. ('digit-by-digit' algorithm)
  1784. */
  1785. void Sqrt()
  1786. {
  1787. UInt<value_size> bit, temp;
  1788. if( IsZero() )
  1789. return;
  1790. UInt<value_size> value(*this);
  1791. SetZero();
  1792. bit.SetZero();
  1793. bit.table[value_size-1] = (TTMATH_UINT_HIGHEST_BIT >> 1);
  1794. while( bit > value )
  1795. bit.Rcr(2);
  1796. while( !bit.IsZero() )
  1797. {
  1798. temp = *this;
  1799. temp.Add(bit);
  1800. if( value >= temp )
  1801. {
  1802. value.Sub(temp);
  1803. Rcr(1);
  1804. Add(bit);
  1805. }
  1806. else
  1807. {
  1808. Rcr(1);
  1809. }
  1810. bit.Rcr(2);
  1811. }
  1812. TTMATH_LOG("UInt::Sqrt")
  1813. }
  1814. /*!
  1815. this method sets n first bits to value zero
  1816. For example:
  1817. let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
  1818. */
  1819. void ClearFirstBits(uint n)
  1820. {
  1821. if( n >= value_size*TTMATH_BITS_PER_UINT )
  1822. {
  1823. SetZero();
  1824. TTMATH_LOG("UInt::ClearFirstBits")
  1825. return;
  1826. }
  1827. uint * p = table;
  1828. // first we're clearing the whole words
  1829. while( n >= TTMATH_BITS_PER_UINT )
  1830. {
  1831. *p++ = 0;
  1832. n -= TTMATH_BITS_PER_UINT;
  1833. }
  1834. if( n == 0 )
  1835. {
  1836. TTMATH_LOG("UInt::ClearFirstBits")
  1837. return;
  1838. }
  1839. // and then we're clearing one word which has left
  1840. // mask -- all bits are set to one
  1841. uint mask = TTMATH_UINT_MAX_VALUE;
  1842. mask = mask << n;
  1843. (*p) &= mask;
  1844. TTMATH_LOG("UInt::ClearFirstBits")
  1845. }
  1846. /*!
  1847. this method returns true if the highest bit of the value is set
  1848. */
  1849. bool IsTheHighestBitSet() const
  1850. {
  1851. return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0;
  1852. }
  1853. /*!
  1854. this method returns true if the lowest bit of the value is set
  1855. */
  1856. bool IsTheLowestBitSet() const
  1857. {
  1858. return (*table & 1) != 0;
  1859. }
  1860. /*!
  1861. returning true if only the highest bit is set
  1862. */
  1863. bool IsOnlyTheHighestBitSet() const
  1864. {
  1865. #ifdef __clang__
  1866. #pragma clang diagnostic push
  1867. #pragma clang diagnostic ignored "-Wtautological-compare"
  1868. #endif
  1869. for(uint i=0 ; i<value_size-1 ; ++i)
  1870. if( table[i] != 0 )
  1871. return false;
  1872. #ifdef __clang__
  1873. #pragma clang diagnostic pop
  1874. #endif
  1875. if( table[value_size-1] != TTMATH_UINT_HIGHEST_BIT )
  1876. return false;
  1877. return true;
  1878. }
  1879. /*!
  1880. returning true if only the lowest bit is set
  1881. */
  1882. bool IsOnlyTheLowestBitSet() const
  1883. {
  1884. if( table[0] != 1 )
  1885. return false;
  1886. for(uint i=1 ; i<value_size ; ++i)
  1887. if( table[i] != 0 )
  1888. return false;
  1889. return true;
  1890. }
  1891. /*!
  1892. this method returns true if the value is equal zero
  1893. */
  1894. bool IsZero() const
  1895. {
  1896. for(uint i=0 ; i<value_size ; ++i)
  1897. if(table[i] != 0)
  1898. return false;
  1899. return true;
  1900. }
  1901. /*!
  1902. returning true if first 'bits' bits are equal zero
  1903. */
  1904. bool AreFirstBitsZero(uint bits) const
  1905. {
  1906. TTMATH_ASSERT( bits <= value_size * TTMATH_BITS_PER_UINT )
  1907. uint index = bits / TTMATH_BITS_PER_UINT;
  1908. uint rest = bits % TTMATH_BITS_PER_UINT;
  1909. uint i;
  1910. for(i=0 ; i<index ; ++i)
  1911. if(table[i] != 0 )
  1912. return false;
  1913. if( rest == 0 )
  1914. return true;
  1915. uint mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
  1916. return (table[i] & mask) == 0;
  1917. }
  1918. /*!
  1919. *
  1920. * conversion methods
  1921. *
  1922. */
  1923. /*!
  1924. this method converts an UInt<another_size> type to this class
  1925. this operation has mainly sense if the value from p is
  1926. equal or smaller than that one which is returned from UInt<value_size>::SetMax()
  1927. it returns a carry if the value 'p' is too big
  1928. */
  1929. template<uint argument_size>
  1930. uint FromUInt(const UInt<argument_size> & p)
  1931. {
  1932. uint min_size = (value_size < argument_size)? value_size : argument_size;
  1933. uint i;
  1934. for(i=0 ; i<min_size ; ++i)
  1935. table[i] = p.table[i];
  1936. if( value_size > argument_size )
  1937. {
  1938. // 'this' is longer than 'p'
  1939. for( ; i<value_size ; ++i)
  1940. table[i] = 0;
  1941. }
  1942. else
  1943. {
  1944. for( ; i<argument_size ; ++i)
  1945. if( p.table[i] != 0 )
  1946. {
  1947. TTMATH_LOGC("UInt::FromUInt(UInt<>)", 1)
  1948. return 1;
  1949. }
  1950. }
  1951. TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0)
  1952. return 0;
  1953. }
  1954. /*!
  1955. this method converts an UInt<another_size> type to this class
  1956. this operation has mainly sense if the value from p is
  1957. equal or smaller than that one which is returned from UInt<value_size>::SetMax()
  1958. it returns a carry if the value 'p' is too big
  1959. */
  1960. template<uint argument_size>
  1961. uint FromInt(const UInt<argument_size> & p)
  1962. {
  1963. return FromUInt(p);
  1964. }
  1965. /*!
  1966. this method converts the uint type to this class
  1967. */
  1968. uint FromUInt(uint value)
  1969. {
  1970. for(uint i=1 ; i<value_size ; ++i)
  1971. table[i] = 0;
  1972. table[0] = value;
  1973. TTMATH_LOG("UInt::FromUInt(uint)")
  1974. // there'll never be a carry here
  1975. return 0;
  1976. }
  1977. /*!
  1978. this method converts the uint type to this class
  1979. */
  1980. uint FromInt(uint value)
  1981. {
  1982. return FromUInt(value);
  1983. }
  1984. /*!
  1985. this method converts the sint type to this class
  1986. */
  1987. uint FromInt(sint value)
  1988. {
  1989. uint c = FromUInt(uint(value));
  1990. if( c || value < 0 )
  1991. return 1;
  1992. return 0;
  1993. }
  1994. /*!
  1995. this operator converts an UInt<another_size> type to this class
  1996. it doesn't return a carry
  1997. */
  1998. /* template<uint argument_size>
  1999. UInt<value_size> & operator=(const UInt<argument_size> & p)
  2000. {
  2001. FromUInt(p);
  2002. return *this;
  2003. }
  2004. */
  2005. /*!
  2006. the assignment operator
  2007. */
  2008. /* UInt<value_size> & operator=(const UInt<value_size> & p)
  2009. {
  2010. for(uint i=0 ; i<value_size ; ++i)
  2011. table[i] = p.table[i];
  2012. TTMATH_LOG("UInt::operator=(UInt<>)")
  2013. return *this;
  2014. }
  2015. */
  2016. /*!
  2017. this method converts the uint type to this class
  2018. */
  2019. UInt<value_size> & operator=(uint i)
  2020. {
  2021. FromUInt(i);
  2022. return *this;
  2023. }
  2024. /*!
  2025. a constructor for converting the uint to this class
  2026. */
  2027. /* UInt(uint i)
  2028. {
  2029. FromUInt(i);
  2030. }
  2031. */
  2032. /*!
  2033. this method converts the sint type to this class
  2034. */
  2035. UInt<value_size> & operator=(sint i)
  2036. {
  2037. FromInt(i);
  2038. return *this;
  2039. }
  2040. /*!
  2041. a constructor for converting the sint to this class
  2042. look at the description of UInt::operator=(sint)
  2043. */
  2044. /* UInt(sint i)
  2045. {
  2046. FromInt(i);
  2047. }
  2048. */
  2049. #ifdef TTMATH_PLATFORM32
  2050. /*!
  2051. this method converts unsigned 64 bit int type to this class
  2052. ***this method is created only on a 32bit platform***
  2053. */
  2054. uint FromUInt(ulint n)
  2055. {
  2056. table[0] = (uint)n;
  2057. if( value_size == 1 )
  2058. {
  2059. uint c = ((n >> TTMATH_BITS_PER_UINT) == 0) ? 0 : 1;
  2060. TTMATH_LOGC("UInt::FromUInt(ulint)", c)
  2061. return c;
  2062. }
  2063. table[1] = (uint)(n >> TTMATH_BITS_PER_UINT);
  2064. for(uint i=2 ; i<value_size ; ++i)
  2065. table[i] = 0;
  2066. TTMATH_LOG("UInt::FromUInt(ulint)")
  2067. return 0;
  2068. }
  2069. /*!
  2070. this method converts unsigned 64 bit int type to this class
  2071. ***this method is created only on a 32bit platform***
  2072. */
  2073. uint FromInt(ulint n)
  2074. {
  2075. return FromUInt(n);
  2076. }
  2077. /*!
  2078. this method converts signed 64 bit int type to this class
  2079. ***this method is created only on a 32bit platform***
  2080. */
  2081. uint FromInt(slint n)
  2082. {
  2083. uint c = FromUInt(ulint(n));
  2084. if( c || n < 0 )
  2085. return 1;
  2086. return 0;
  2087. }
  2088. /*!
  2089. this operator converts unsigned 64 bit int type to this class
  2090. ***this operator is created only on a 32bit platform***
  2091. */
  2092. UInt<value_size> & operator=(ulint n)
  2093. {
  2094. FromUInt(n);
  2095. return *this;
  2096. }
  2097. /*!
  2098. a constructor for converting unsigned 64 bit int to this class
  2099. ***this constructor is created only on a 32bit platform***
  2100. */
  2101. /* UInt(ulint n)
  2102. {
  2103. FromUInt(n);
  2104. }
  2105. */
  2106. /*!
  2107. this operator converts signed 64 bit int type to this class
  2108. ***this operator is created only on a 32bit platform***
  2109. */
  2110. UInt<value_size> & operator=(slint n)
  2111. {
  2112. FromInt(n);
  2113. return *this;
  2114. }
  2115. /*!
  2116. a constructor for converting signed 64 bit int to this class
  2117. ***this constructor is created only on a 32bit platform***
  2118. */
  2119. /* UInt(slint n)
  2120. {
  2121. FromInt(n);
  2122. }
  2123. */
  2124. #endif
  2125. #ifdef TTMATH_PLATFORM64
  2126. /*!
  2127. this method converts 32 bit unsigned int type to this class
  2128. ***this operator is created only on a 64bit platform***
  2129. */
  2130. uint FromUInt(unsigned int i)
  2131. {
  2132. return FromUInt(uint(i));
  2133. }
  2134. /*!
  2135. this method converts 32 bit unsigned int type to this class
  2136. ***this operator is created only on a 64bit platform***
  2137. */
  2138. uint FromInt(unsigned int i)
  2139. {
  2140. return FromUInt(uint(i));
  2141. }
  2142. /*!
  2143. this method converts 32 bit signed int type to this class
  2144. ***this operator is created only on a 64bit platform***
  2145. */
  2146. uint FromInt(signed int i)
  2147. {
  2148. return FromInt(sint(i));
  2149. }
  2150. /*!
  2151. this operator converts 32 bit unsigned int type to this class
  2152. ***this operator is created only on a 64bit platform***
  2153. */
  2154. UInt<value_size> & operator=(unsigned int i)
  2155. {
  2156. FromUInt(i);
  2157. return *this;
  2158. }
  2159. /*!
  2160. a constructor for converting 32 bit unsigned int to this class
  2161. ***this constructor is created only on a 64bit platform***
  2162. */
  2163. /* UInt(unsigned int i)
  2164. {
  2165. FromUInt(i);
  2166. }
  2167. */
  2168. /*!
  2169. an operator for converting 32 bit signed int to this class
  2170. ***this constructor is created only on a 64bit platform***
  2171. */
  2172. UInt<value_size> & operator=(signed int i)
  2173. {
  2174. FromInt(i);
  2175. return *this;
  2176. }
  2177. /*!
  2178. a constructor for converting 32 bit signed int to this class
  2179. ***this constructor is created only on a 64bit platform***
  2180. */
  2181. /* UInt(signed int i)
  2182. {
  2183. FromInt(i);
  2184. }
  2185. */
  2186. #endif
  2187. /*!
  2188. a constructor for converting a string to this class (with the base=10)
  2189. */
  2190. /* UInt(const char * s)
  2191. {
  2192. FromString(s);
  2193. }
  2194. */
  2195. /*!
  2196. a constructor for converting a string to this class (with the base=10)
  2197. */
  2198. /* UInt(const std::string & s)
  2199. {
  2200. FromString( s.c_str() );
  2201. }
  2202. */
  2203. #ifndef TTMATH_DONT_USE_WCHAR
  2204. /*!
  2205. a constructor for converting a string to this class (with the base=10)
  2206. */
  2207. UInt(const wchar_t * s)
  2208. {
  2209. FromString(s);
  2210. }
  2211. /*!
  2212. a constructor for converting a string to this class (with the base=10)
  2213. */
  2214. UInt(const std::wstring & s)
  2215. {
  2216. FromString( s.c_str() );
  2217. }
  2218. #endif
  2219. /*!
  2220. a default constructor
  2221. we don't clear the table
  2222. */
  2223. /* UInt()
  2224. {
  2225. // when macro TTMATH_DEBUG_LOG is defined
  2226. // we set special values to the table
  2227. // in order to be everywhere the same value of the UInt object
  2228. // without this it would be difficult to analyse the log file
  2229. #ifdef TTMATH_DEBUG_LOG
  2230. #ifdef TTMATH_PLATFORM32
  2231. for(uint i=0 ; i<value_size ; ++i)
  2232. table[i] = 0xc1c1c1c1;
  2233. #else
  2234. for(uint i=0 ; i<value_size ; ++i)
  2235. table[i] = 0xc1c1c1c1c1c1c1c1;
  2236. #endif
  2237. #endif
  2238. }
  2239. */
  2240. /*!
  2241. a copy constructor
  2242. */
  2243. /* UInt(const UInt<value_size> & u)
  2244. {
  2245. for(uint i=0 ; i<value_size ; ++i)
  2246. table[i] = u.table[i];
  2247. TTMATH_LOG("UInt::UInt(UInt<>)")
  2248. }
  2249. */
  2250. /*!
  2251. a template for producting constructors for copying from another types
  2252. */
  2253. /* template<uint argument_size>
  2254. UInt(const UInt<argument_size> & u)
  2255. {
  2256. // look that 'size' we still set as 'value_size' and not as u.value_size
  2257. FromUInt(u);
  2258. }
  2259. */
  2260. /*!
  2261. a destructor
  2262. */
  2263. /* ~UInt()
  2264. {
  2265. }
  2266. */
  2267. /*!
  2268. this method returns the lowest value from table
  2269. we must be sure when we using this method whether the value
  2270. will hold in an uint type or not (the rest value from the table must be zero)
  2271. */
  2272. uint ToUInt() const
  2273. {
  2274. return table[0];
  2275. }
  2276. /*!
  2277. this method converts the value to uint type
  2278. can return a carry if the value is too long to store it in uint type
  2279. */
  2280. uint ToUInt(uint & result) const
  2281. {
  2282. result = table[0];
  2283. for(uint i=1 ; i<value_size ; ++i)
  2284. if( table[i] != 0 )
  2285. return 1;
  2286. return 0;
  2287. }
  2288. /*!
  2289. this method converts the value to uint type
  2290. can return a carry if the value is too long to store it in uint type
  2291. */
  2292. uint ToInt(uint & result) const
  2293. {
  2294. return ToUInt(result);
  2295. }
  2296. /*!
  2297. this method converts the value to sint type (signed integer)
  2298. can return a carry if the value is too long to store it in sint type
  2299. */
  2300. uint ToInt(sint & result) const
  2301. {
  2302. result = sint(table[0]);
  2303. if( (result & TTMATH_UINT_HIGHEST_BIT) != 0 )
  2304. return 1;
  2305. for(uint i=1 ; i<value_size ; ++i)
  2306. if( table[i] != 0 )
  2307. return 1;
  2308. return 0;
  2309. }
  2310. #ifdef TTMATH_PLATFORM32
  2311. /*!
  2312. this method converts the value to ulint type (64 bit unsigned integer)
  2313. can return a carry if the value is too long to store it in ulint type
  2314. *** this method is created only on a 32 bit platform ***
  2315. */
  2316. uint ToUInt(ulint & result) const
  2317. {
  2318. if( value_size == 1 )
  2319. {
  2320. result = table[0];
  2321. }
  2322. else
  2323. {
  2324. uint low = table[0];
  2325. uint high = table[1];
  2326. result = low;
  2327. result |= (ulint(high) << TTMATH_BITS_PER_UINT);
  2328. for(uint i=2 ; i<value_size ; ++i)
  2329. if( table[i] != 0 )
  2330. return 1;
  2331. }
  2332. return 0;
  2333. }
  2334. /*!
  2335. this method converts the value to ulint type (64 bit unsigned integer)
  2336. can return a carry if the value is too long to store it in ulint type
  2337. *** this method is created only on a 32 bit platform ***
  2338. */
  2339. uint ToInt(ulint & result) const
  2340. {
  2341. return ToUInt(result);
  2342. }
  2343. /*!
  2344. this method converts the value to slint type (64 bit signed integer)
  2345. can return a carry if the value is too long to store it in slint type
  2346. *** this method is created only on a 32 bit platform ***
  2347. */
  2348. uint ToInt(slint & result) const
  2349. {
  2350. ulint temp;
  2351. uint c = ToUInt(temp);
  2352. result = slint(temp);
  2353. if( c || result < 0 )
  2354. return 1;
  2355. return 0;
  2356. }
  2357. #endif
  2358. #ifdef TTMATH_PLATFORM64
  2359. /*!
  2360. this method converts the value to a 32 unsigned integer
  2361. can return a carry if the value is too long to store it in this type
  2362. *** this method is created only on a 64 bit platform ***
  2363. */
  2364. uint ToUInt(unsigned int & result) const
  2365. {
  2366. result = (unsigned int)table[0];
  2367. if( (table[0] >> 32) != 0 )
  2368. return 1;
  2369. for(uint i=1 ; i<value_size ; ++i)
  2370. if( table[i] != 0 )
  2371. return 1;
  2372. return 0;
  2373. }
  2374. /*!
  2375. this method converts the value to a 32 unsigned integer
  2376. can return a carry if the value is too long to store it in this type
  2377. *** this method is created only on a 64 bit platform ***
  2378. */
  2379. uint ToInt(unsigned int & result) const
  2380. {
  2381. return ToUInt(result);
  2382. }
  2383. /*!
  2384. this method converts the value to a 32 signed integer
  2385. can return a carry if the value is too long to store it in this type
  2386. *** this method is created only on a 64 bit platform ***
  2387. */
  2388. uint ToInt(int & result) const
  2389. {
  2390. unsigned int temp;
  2391. uint c = ToUInt(temp);
  2392. result = int(temp);
  2393. if( c || result < 0 )
  2394. return 1;
  2395. return 0;
  2396. }
  2397. #endif
  2398. protected:
  2399. /*!
  2400. an auxiliary method for converting into the string
  2401. it returns the log (with the base 2) from x
  2402. where x is in <2;16>
  2403. */
  2404. double ToStringLog2(uint x) const
  2405. {
  2406. static double log_tab[] = {
  2407. 1.000000000000000000,
  2408. 0.630929753571457437,
  2409. 0.500000000000000000,
  2410. 0.430676558073393050,
  2411. 0.386852807234541586,
  2412. 0.356207187108022176,
  2413. 0.333333333333333333,
  2414. 0.315464876785728718,
  2415. 0.301029995663981195,
  2416. 0.289064826317887859,
  2417. 0.278942945651129843,
  2418. 0.270238154427319741,
  2419. 0.262649535037193547,
  2420. 0.255958024809815489,
  2421. 0.250000000000000000
  2422. };
  2423. if( x<2 || x>16 )
  2424. return 0;
  2425. return log_tab[x-2];
  2426. }
  2427. public:
  2428. /*!
  2429. an auxiliary method for converting to a string
  2430. it's used from Int::ToString() too (negative is set true then)
  2431. */
  2432. template<class string_type>
  2433. void ToStringBase(string_type & result, uint b = 10, bool negative = false) const
  2434. {
  2435. UInt<value_size> temp(*this);
  2436. uint rest, table_id, index, digits;
  2437. double digits_d;
  2438. char character;
  2439. result.clear();
  2440. if( b<2 || b>16 )
  2441. return;
  2442. if( !FindLeadingBit(table_id, index) )
  2443. {
  2444. result = '0';
  2445. return;
  2446. }
  2447. if( negative )
  2448. result = '-';
  2449. digits_d = table_id; // for not making an overflow in uint type
  2450. digits_d *= TTMATH_BITS_PER_UINT;
  2451. digits_d += index + 1;
  2452. digits_d *= ToStringLog2(b);
  2453. digits = static_cast<uint>(digits_d) + 3; // plus some epsilon
  2454. if( result.capacity() < digits )
  2455. result.reserve(digits);
  2456. do
  2457. {
  2458. temp.DivInt(b, &rest);
  2459. character = static_cast<char>(Misc::DigitToChar(rest));
  2460. result.insert(result.end(), character);
  2461. }
  2462. while( !temp.IsZero() );
  2463. size_t i1 = negative ? 1 : 0; // the first is a hyphen (when negative is true)
  2464. size_t i2 = result.size() - 1;
  2465. for( ; i1 < i2 ; ++i1, --i2 )
  2466. {
  2467. char tempc = static_cast<char>(result[i1]);
  2468. result[i1] = result[i2];
  2469. result[i2] = tempc;
  2470. }
  2471. }
  2472. /*!
  2473. this method converts the value to a string with a base equal 'b'
  2474. */
  2475. void ToString(std::string & result, uint b = 10) const
  2476. {
  2477. return ToStringBase(result, b);
  2478. }
  2479. std::string ToString(uint b = 10) const
  2480. {
  2481. std::string result;
  2482. ToStringBase(result, b);
  2483. return result;
  2484. }
  2485. #ifndef TTMATH_DONT_USE_WCHAR
  2486. void ToString(std::wstring & result, uint b = 10) const
  2487. {
  2488. return ToStringBase(result, b);
  2489. }
  2490. std::wstring ToWString(uint b = 10) const
  2491. {
  2492. std::wstring result;
  2493. ToStringBase(result, b);
  2494. return result;
  2495. }
  2496. #endif
  2497. private:
  2498. /*!
  2499. an auxiliary method for converting from a string
  2500. */
  2501. template<class char_type>
  2502. uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
  2503. {
  2504. UInt<value_size> base;
  2505. base.FromUInt( b );
  2506. UInt<value_size> temp;
  2507. sint z;
  2508. uint c = 0;
  2509. SetZero();
  2510. temp.SetZero();
  2511. Misc::SkipWhiteCharacters(s);
  2512. if( after_source )
  2513. *after_source = s;
  2514. if( value_read )
  2515. *value_read = false;
  2516. if( b<2 || b>16 )
  2517. return 1;
  2518. for( ; (z=Misc::CharToDigit(*s, b)) != -1 ; ++s)
  2519. {
  2520. if( value_read )
  2521. *value_read = true;
  2522. if( c == 0 )
  2523. {
  2524. temp.table[0] = z;
  2525. c += Mul(base); // !! IMPROVE ME: there can be used MulInt here
  2526. c += Add(temp);
  2527. }
  2528. }
  2529. if( after_source )
  2530. *after_source = s;
  2531. TTMATH_LOGC("UInt::FromString", c)
  2532. return (c==0)? 0 : 1;
  2533. }
  2534. public:
  2535. /*!
  2536. this method converts a string into its value
  2537. it returns carry=1 if the value will be too big or an incorrect base 'b' is given
  2538. string is ended with a non-digit value, for example:
  2539. "12" will be translated to 12
  2540. as well as:
  2541. "12foo" will be translated to 12 too
  2542. existing first white characters will be ommited
  2543. if the value from s is too large the rest digits will be skipped
  2544. after_source (if exists) is pointing at the end of the parsed string
  2545. value_read (if exists) tells whether something has actually been read (at least one digit)
  2546. */
  2547. uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
  2548. {
  2549. return FromStringBase(s, b, after_source, value_read);
  2550. }
  2551. /*!
  2552. this method converts a string into its value
  2553. (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
  2554. */
  2555. uint FromString(const std::string & s, uint b = 10)
  2556. {
  2557. return FromString( s.c_str(), b );
  2558. }
  2559. /*!
  2560. this operator converts a string into its value (with base = 10)
  2561. */
  2562. UInt<value_size> & operator=(const char * s)
  2563. {
  2564. FromString(s);
  2565. return *this;
  2566. }
  2567. /*!
  2568. this operator converts a string into its value (with base = 10)
  2569. */
  2570. UInt<value_size> & operator=(const std::string & s)
  2571. {
  2572. FromString( s.c_str() );
  2573. return *this;
  2574. }
  2575. #ifndef TTMATH_DONT_USE_WCHAR
  2576. /*!
  2577. this method converts a string into its value
  2578. */
  2579. uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
  2580. {
  2581. return FromStringBase(s, b, after_source, value_read);
  2582. }
  2583. /*!
  2584. this method converts a string into its value
  2585. (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
  2586. */
  2587. uint FromString(const std::wstring & s, uint b = 10)
  2588. {
  2589. return FromString( s.c_str(), b );
  2590. }
  2591. /*!
  2592. this operator converts a string into its value (with base = 10)
  2593. */
  2594. UInt<value_size> & operator=(const wchar_t * s)
  2595. {
  2596. FromString(s);
  2597. return *this;
  2598. }
  2599. /*!
  2600. this operator converts a string into its value (with base = 10)
  2601. */
  2602. UInt<value_size> & operator=(const std::wstring & s)
  2603. {
  2604. FromString( s.c_str() );
  2605. return *this;
  2606. }
  2607. #endif
  2608. /*!
  2609. *
  2610. * methods for comparing
  2611. *
  2612. */
  2613. /*!
  2614. this method returns true if 'this' is smaller than 'l'
  2615. 'index' is an index of the first word from will be the comparison performed
  2616. (note: we start the comparison from back - from the last word, when index is -1 /default/
  2617. it is automatically set into the last word)
  2618. I introduced it for some kind of optimization made in the second division algorithm (Div2)
  2619. */
  2620. bool CmpSmaller(const UInt<value_size> & l, sint index = -1) const
  2621. {
  2622. sint i;
  2623. if( index==-1 || index>=sint(value_size) )
  2624. i = value_size - 1;
  2625. else
  2626. i = index;
  2627. for( ; i>=0 ; --i)
  2628. {
  2629. if( table[i] != l.table[i] )
  2630. return table[i] < l.table[i];
  2631. }
  2632. // they're equal
  2633. return false;
  2634. }
  2635. /*!
  2636. this method returns true if 'this' is bigger than 'l'
  2637. 'index' is an index of the first word from will be the comparison performed
  2638. (note: we start the comparison from back - from the last word, when index is -1 /default/
  2639. it is automatically set into the last word)
  2640. I introduced it for some kind of optimization made in the second division algorithm (Div2)
  2641. */
  2642. bool CmpBigger(const UInt<value_size> & l, sint index = -1) const
  2643. {
  2644. sint i;
  2645. if( index==-1 || index>=sint(value_size) )
  2646. i = value_size - 1;
  2647. else
  2648. i = index;
  2649. for( ; i>=0 ; --i)
  2650. {
  2651. if( table[i] != l.table[i] )
  2652. return table[i] > l.table[i];
  2653. }
  2654. // they're equal
  2655. return false;
  2656. }
  2657. /*!
  2658. this method returns true if 'this' is equal 'l'
  2659. 'index' is an index of the first word from will be the comparison performed
  2660. (note: we start the comparison from back - from the last word, when index is -1 /default/
  2661. it is automatically set into the last word)
  2662. */
  2663. bool CmpEqual(const UInt<value_size> & l, sint index = -1) const
  2664. {
  2665. sint i;
  2666. if( index==-1 || index>=sint(value_size) )
  2667. i = value_size - 1;
  2668. else
  2669. i = index;
  2670. for( ; i>=0 ; --i)
  2671. if( table[i] != l.table[i] )
  2672. return false;
  2673. return true;
  2674. }
  2675. /*!
  2676. this method returns true if 'this' is smaller than or equal 'l'
  2677. 'index' is an index of the first word from will be the comparison performed
  2678. (note: we start the comparison from back - from the last word, when index is -1 /default/
  2679. it is automatically set into the last word)
  2680. */
  2681. bool CmpSmallerEqual(const UInt<value_size> & l, sint index=-1) const
  2682. {
  2683. sint i;
  2684. if( index==-1 || index>=sint(value_size) )
  2685. i = value_size - 1;
  2686. else
  2687. i = index;
  2688. for( ; i>=0 ; --i)
  2689. {
  2690. if( table[i] != l.table[i] )
  2691. return table[i] < l.table[i];
  2692. }
  2693. // they're equal
  2694. return true;
  2695. }
  2696. /*!
  2697. this method returns true if 'this' is bigger than or equal 'l'
  2698. 'index' is an index of the first word from will be the comparison performed
  2699. (note: we start the comparison from back - from the last word, when index is -1 /default/
  2700. it is automatically set into the last word)
  2701. */
  2702. bool CmpBiggerEqual(const UInt<value_size> & l, sint index=-1) const
  2703. {
  2704. sint i;
  2705. if( index==-1 || index>=sint(value_size) )
  2706. i = value_size - 1;
  2707. else
  2708. i = index;
  2709. for( ; i>=0 ; --i)
  2710. {
  2711. if( table[i] != l.table[i] )
  2712. return table[i] > l.table[i];
  2713. }
  2714. // they're equal
  2715. return true;
  2716. }
  2717. /*
  2718. operators for comparising
  2719. */
  2720. bool operator<(const UInt<value_size> & l) const
  2721. {
  2722. return CmpSmaller(l);
  2723. }
  2724. bool operator>(const UInt<value_size> & l) const
  2725. {
  2726. return CmpBigger(l);
  2727. }
  2728. bool operator==(const UInt<value_size> & l) const
  2729. {
  2730. return CmpEqual(l);
  2731. }
  2732. bool operator!=(const UInt<value_size> & l) const
  2733. {
  2734. return !operator==(l);
  2735. }
  2736. bool operator<=(const UInt<value_size> & l) const
  2737. {
  2738. return CmpSmallerEqual(l);
  2739. }
  2740. bool operator>=(const UInt<value_size> & l) const
  2741. {
  2742. return CmpBiggerEqual(l);
  2743. }
  2744. /*!
  2745. *
  2746. * standard mathematical operators
  2747. *
  2748. */
  2749. UInt<value_size> operator-(const UInt<value_size> & p2) const
  2750. {
  2751. UInt<value_size> temp(*this);
  2752. temp.Sub(p2);
  2753. return temp;
  2754. }
  2755. UInt<value_size> & operator-=(const UInt<value_size> & p2)
  2756. {
  2757. Sub(p2);
  2758. return *this;
  2759. }
  2760. UInt<value_size> operator+(const UInt<value_size> & p2) const
  2761. {
  2762. UInt<value_size> temp(*this);
  2763. temp.Add(p2);
  2764. return temp;
  2765. }
  2766. UInt<value_size> & operator+=(const UInt<value_size> & p2)
  2767. {
  2768. Add(p2);
  2769. return *this;
  2770. }
  2771. UInt<value_size> operator*(const UInt<value_size> & p2) const
  2772. {
  2773. UInt<value_size> temp(*this);
  2774. temp.Mul(p2);
  2775. return temp;
  2776. }
  2777. UInt<value_size> & operator*=(const UInt<value_size> & p2)
  2778. {
  2779. Mul(p2);
  2780. return *this;
  2781. }
  2782. UInt<value_size> operator/(const UInt<value_size> & p2) const
  2783. {
  2784. UInt<value_size> temp(*this);
  2785. temp.Div(p2);
  2786. return temp;
  2787. }
  2788. UInt<value_size> & operator/=(const UInt<value_size> & p2)
  2789. {
  2790. Div(p2);
  2791. return *this;
  2792. }
  2793. UInt<value_size> operator%(const UInt<value_size> & p2) const
  2794. {
  2795. UInt<value_size> temp(*this);
  2796. UInt<value_size> remainder;
  2797. temp.Div( p2, remainder );
  2798. return remainder;
  2799. }
  2800. UInt<value_size> & operator%=(const UInt<value_size> & p2)
  2801. {
  2802. UInt<value_size> remainder;
  2803. Div( p2, remainder );
  2804. operator=(remainder);
  2805. return *this;
  2806. }
  2807. /*!
  2808. Prefix operator e.g ++variable
  2809. */
  2810. UInt<value_size> & operator++()
  2811. {
  2812. AddOne();
  2813. return *this;
  2814. }
  2815. /*!
  2816. Postfix operator e.g variable++
  2817. */
  2818. UInt<value_size> operator++(int)
  2819. {
  2820. UInt<value_size> temp( *this );
  2821. AddOne();
  2822. return temp;
  2823. }
  2824. UInt<value_size> & operator--()
  2825. {
  2826. SubOne();
  2827. return *this;
  2828. }
  2829. UInt<value_size> operator--(int)
  2830. {
  2831. UInt<value_size> temp( *this );
  2832. SubOne();
  2833. return temp;
  2834. }
  2835. /*!
  2836. *
  2837. * bitwise operators
  2838. *
  2839. */
  2840. UInt<value_size> operator~() const
  2841. {
  2842. UInt<value_size> temp( *this );
  2843. temp.BitNot();
  2844. return temp;
  2845. }
  2846. UInt<value_size> operator&(const UInt<value_size> & p2) const
  2847. {
  2848. UInt<value_size> temp( *this );
  2849. temp.BitAnd(p2);
  2850. return temp;
  2851. }
  2852. UInt<value_size> & operator&=(const UInt<value_size> & p2)
  2853. {
  2854. BitAnd(p2);
  2855. return *this;
  2856. }
  2857. UInt<value_size> operator|(const UInt<value_size> & p2) const
  2858. {
  2859. UInt<value_size> temp( *this );
  2860. temp.BitOr(p2);
  2861. return temp;
  2862. }
  2863. UInt<value_size> & operator|=(const UInt<value_size> & p2)
  2864. {
  2865. BitOr(p2);
  2866. return *this;
  2867. }
  2868. UInt<value_size> operator^(const UInt<value_size> & p2) const
  2869. {
  2870. UInt<value_size> temp( *this );
  2871. temp.BitXor(p2);
  2872. return temp;
  2873. }
  2874. UInt<value_size> & operator^=(const UInt<value_size> & p2)
  2875. {
  2876. BitXor(p2);
  2877. return *this;
  2878. }
  2879. UInt<value_size> operator>>(int move) const
  2880. {
  2881. UInt<value_size> temp( *this );
  2882. temp.Rcr(move);
  2883. return temp;
  2884. }
  2885. UInt<value_size> & operator>>=(int move)
  2886. {
  2887. Rcr(move);
  2888. return *this;
  2889. }
  2890. UInt<value_size> operator<<(int move) const
  2891. {
  2892. UInt<value_size> temp( *this );
  2893. temp.Rcl(move);
  2894. return temp;
  2895. }
  2896. UInt<value_size> & operator<<=(int move)
  2897. {
  2898. Rcl(move);
  2899. return *this;
  2900. }
  2901. /*!
  2902. *
  2903. * input/output operators for standard streams
  2904. *
  2905. * (they are very simple, in the future they should be changed)
  2906. *
  2907. */
  2908. private:
  2909. /*!
  2910. an auxiliary method for outputing to standard streams
  2911. */
  2912. template<class ostream_type, class string_type>
  2913. static ostream_type & OutputToStream(ostream_type & s, const UInt<value_size> & l)
  2914. {
  2915. string_type ss;
  2916. l.ToString(ss);
  2917. s << ss;
  2918. return s;
  2919. }
  2920. public:
  2921. /*!
  2922. output to standard streams
  2923. */
  2924. friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
  2925. {
  2926. return OutputToStream<std::ostream, std::string>(s, l);
  2927. }
  2928. #ifndef TTMATH_DONT_USE_WCHAR
  2929. /*!
  2930. output to standard streams
  2931. */
  2932. friend std::wostream & operator<<(std::wostream & s, const UInt<value_size> & l)
  2933. {
  2934. return OutputToStream<std::wostream, std::wstring>(s, l);
  2935. }
  2936. #endif
  2937. private:
  2938. /*!
  2939. an auxiliary method for reading from standard streams
  2940. */
  2941. template<class istream_type, class string_type, class char_type>
  2942. static istream_type & InputFromStream(istream_type & s, UInt<value_size> & l)
  2943. {
  2944. string_type ss;
  2945. // char or wchar_t for operator>>
  2946. char_type z;
  2947. // operator>> omits white characters if they're set for ommiting
  2948. s >> z;
  2949. // we're reading only digits (base=10)
  2950. while( s.good() && Misc::CharToDigit(z, 10)>=0 )
  2951. {
  2952. ss += z;
  2953. z = static_cast<char_type>(s.get());
  2954. }
  2955. // we're leaving the last read character
  2956. // (it's not belonging to the value)
  2957. s.unget();
  2958. l.FromString(ss);
  2959. return s;
  2960. }
  2961. public:
  2962. /*!
  2963. input from standard streams
  2964. */
  2965. friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
  2966. {
  2967. return InputFromStream<std::istream, std::string, char>(s, l);
  2968. }
  2969. #ifndef TTMATH_DONT_USE_WCHAR
  2970. /*!
  2971. input from standard streams
  2972. */
  2973. friend std::wistream & operator>>(std::wistream & s, UInt<value_size> & l)
  2974. {
  2975. return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
  2976. }
  2977. #endif
  2978. /*
  2979. Following methods are defined in:
  2980. ttmathuint_x86.h
  2981. ttmathuint_x86_64.h
  2982. ttmathuint_noasm.h
  2983. */
  2984. #ifdef TTMATH_NOASM
  2985. static uint AddTwoWords(uint a, uint b, uint carry, uint * result);
  2986. static uint SubTwoWords(uint a, uint b, uint carry, uint * result);
  2987. #ifdef TTMATH_PLATFORM64
  2988. union uint_
  2989. {
  2990. struct
  2991. {
  2992. unsigned int low; // 32 bit
  2993. unsigned int high; // 32 bit
  2994. } u_;
  2995. uint u; // 64 bit
  2996. };
  2997. static void DivTwoWords2(uint a,uint b, uint c, uint * r, uint * rest);
  2998. static uint DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_);
  2999. static uint DivTwoWordsUnnormalize(uint u, uint d);
  3000. static unsigned int DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_);
  3001. static void MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_);
  3002. #endif // TTMATH_PLATFORM64
  3003. #endif // TTMATH_NOASM
  3004. private:
  3005. uint Rcl2_one(uint c);
  3006. uint Rcr2_one(uint c);
  3007. uint Rcl2(uint bits, uint c);
  3008. uint Rcr2(uint bits, uint c);
  3009. public:
  3010. static const char * LibTypeStr();
  3011. static LibTypeCode LibType();
  3012. uint Add(const UInt<value_size> & ss2, uint c=0);
  3013. uint AddInt(uint value, uint index = 0);
  3014. uint AddTwoInts(uint x2, uint x1, uint index);
  3015. static uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
  3016. uint Sub(const UInt<value_size> & ss2, uint c=0);
  3017. uint SubInt(uint value, uint index = 0);
  3018. static uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
  3019. static sint FindLeadingBitInWord(uint x);
  3020. static sint FindLowestBitInWord(uint x);
  3021. static uint SetBitInWord(uint & value, uint bit);
  3022. static void MulTwoWords(uint a, uint b, uint * result_high, uint * result_low);
  3023. static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
  3024. };
  3025. /*!
  3026. this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array"
  3027. when compiling Mul3Big2() method
  3028. */
  3029. template<>
  3030. class UInt<0>
  3031. {
  3032. public:
  3033. uint table[1];
  3034. void Mul2Big(const UInt<0> &, UInt<0> &) { TTMATH_ASSERT(false) };
  3035. void SetZero() { TTMATH_ASSERT(false) };
  3036. uint AddTwoInts(uint, uint, uint) { TTMATH_ASSERT(false) return 0; };
  3037. };
  3038. } //namespace
  3039. #include "ttmathuint_x86.h"
  3040. #include "ttmathuint_x86_64.h"
  3041. #include "ttmathuint_noasm.h"
  3042. #endif