mpz.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <string.h>
  27. #include <assert.h>
  28. #include "py/mpz.h"
  29. #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
  30. #define DIG_SIZE (MPZ_DIG_SIZE)
  31. #define DIG_MASK ((MPZ_LONG_1 << DIG_SIZE) - 1)
  32. #define DIG_MSB (MPZ_LONG_1 << (DIG_SIZE - 1))
  33. #define DIG_BASE (MPZ_LONG_1 << DIG_SIZE)
  34. /*
  35. mpz is an arbitrary precision integer type with a public API.
  36. mpn functions act on non-negative integers represented by an array of generalised
  37. digits (eg a word per digit). You also need to specify separately the length of the
  38. array. There is no public API for mpn. Rather, the functions are used by mpz to
  39. implement its features.
  40. Integer values are stored little endian (first digit is first in memory).
  41. Definition of normalise: ?
  42. */
  43. STATIC size_t mpn_remove_trailing_zeros(mpz_dig_t *oidig, mpz_dig_t *idig) {
  44. for (--idig; idig >= oidig && *idig == 0; --idig) {
  45. }
  46. return idig + 1 - oidig;
  47. }
  48. /* compares i with j
  49. returns sign(i - j)
  50. assumes i, j are normalised
  51. */
  52. STATIC int mpn_cmp(const mpz_dig_t *idig, size_t ilen, const mpz_dig_t *jdig, size_t jlen) {
  53. if (ilen < jlen) { return -1; }
  54. if (ilen > jlen) { return 1; }
  55. for (idig += ilen, jdig += ilen; ilen > 0; --ilen) {
  56. mpz_dbl_dig_signed_t cmp = (mpz_dbl_dig_t)*(--idig) - (mpz_dbl_dig_t)*(--jdig);
  57. if (cmp < 0) { return -1; }
  58. if (cmp > 0) { return 1; }
  59. }
  60. return 0;
  61. }
  62. /* computes i = j << n
  63. returns number of digits in i
  64. assumes enough memory in i; assumes normalised j; assumes n > 0
  65. can have i, j pointing to same memory
  66. */
  67. STATIC size_t mpn_shl(mpz_dig_t *idig, mpz_dig_t *jdig, size_t jlen, mp_uint_t n) {
  68. mp_uint_t n_whole = (n + DIG_SIZE - 1) / DIG_SIZE;
  69. mp_uint_t n_part = n % DIG_SIZE;
  70. if (n_part == 0) {
  71. n_part = DIG_SIZE;
  72. }
  73. // start from the high end of the digit arrays
  74. idig += jlen + n_whole - 1;
  75. jdig += jlen - 1;
  76. // shift the digits
  77. mpz_dbl_dig_t d = 0;
  78. for (size_t i = jlen; i > 0; i--, idig--, jdig--) {
  79. d |= *jdig;
  80. *idig = (d >> (DIG_SIZE - n_part)) & DIG_MASK;
  81. d <<= DIG_SIZE;
  82. }
  83. // store remaining bits
  84. *idig = (d >> (DIG_SIZE - n_part)) & DIG_MASK;
  85. idig -= n_whole - 1;
  86. memset(idig, 0, (n_whole - 1) * sizeof(mpz_dig_t));
  87. // work out length of result
  88. jlen += n_whole;
  89. while (jlen != 0 && idig[jlen - 1] == 0) {
  90. jlen--;
  91. }
  92. // return length of result
  93. return jlen;
  94. }
  95. /* computes i = j >> n
  96. returns number of digits in i
  97. assumes enough memory in i; assumes normalised j; assumes n > 0
  98. can have i, j pointing to same memory
  99. */
  100. STATIC size_t mpn_shr(mpz_dig_t *idig, mpz_dig_t *jdig, size_t jlen, mp_uint_t n) {
  101. mp_uint_t n_whole = n / DIG_SIZE;
  102. mp_uint_t n_part = n % DIG_SIZE;
  103. if (n_whole >= jlen) {
  104. return 0;
  105. }
  106. jdig += n_whole;
  107. jlen -= n_whole;
  108. for (size_t i = jlen; i > 0; i--, idig++, jdig++) {
  109. mpz_dbl_dig_t d = *jdig;
  110. if (i > 1) {
  111. d |= (mpz_dbl_dig_t)jdig[1] << DIG_SIZE;
  112. }
  113. d >>= n_part;
  114. *idig = d & DIG_MASK;
  115. }
  116. if (idig[-1] == 0) {
  117. jlen--;
  118. }
  119. return jlen;
  120. }
  121. /* computes i = j + k
  122. returns number of digits in i
  123. assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
  124. can have i, j, k pointing to same memory
  125. */
  126. STATIC size_t mpn_add(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen) {
  127. mpz_dig_t *oidig = idig;
  128. mpz_dbl_dig_t carry = 0;
  129. jlen -= klen;
  130. for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) {
  131. carry += (mpz_dbl_dig_t)*jdig + (mpz_dbl_dig_t)*kdig;
  132. *idig = carry & DIG_MASK;
  133. carry >>= DIG_SIZE;
  134. }
  135. for (; jlen > 0; --jlen, ++idig, ++jdig) {
  136. carry += *jdig;
  137. *idig = carry & DIG_MASK;
  138. carry >>= DIG_SIZE;
  139. }
  140. if (carry != 0) {
  141. *idig++ = carry;
  142. }
  143. return idig - oidig;
  144. }
  145. /* computes i = j - k
  146. returns number of digits in i
  147. assumes enough memory in i; assumes normalised j, k; assumes j >= k
  148. can have i, j, k pointing to same memory
  149. */
  150. STATIC size_t mpn_sub(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen) {
  151. mpz_dig_t *oidig = idig;
  152. mpz_dbl_dig_signed_t borrow = 0;
  153. jlen -= klen;
  154. for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) {
  155. borrow += (mpz_dbl_dig_t)*jdig - (mpz_dbl_dig_t)*kdig;
  156. *idig = borrow & DIG_MASK;
  157. borrow >>= DIG_SIZE;
  158. }
  159. for (; jlen > 0; --jlen, ++idig, ++jdig) {
  160. borrow += *jdig;
  161. *idig = borrow & DIG_MASK;
  162. borrow >>= DIG_SIZE;
  163. }
  164. return mpn_remove_trailing_zeros(oidig, idig);
  165. }
  166. #if MICROPY_OPT_MPZ_BITWISE
  167. /* computes i = j & k
  168. returns number of digits in i
  169. assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen (jlen argument not needed)
  170. can have i, j, k pointing to same memory
  171. */
  172. STATIC size_t mpn_and(mpz_dig_t *idig, const mpz_dig_t *jdig, const mpz_dig_t *kdig, size_t klen) {
  173. mpz_dig_t *oidig = idig;
  174. for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) {
  175. *idig = *jdig & *kdig;
  176. }
  177. return mpn_remove_trailing_zeros(oidig, idig);
  178. }
  179. #endif
  180. /* i = -((-j) & (-k)) = ~((~j + 1) & (~k + 1)) + 1
  181. i = (j & (-k)) = (j & (~k + 1)) = ( j & (~k + 1))
  182. i = ((-j) & k) = ((~j + 1) & k) = ((~j + 1) & k )
  183. computes general form:
  184. i = (im ^ (((j ^ jm) + jc) & ((k ^ km) + kc))) + ic where Xm = Xc == 0 ? 0 : DIG_MASK
  185. returns number of digits in i
  186. assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
  187. can have i, j, k pointing to same memory
  188. */
  189. STATIC size_t mpn_and_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen,
  190. mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
  191. mpz_dig_t *oidig = idig;
  192. mpz_dig_t imask = (0 == carryi) ? 0 : DIG_MASK;
  193. mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
  194. mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
  195. for (; jlen > 0; ++idig, ++jdig) {
  196. carryj += *jdig ^ jmask;
  197. carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
  198. carryi += ((carryj & carryk) ^ imask) & DIG_MASK;
  199. *idig = carryi & DIG_MASK;
  200. carryk >>= DIG_SIZE;
  201. carryj >>= DIG_SIZE;
  202. carryi >>= DIG_SIZE;
  203. }
  204. if (0 != carryi) {
  205. *idig++ = carryi;
  206. }
  207. return mpn_remove_trailing_zeros(oidig, idig);
  208. }
  209. #if MICROPY_OPT_MPZ_BITWISE
  210. /* computes i = j | k
  211. returns number of digits in i
  212. assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
  213. can have i, j, k pointing to same memory
  214. */
  215. STATIC size_t mpn_or(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen) {
  216. mpz_dig_t *oidig = idig;
  217. jlen -= klen;
  218. for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) {
  219. *idig = *jdig | *kdig;
  220. }
  221. for (; jlen > 0; --jlen, ++idig, ++jdig) {
  222. *idig = *jdig;
  223. }
  224. return idig - oidig;
  225. }
  226. #endif
  227. /* i = -((-j) | (-k)) = ~((~j + 1) | (~k + 1)) + 1
  228. i = -(j | (-k)) = -(j | (~k + 1)) = ~( j | (~k + 1)) + 1
  229. i = -((-j) | k) = -((~j + 1) | k) = ~((~j + 1) | k ) + 1
  230. computes general form:
  231. i = ~(((j ^ jm) + jc) | ((k ^ km) + kc)) + 1 where Xm = Xc == 0 ? 0 : DIG_MASK
  232. returns number of digits in i
  233. assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
  234. can have i, j, k pointing to same memory
  235. */
  236. #if MICROPY_OPT_MPZ_BITWISE
  237. STATIC size_t mpn_or_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen,
  238. mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
  239. mpz_dig_t *oidig = idig;
  240. mpz_dbl_dig_t carryi = 1;
  241. mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
  242. mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
  243. for (; jlen > 0; ++idig, ++jdig) {
  244. carryj += *jdig ^ jmask;
  245. carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
  246. carryi += ((carryj | carryk) ^ DIG_MASK) & DIG_MASK;
  247. *idig = carryi & DIG_MASK;
  248. carryk >>= DIG_SIZE;
  249. carryj >>= DIG_SIZE;
  250. carryi >>= DIG_SIZE;
  251. }
  252. // At least one of j,k must be negative so the above for-loop runs at least
  253. // once. For carryi to be non-zero here it must be equal to 1 at the end of
  254. // each iteration of the loop. So the accumulation of carryi must overflow
  255. // each time, ie carryi += 0xff..ff. So carryj|carryk must be 0 in the
  256. // DIG_MASK bits on each iteration. But considering all cases of signs of
  257. // j,k one sees that this is not possible.
  258. assert(carryi == 0);
  259. return mpn_remove_trailing_zeros(oidig, idig);
  260. }
  261. #else
  262. STATIC size_t mpn_or_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen,
  263. mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
  264. mpz_dig_t *oidig = idig;
  265. mpz_dig_t imask = (0 == carryi) ? 0 : DIG_MASK;
  266. mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
  267. mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
  268. for (; jlen > 0; ++idig, ++jdig) {
  269. carryj += *jdig ^ jmask;
  270. carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
  271. carryi += ((carryj | carryk) ^ imask) & DIG_MASK;
  272. *idig = carryi & DIG_MASK;
  273. carryk >>= DIG_SIZE;
  274. carryj >>= DIG_SIZE;
  275. carryi >>= DIG_SIZE;
  276. }
  277. // See comment in above mpn_or_neg for why carryi must be 0.
  278. assert(carryi == 0);
  279. return mpn_remove_trailing_zeros(oidig, idig);
  280. }
  281. #endif
  282. #if MICROPY_OPT_MPZ_BITWISE
  283. /* computes i = j ^ k
  284. returns number of digits in i
  285. assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
  286. can have i, j, k pointing to same memory
  287. */
  288. STATIC size_t mpn_xor(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen) {
  289. mpz_dig_t *oidig = idig;
  290. jlen -= klen;
  291. for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) {
  292. *idig = *jdig ^ *kdig;
  293. }
  294. for (; jlen > 0; --jlen, ++idig, ++jdig) {
  295. *idig = *jdig;
  296. }
  297. return mpn_remove_trailing_zeros(oidig, idig);
  298. }
  299. #endif
  300. /* i = (-j) ^ (-k) = ~(j - 1) ^ ~(k - 1) = (j - 1) ^ (k - 1)
  301. i = -(j ^ (-k)) = -(j ^ ~(k - 1)) = ~(j ^ ~(k - 1)) + 1 = (j ^ (k - 1)) + 1
  302. i = -((-j) ^ k) = -(~(j - 1) ^ k) = ~(~(j - 1) ^ k) + 1 = ((j - 1) ^ k) + 1
  303. computes general form:
  304. i = ((j - 1 + jc) ^ (k - 1 + kc)) + ic
  305. returns number of digits in i
  306. assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
  307. can have i, j, k pointing to same memory
  308. */
  309. STATIC size_t mpn_xor_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, size_t jlen, const mpz_dig_t *kdig, size_t klen,
  310. mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
  311. mpz_dig_t *oidig = idig;
  312. for (; jlen > 0; ++idig, ++jdig) {
  313. carryj += *jdig + DIG_MASK;
  314. carryk += (--klen <= --jlen) ? (*kdig++ + DIG_MASK) : DIG_MASK;
  315. carryi += (carryj ^ carryk) & DIG_MASK;
  316. *idig = carryi & DIG_MASK;
  317. carryk >>= DIG_SIZE;
  318. carryj >>= DIG_SIZE;
  319. carryi >>= DIG_SIZE;
  320. }
  321. if (0 != carryi) {
  322. *idig++ = carryi;
  323. }
  324. return mpn_remove_trailing_zeros(oidig, idig);
  325. }
  326. /* computes i = i * d1 + d2
  327. returns number of digits in i
  328. assumes enough memory in i; assumes normalised i; assumes dmul != 0
  329. */
  330. STATIC size_t mpn_mul_dig_add_dig(mpz_dig_t *idig, size_t ilen, mpz_dig_t dmul, mpz_dig_t dadd) {
  331. mpz_dig_t *oidig = idig;
  332. mpz_dbl_dig_t carry = dadd;
  333. for (; ilen > 0; --ilen, ++idig) {
  334. carry += (mpz_dbl_dig_t)*idig * (mpz_dbl_dig_t)dmul; // will never overflow so long as DIG_SIZE <= 8*sizeof(mpz_dbl_dig_t)/2
  335. *idig = carry & DIG_MASK;
  336. carry >>= DIG_SIZE;
  337. }
  338. if (carry != 0) {
  339. *idig++ = carry;
  340. }
  341. return idig - oidig;
  342. }
  343. /* computes i = j * k
  344. returns number of digits in i
  345. assumes enough memory in i; assumes i is zeroed; assumes normalised j, k
  346. can have j, k point to same memory
  347. */
  348. STATIC size_t mpn_mul(mpz_dig_t *idig, mpz_dig_t *jdig, size_t jlen, mpz_dig_t *kdig, size_t klen) {
  349. mpz_dig_t *oidig = idig;
  350. size_t ilen = 0;
  351. for (; klen > 0; --klen, ++idig, ++kdig) {
  352. mpz_dig_t *id = idig;
  353. mpz_dbl_dig_t carry = 0;
  354. size_t jl = jlen;
  355. for (mpz_dig_t *jd = jdig; jl > 0; --jl, ++jd, ++id) {
  356. carry += (mpz_dbl_dig_t)*id + (mpz_dbl_dig_t)*jd * (mpz_dbl_dig_t)*kdig; // will never overflow so long as DIG_SIZE <= 8*sizeof(mpz_dbl_dig_t)/2
  357. *id = carry & DIG_MASK;
  358. carry >>= DIG_SIZE;
  359. }
  360. if (carry != 0) {
  361. *id++ = carry;
  362. }
  363. ilen = id - oidig;
  364. }
  365. return ilen;
  366. }
  367. /* natural_div - quo * den + new_num = old_num (ie num is replaced with rem)
  368. assumes den != 0
  369. assumes num_dig has enough memory to be extended by 1 digit
  370. assumes quo_dig has enough memory (as many digits as num)
  371. assumes quo_dig is filled with zeros
  372. */
  373. STATIC void mpn_div(mpz_dig_t *num_dig, size_t *num_len, const mpz_dig_t *den_dig, size_t den_len, mpz_dig_t *quo_dig, size_t *quo_len) {
  374. mpz_dig_t *orig_num_dig = num_dig;
  375. mpz_dig_t *orig_quo_dig = quo_dig;
  376. mpz_dig_t norm_shift = 0;
  377. mpz_dbl_dig_t lead_den_digit;
  378. // handle simple cases
  379. {
  380. int cmp = mpn_cmp(num_dig, *num_len, den_dig, den_len);
  381. if (cmp == 0) {
  382. *num_len = 0;
  383. quo_dig[0] = 1;
  384. *quo_len = 1;
  385. return;
  386. } else if (cmp < 0) {
  387. // numerator remains the same
  388. *quo_len = 0;
  389. return;
  390. }
  391. }
  392. // We need to normalise the denominator (leading bit of leading digit is 1)
  393. // so that the division routine works. Since the denominator memory is
  394. // read-only we do the normalisation on the fly, each time a digit of the
  395. // denominator is needed. We need to know is how many bits to shift by.
  396. // count number of leading zeros in leading digit of denominator
  397. {
  398. mpz_dig_t d = den_dig[den_len - 1];
  399. while ((d & DIG_MSB) == 0) {
  400. d <<= 1;
  401. ++norm_shift;
  402. }
  403. }
  404. // now need to shift numerator by same amount as denominator
  405. // first, increase length of numerator in case we need more room to shift
  406. num_dig[*num_len] = 0;
  407. ++(*num_len);
  408. for (mpz_dig_t *num = num_dig, carry = 0; num < num_dig + *num_len; ++num) {
  409. mpz_dig_t n = *num;
  410. *num = ((n << norm_shift) | carry) & DIG_MASK;
  411. carry = (mpz_dbl_dig_t)n >> (DIG_SIZE - norm_shift);
  412. }
  413. // cache the leading digit of the denominator
  414. lead_den_digit = (mpz_dbl_dig_t)den_dig[den_len - 1] << norm_shift;
  415. if (den_len >= 2) {
  416. lead_den_digit |= (mpz_dbl_dig_t)den_dig[den_len - 2] >> (DIG_SIZE - norm_shift);
  417. }
  418. // point num_dig to last digit in numerator
  419. num_dig += *num_len - 1;
  420. // calculate number of digits in quotient
  421. *quo_len = *num_len - den_len;
  422. // point to last digit to store for quotient
  423. quo_dig += *quo_len - 1;
  424. // keep going while we have enough digits to divide
  425. while (*num_len > den_len) {
  426. mpz_dbl_dig_t quo = ((mpz_dbl_dig_t)*num_dig << DIG_SIZE) | num_dig[-1];
  427. // get approximate quotient
  428. quo /= lead_den_digit;
  429. // Multiply quo by den and subtract from num to get remainder.
  430. // We have different code here to handle different compile-time
  431. // configurations of mpz:
  432. //
  433. // 1. DIG_SIZE is stricly less than half the number of bits
  434. // available in mpz_dbl_dig_t. In this case we can use a
  435. // slightly more optimal (in time and space) routine that
  436. // uses the extra bits in mpz_dbl_dig_signed_t to store a
  437. // sign bit.
  438. //
  439. // 2. DIG_SIZE is exactly half the number of bits available in
  440. // mpz_dbl_dig_t. In this (common) case we need to be careful
  441. // not to overflow the borrow variable. And the shifting of
  442. // borrow needs some special logic (it's a shift right with
  443. // round up).
  444. if (DIG_SIZE < 8 * sizeof(mpz_dbl_dig_t) / 2) {
  445. const mpz_dig_t *d = den_dig;
  446. mpz_dbl_dig_t d_norm = 0;
  447. mpz_dbl_dig_signed_t borrow = 0;
  448. for (mpz_dig_t *n = num_dig - den_len; n < num_dig; ++n, ++d) {
  449. d_norm = ((mpz_dbl_dig_t)*d << norm_shift) | (d_norm >> DIG_SIZE);
  450. borrow += (mpz_dbl_dig_t)*n - (mpz_dbl_dig_t)quo * (d_norm & DIG_MASK); // will overflow if DIG_SIZE >= 8*sizeof(mpz_dbl_dig_t)/2
  451. *n = borrow & DIG_MASK;
  452. borrow >>= DIG_SIZE;
  453. }
  454. borrow += *num_dig; // will overflow if DIG_SIZE >= 8*sizeof(mpz_dbl_dig_t)/2
  455. *num_dig = borrow & DIG_MASK;
  456. borrow >>= DIG_SIZE;
  457. // adjust quotient if it is too big
  458. for (; borrow != 0; --quo) {
  459. d = den_dig;
  460. d_norm = 0;
  461. mpz_dbl_dig_t carry = 0;
  462. for (mpz_dig_t *n = num_dig - den_len; n < num_dig; ++n, ++d) {
  463. d_norm = ((mpz_dbl_dig_t)*d << norm_shift) | (d_norm >> DIG_SIZE);
  464. carry += (mpz_dbl_dig_t)*n + (d_norm & DIG_MASK);
  465. *n = carry & DIG_MASK;
  466. carry >>= DIG_SIZE;
  467. }
  468. carry += *num_dig;
  469. *num_dig = carry & DIG_MASK;
  470. carry >>= DIG_SIZE;
  471. borrow += carry;
  472. }
  473. } else { // DIG_SIZE == 8 * sizeof(mpz_dbl_dig_t) / 2
  474. const mpz_dig_t *d = den_dig;
  475. mpz_dbl_dig_t d_norm = 0;
  476. mpz_dbl_dig_t borrow = 0;
  477. for (mpz_dig_t *n = num_dig - den_len; n < num_dig; ++n, ++d) {
  478. d_norm = ((mpz_dbl_dig_t)*d << norm_shift) | (d_norm >> DIG_SIZE);
  479. mpz_dbl_dig_t x = (mpz_dbl_dig_t)quo * (d_norm & DIG_MASK);
  480. if (x >= *n || *n - x <= borrow) {
  481. borrow += (mpz_dbl_dig_t)x - (mpz_dbl_dig_t)*n;
  482. *n = (-borrow) & DIG_MASK;
  483. borrow = (borrow >> DIG_SIZE) + ((borrow & DIG_MASK) == 0 ? 0 : 1); // shift-right with round-up
  484. } else {
  485. *n = ((mpz_dbl_dig_t)*n - (mpz_dbl_dig_t)x - (mpz_dbl_dig_t)borrow) & DIG_MASK;
  486. borrow = 0;
  487. }
  488. }
  489. if (borrow >= *num_dig) {
  490. borrow -= (mpz_dbl_dig_t)*num_dig;
  491. *num_dig = (-borrow) & DIG_MASK;
  492. borrow = (borrow >> DIG_SIZE) + ((borrow & DIG_MASK) == 0 ? 0 : 1); // shift-right with round-up
  493. } else {
  494. *num_dig = (*num_dig - borrow) & DIG_MASK;
  495. borrow = 0;
  496. }
  497. // adjust quotient if it is too big
  498. for (; borrow != 0; --quo) {
  499. d = den_dig;
  500. d_norm = 0;
  501. mpz_dbl_dig_t carry = 0;
  502. for (mpz_dig_t *n = num_dig - den_len; n < num_dig; ++n, ++d) {
  503. d_norm = ((mpz_dbl_dig_t)*d << norm_shift) | (d_norm >> DIG_SIZE);
  504. carry += (mpz_dbl_dig_t)*n + (d_norm & DIG_MASK);
  505. *n = carry & DIG_MASK;
  506. carry >>= DIG_SIZE;
  507. }
  508. carry += (mpz_dbl_dig_t)*num_dig;
  509. *num_dig = carry & DIG_MASK;
  510. carry >>= DIG_SIZE;
  511. //assert(borrow >= carry); // enable this to check the logic
  512. borrow -= carry;
  513. }
  514. }
  515. // store this digit of the quotient
  516. *quo_dig = quo & DIG_MASK;
  517. --quo_dig;
  518. // move down to next digit of numerator
  519. --num_dig;
  520. --(*num_len);
  521. }
  522. // unnormalise numerator (remainder now)
  523. for (mpz_dig_t *num = orig_num_dig + *num_len - 1, carry = 0; num >= orig_num_dig; --num) {
  524. mpz_dig_t n = *num;
  525. *num = ((n >> norm_shift) | carry) & DIG_MASK;
  526. carry = (mpz_dbl_dig_t)n << (DIG_SIZE - norm_shift);
  527. }
  528. // strip trailing zeros
  529. while (*quo_len > 0 && orig_quo_dig[*quo_len - 1] == 0) {
  530. --(*quo_len);
  531. }
  532. while (*num_len > 0 && orig_num_dig[*num_len - 1] == 0) {
  533. --(*num_len);
  534. }
  535. }
  536. #define MIN_ALLOC (2)
  537. void mpz_init_zero(mpz_t *z) {
  538. z->neg = 0;
  539. z->fixed_dig = 0;
  540. z->alloc = 0;
  541. z->len = 0;
  542. z->dig = NULL;
  543. }
  544. void mpz_init_from_int(mpz_t *z, mp_int_t val) {
  545. mpz_init_zero(z);
  546. mpz_set_from_int(z, val);
  547. }
  548. void mpz_init_fixed_from_int(mpz_t *z, mpz_dig_t *dig, size_t alloc, mp_int_t val) {
  549. z->neg = 0;
  550. z->fixed_dig = 1;
  551. z->alloc = alloc;
  552. z->len = 0;
  553. z->dig = dig;
  554. mpz_set_from_int(z, val);
  555. }
  556. void mpz_deinit(mpz_t *z) {
  557. if (z != NULL && !z->fixed_dig) {
  558. m_del(mpz_dig_t, z->dig, z->alloc);
  559. }
  560. }
  561. #if 0
  562. these functions are unused
  563. mpz_t *mpz_zero(void) {
  564. mpz_t *z = m_new_obj(mpz_t);
  565. mpz_init_zero(z);
  566. return z;
  567. }
  568. mpz_t *mpz_from_int(mp_int_t val) {
  569. mpz_t *z = mpz_zero();
  570. mpz_set_from_int(z, val);
  571. return z;
  572. }
  573. mpz_t *mpz_from_ll(long long val, bool is_signed) {
  574. mpz_t *z = mpz_zero();
  575. mpz_set_from_ll(z, val, is_signed);
  576. return z;
  577. }
  578. #if MICROPY_PY_BUILTINS_FLOAT
  579. mpz_t *mpz_from_float(mp_float_t val) {
  580. mpz_t *z = mpz_zero();
  581. mpz_set_from_float(z, val);
  582. return z;
  583. }
  584. #endif
  585. mpz_t *mpz_from_str(const char *str, size_t len, bool neg, unsigned int base) {
  586. mpz_t *z = mpz_zero();
  587. mpz_set_from_str(z, str, len, neg, base);
  588. return z;
  589. }
  590. #endif
  591. STATIC void mpz_free(mpz_t *z) {
  592. if (z != NULL) {
  593. m_del(mpz_dig_t, z->dig, z->alloc);
  594. m_del_obj(mpz_t, z);
  595. }
  596. }
  597. STATIC void mpz_need_dig(mpz_t *z, size_t need) {
  598. if (need < MIN_ALLOC) {
  599. need = MIN_ALLOC;
  600. }
  601. if (z->dig == NULL || z->alloc < need) {
  602. // if z has fixed digit buffer there's not much we can do as the caller will
  603. // be expecting a buffer with at least "need" bytes (but it shouldn't happen)
  604. assert(!z->fixed_dig);
  605. z->dig = m_renew(mpz_dig_t, z->dig, z->alloc, need);
  606. z->alloc = need;
  607. }
  608. }
  609. STATIC mpz_t *mpz_clone(const mpz_t *src) {
  610. mpz_t *z = m_new_obj(mpz_t);
  611. z->neg = src->neg;
  612. z->fixed_dig = 0;
  613. z->alloc = src->alloc;
  614. z->len = src->len;
  615. if (src->dig == NULL) {
  616. z->dig = NULL;
  617. } else {
  618. z->dig = m_new(mpz_dig_t, z->alloc);
  619. memcpy(z->dig, src->dig, src->alloc * sizeof(mpz_dig_t));
  620. }
  621. return z;
  622. }
  623. /* sets dest = src
  624. can have dest, src the same
  625. */
  626. void mpz_set(mpz_t *dest, const mpz_t *src) {
  627. mpz_need_dig(dest, src->len);
  628. dest->neg = src->neg;
  629. dest->len = src->len;
  630. memcpy(dest->dig, src->dig, src->len * sizeof(mpz_dig_t));
  631. }
  632. void mpz_set_from_int(mpz_t *z, mp_int_t val) {
  633. if (val == 0) {
  634. z->len = 0;
  635. return;
  636. }
  637. mpz_need_dig(z, MPZ_NUM_DIG_FOR_INT);
  638. mp_uint_t uval;
  639. if (val < 0) {
  640. z->neg = 1;
  641. uval = -val;
  642. } else {
  643. z->neg = 0;
  644. uval = val;
  645. }
  646. z->len = 0;
  647. while (uval > 0) {
  648. z->dig[z->len++] = uval & DIG_MASK;
  649. uval >>= DIG_SIZE;
  650. }
  651. }
  652. void mpz_set_from_ll(mpz_t *z, long long val, bool is_signed) {
  653. mpz_need_dig(z, MPZ_NUM_DIG_FOR_LL);
  654. unsigned long long uval;
  655. if (is_signed && val < 0) {
  656. z->neg = 1;
  657. uval = -val;
  658. } else {
  659. z->neg = 0;
  660. uval = val;
  661. }
  662. z->len = 0;
  663. while (uval > 0) {
  664. z->dig[z->len++] = uval & DIG_MASK;
  665. uval >>= DIG_SIZE;
  666. }
  667. }
  668. #if MICROPY_PY_BUILTINS_FLOAT
  669. void mpz_set_from_float(mpz_t *z, mp_float_t src) {
  670. #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
  671. typedef uint64_t mp_float_int_t;
  672. #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
  673. typedef uint32_t mp_float_int_t;
  674. #endif
  675. union {
  676. mp_float_t f;
  677. #if MP_ENDIANNESS_LITTLE
  678. struct { mp_float_int_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p;
  679. #else
  680. struct { mp_float_int_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p;
  681. #endif
  682. } u = {src};
  683. z->neg = u.p.sgn;
  684. if (u.p.exp == 0) {
  685. // value == 0 || value < 1
  686. mpz_set_from_int(z, 0);
  687. } else if (u.p.exp == ((1 << MP_FLOAT_EXP_BITS) - 1)) {
  688. // u.p.frc == 0 indicates inf, else NaN
  689. // should be handled by caller
  690. mpz_set_from_int(z, 0);
  691. } else {
  692. const int adj_exp = (int)u.p.exp - MP_FLOAT_EXP_BIAS;
  693. if (adj_exp < 0) {
  694. // value < 1 , truncates to 0
  695. mpz_set_from_int(z, 0);
  696. } else if (adj_exp == 0) {
  697. // 1 <= value < 2 , so truncates to 1
  698. mpz_set_from_int(z, 1);
  699. } else {
  700. // 2 <= value
  701. const int dig_cnt = (adj_exp + 1 + (DIG_SIZE - 1)) / DIG_SIZE;
  702. const unsigned int rem = adj_exp % DIG_SIZE;
  703. int dig_ind, shft;
  704. mp_float_int_t frc = u.p.frc | ((mp_float_int_t)1 << MP_FLOAT_FRAC_BITS);
  705. if (adj_exp < MP_FLOAT_FRAC_BITS) {
  706. shft = 0;
  707. dig_ind = 0;
  708. frc >>= MP_FLOAT_FRAC_BITS - adj_exp;
  709. } else {
  710. shft = (rem - MP_FLOAT_FRAC_BITS) % DIG_SIZE;
  711. dig_ind = (adj_exp - MP_FLOAT_FRAC_BITS) / DIG_SIZE;
  712. }
  713. mpz_need_dig(z, dig_cnt);
  714. z->len = dig_cnt;
  715. if (dig_ind != 0) {
  716. memset(z->dig, 0, dig_ind * sizeof(mpz_dig_t));
  717. }
  718. if (shft != 0) {
  719. z->dig[dig_ind++] = (frc << shft) & DIG_MASK;
  720. frc >>= DIG_SIZE - shft;
  721. }
  722. #if DIG_SIZE < (MP_FLOAT_FRAC_BITS + 1)
  723. while (dig_ind != dig_cnt) {
  724. z->dig[dig_ind++] = frc & DIG_MASK;
  725. frc >>= DIG_SIZE;
  726. }
  727. #else
  728. if (dig_ind != dig_cnt) {
  729. z->dig[dig_ind] = frc;
  730. }
  731. #endif
  732. }
  733. }
  734. }
  735. #endif
  736. // returns number of bytes from str that were processed
  737. size_t mpz_set_from_str(mpz_t *z, const char *str, size_t len, bool neg, unsigned int base) {
  738. assert(base <= 36);
  739. const char *cur = str;
  740. const char *top = str + len;
  741. mpz_need_dig(z, len * 8 / DIG_SIZE + 1);
  742. if (neg) {
  743. z->neg = 1;
  744. } else {
  745. z->neg = 0;
  746. }
  747. z->len = 0;
  748. for (; cur < top; ++cur) { // XXX UTF8 next char
  749. //mp_uint_t v = char_to_numeric(cur#); // XXX UTF8 get char
  750. mp_uint_t v = *cur;
  751. if ('0' <= v && v <= '9') {
  752. v -= '0';
  753. } else if ('A' <= v && v <= 'Z') {
  754. v -= 'A' - 10;
  755. } else if ('a' <= v && v <= 'z') {
  756. v -= 'a' - 10;
  757. } else {
  758. break;
  759. }
  760. if (v >= base) {
  761. break;
  762. }
  763. z->len = mpn_mul_dig_add_dig(z->dig, z->len, base, v);
  764. }
  765. return cur - str;
  766. }
  767. void mpz_set_from_bytes(mpz_t *z, bool big_endian, size_t len, const byte *buf) {
  768. int delta = 1;
  769. if (big_endian) {
  770. buf += len - 1;
  771. delta = -1;
  772. }
  773. mpz_need_dig(z, (len * 8 + DIG_SIZE - 1) / DIG_SIZE);
  774. mpz_dig_t d = 0;
  775. int num_bits = 0;
  776. z->neg = 0;
  777. z->len = 0;
  778. while (len) {
  779. while (len && num_bits < DIG_SIZE) {
  780. d |= *buf << num_bits;
  781. num_bits += 8;
  782. buf += delta;
  783. len--;
  784. }
  785. z->dig[z->len++] = d & DIG_MASK;
  786. // Need this #if because it's C undefined behavior to do: uint32_t >> 32
  787. #if DIG_SIZE != 8 && DIG_SIZE != 16 && DIG_SIZE != 32
  788. d >>= DIG_SIZE;
  789. #else
  790. d = 0;
  791. #endif
  792. num_bits -= DIG_SIZE;
  793. }
  794. z->len = mpn_remove_trailing_zeros(z->dig, z->dig + z->len);
  795. }
  796. #if 0
  797. these functions are unused
  798. bool mpz_is_pos(const mpz_t *z) {
  799. return z->len > 0 && z->neg == 0;
  800. }
  801. bool mpz_is_odd(const mpz_t *z) {
  802. return z->len > 0 && (z->dig[0] & 1) != 0;
  803. }
  804. bool mpz_is_even(const mpz_t *z) {
  805. return z->len == 0 || (z->dig[0] & 1) == 0;
  806. }
  807. #endif
  808. int mpz_cmp(const mpz_t *z1, const mpz_t *z2) {
  809. // to catch comparison of -0 with +0
  810. if (z1->len == 0 && z2->len == 0) {
  811. return 0;
  812. }
  813. int cmp = (int)z2->neg - (int)z1->neg;
  814. if (cmp != 0) {
  815. return cmp;
  816. }
  817. cmp = mpn_cmp(z1->dig, z1->len, z2->dig, z2->len);
  818. if (z1->neg != 0) {
  819. cmp = -cmp;
  820. }
  821. return cmp;
  822. }
  823. #if 0
  824. // obsolete
  825. // compares mpz with an integer that fits within DIG_SIZE bits
  826. mp_int_t mpz_cmp_sml_int(const mpz_t *z, mp_int_t sml_int) {
  827. mp_int_t cmp;
  828. if (z->neg == 0) {
  829. if (sml_int < 0) return 1;
  830. if (sml_int == 0) {
  831. if (z->len == 0) return 0;
  832. return 1;
  833. }
  834. if (z->len == 0) return -1;
  835. assert(sml_int < (1 << DIG_SIZE));
  836. if (z->len != 1) return 1;
  837. cmp = z->dig[0] - sml_int;
  838. } else {
  839. if (sml_int > 0) return -1;
  840. if (sml_int == 0) {
  841. if (z->len == 0) return 0;
  842. return -1;
  843. }
  844. if (z->len == 0) return 1;
  845. assert(sml_int > -(1 << DIG_SIZE));
  846. if (z->len != 1) return -1;
  847. cmp = -z->dig[0] - sml_int;
  848. }
  849. if (cmp < 0) return -1;
  850. if (cmp > 0) return 1;
  851. return 0;
  852. }
  853. #endif
  854. #if 0
  855. these functions are unused
  856. /* returns abs(z)
  857. */
  858. mpz_t *mpz_abs(const mpz_t *z) {
  859. mpz_t *z2 = mpz_clone(z);
  860. z2->neg = 0;
  861. return z2;
  862. }
  863. /* returns -z
  864. */
  865. mpz_t *mpz_neg(const mpz_t *z) {
  866. mpz_t *z2 = mpz_clone(z);
  867. z2->neg = 1 - z2->neg;
  868. return z2;
  869. }
  870. /* returns lhs + rhs
  871. can have lhs, rhs the same
  872. */
  873. mpz_t *mpz_add(const mpz_t *lhs, const mpz_t *rhs) {
  874. mpz_t *z = mpz_zero();
  875. mpz_add_inpl(z, lhs, rhs);
  876. return z;
  877. }
  878. /* returns lhs - rhs
  879. can have lhs, rhs the same
  880. */
  881. mpz_t *mpz_sub(const mpz_t *lhs, const mpz_t *rhs) {
  882. mpz_t *z = mpz_zero();
  883. mpz_sub_inpl(z, lhs, rhs);
  884. return z;
  885. }
  886. /* returns lhs * rhs
  887. can have lhs, rhs the same
  888. */
  889. mpz_t *mpz_mul(const mpz_t *lhs, const mpz_t *rhs) {
  890. mpz_t *z = mpz_zero();
  891. mpz_mul_inpl(z, lhs, rhs);
  892. return z;
  893. }
  894. /* returns lhs ** rhs
  895. can have lhs, rhs the same
  896. */
  897. mpz_t *mpz_pow(const mpz_t *lhs, const mpz_t *rhs) {
  898. mpz_t *z = mpz_zero();
  899. mpz_pow_inpl(z, lhs, rhs);
  900. return z;
  901. }
  902. /* computes new integers in quo and rem such that:
  903. quo * rhs + rem = lhs
  904. 0 <= rem < rhs
  905. can have lhs, rhs the same
  906. */
  907. void mpz_divmod(const mpz_t *lhs, const mpz_t *rhs, mpz_t **quo, mpz_t **rem) {
  908. *quo = mpz_zero();
  909. *rem = mpz_zero();
  910. mpz_divmod_inpl(*quo, *rem, lhs, rhs);
  911. }
  912. #endif
  913. /* computes dest = abs(z)
  914. can have dest, z the same
  915. */
  916. void mpz_abs_inpl(mpz_t *dest, const mpz_t *z) {
  917. if (dest != z) {
  918. mpz_set(dest, z);
  919. }
  920. dest->neg = 0;
  921. }
  922. /* computes dest = -z
  923. can have dest, z the same
  924. */
  925. void mpz_neg_inpl(mpz_t *dest, const mpz_t *z) {
  926. if (dest != z) {
  927. mpz_set(dest, z);
  928. }
  929. dest->neg = 1 - dest->neg;
  930. }
  931. /* computes dest = ~z (= -z - 1)
  932. can have dest, z the same
  933. */
  934. void mpz_not_inpl(mpz_t *dest, const mpz_t *z) {
  935. if (dest != z) {
  936. mpz_set(dest, z);
  937. }
  938. if (dest->len == 0) {
  939. mpz_need_dig(dest, 1);
  940. dest->dig[0] = 1;
  941. dest->len = 1;
  942. dest->neg = 1;
  943. } else if (dest->neg) {
  944. dest->neg = 0;
  945. mpz_dig_t k = 1;
  946. dest->len = mpn_sub(dest->dig, dest->dig, dest->len, &k, 1);
  947. } else {
  948. mpz_need_dig(dest, dest->len + 1);
  949. mpz_dig_t k = 1;
  950. dest->len = mpn_add(dest->dig, dest->dig, dest->len, &k, 1);
  951. dest->neg = 1;
  952. }
  953. }
  954. /* computes dest = lhs << rhs
  955. can have dest, lhs the same
  956. */
  957. void mpz_shl_inpl(mpz_t *dest, const mpz_t *lhs, mp_uint_t rhs) {
  958. if (lhs->len == 0 || rhs == 0) {
  959. mpz_set(dest, lhs);
  960. } else {
  961. mpz_need_dig(dest, lhs->len + (rhs + DIG_SIZE - 1) / DIG_SIZE);
  962. dest->len = mpn_shl(dest->dig, lhs->dig, lhs->len, rhs);
  963. dest->neg = lhs->neg;
  964. }
  965. }
  966. /* computes dest = lhs >> rhs
  967. can have dest, lhs the same
  968. */
  969. void mpz_shr_inpl(mpz_t *dest, const mpz_t *lhs, mp_uint_t rhs) {
  970. if (lhs->len == 0 || rhs == 0) {
  971. mpz_set(dest, lhs);
  972. } else {
  973. mpz_need_dig(dest, lhs->len);
  974. dest->len = mpn_shr(dest->dig, lhs->dig, lhs->len, rhs);
  975. dest->neg = lhs->neg;
  976. if (dest->neg) {
  977. // arithmetic shift right, rounding to negative infinity
  978. mp_uint_t n_whole = rhs / DIG_SIZE;
  979. mp_uint_t n_part = rhs % DIG_SIZE;
  980. mpz_dig_t round_up = 0;
  981. for (size_t i = 0; i < lhs->len && i < n_whole; i++) {
  982. if (lhs->dig[i] != 0) {
  983. round_up = 1;
  984. break;
  985. }
  986. }
  987. if (n_whole < lhs->len && (lhs->dig[n_whole] & ((1 << n_part) - 1)) != 0) {
  988. round_up = 1;
  989. }
  990. if (round_up) {
  991. if (dest->len == 0) {
  992. // dest == 0, so need to add 1 by hand (answer will be -1)
  993. dest->dig[0] = 1;
  994. dest->len = 1;
  995. } else {
  996. // dest > 0, so can use mpn_add to add 1
  997. dest->len = mpn_add(dest->dig, dest->dig, dest->len, &round_up, 1);
  998. }
  999. }
  1000. }
  1001. }
  1002. }
  1003. /* computes dest = lhs + rhs
  1004. can have dest, lhs, rhs the same
  1005. */
  1006. void mpz_add_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1007. if (mpn_cmp(lhs->dig, lhs->len, rhs->dig, rhs->len) < 0) {
  1008. const mpz_t *temp = lhs;
  1009. lhs = rhs;
  1010. rhs = temp;
  1011. }
  1012. if (lhs->neg == rhs->neg) {
  1013. mpz_need_dig(dest, lhs->len + 1);
  1014. dest->len = mpn_add(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1015. } else {
  1016. mpz_need_dig(dest, lhs->len);
  1017. dest->len = mpn_sub(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1018. }
  1019. dest->neg = lhs->neg;
  1020. }
  1021. /* computes dest = lhs - rhs
  1022. can have dest, lhs, rhs the same
  1023. */
  1024. void mpz_sub_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1025. bool neg = false;
  1026. if (mpn_cmp(lhs->dig, lhs->len, rhs->dig, rhs->len) < 0) {
  1027. const mpz_t *temp = lhs;
  1028. lhs = rhs;
  1029. rhs = temp;
  1030. neg = true;
  1031. }
  1032. if (lhs->neg != rhs->neg) {
  1033. mpz_need_dig(dest, lhs->len + 1);
  1034. dest->len = mpn_add(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1035. } else {
  1036. mpz_need_dig(dest, lhs->len);
  1037. dest->len = mpn_sub(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1038. }
  1039. if (neg) {
  1040. dest->neg = 1 - lhs->neg;
  1041. } else {
  1042. dest->neg = lhs->neg;
  1043. }
  1044. }
  1045. /* computes dest = lhs & rhs
  1046. can have dest, lhs, rhs the same
  1047. */
  1048. void mpz_and_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1049. // make sure lhs has the most digits
  1050. if (lhs->len < rhs->len) {
  1051. const mpz_t *temp = lhs;
  1052. lhs = rhs;
  1053. rhs = temp;
  1054. }
  1055. #if MICROPY_OPT_MPZ_BITWISE
  1056. if ((0 == lhs->neg) && (0 == rhs->neg)) {
  1057. mpz_need_dig(dest, lhs->len);
  1058. dest->len = mpn_and(dest->dig, lhs->dig, rhs->dig, rhs->len);
  1059. dest->neg = 0;
  1060. } else {
  1061. mpz_need_dig(dest, lhs->len + 1);
  1062. dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
  1063. lhs->neg == rhs->neg, 0 != lhs->neg, 0 != rhs->neg);
  1064. dest->neg = lhs->neg & rhs->neg;
  1065. }
  1066. #else
  1067. mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
  1068. dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
  1069. (lhs->neg == rhs->neg) ? lhs->neg : 0, lhs->neg, rhs->neg);
  1070. dest->neg = lhs->neg & rhs->neg;
  1071. #endif
  1072. }
  1073. /* computes dest = lhs | rhs
  1074. can have dest, lhs, rhs the same
  1075. */
  1076. void mpz_or_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1077. // make sure lhs has the most digits
  1078. if (lhs->len < rhs->len) {
  1079. const mpz_t *temp = lhs;
  1080. lhs = rhs;
  1081. rhs = temp;
  1082. }
  1083. #if MICROPY_OPT_MPZ_BITWISE
  1084. if ((0 == lhs->neg) && (0 == rhs->neg)) {
  1085. mpz_need_dig(dest, lhs->len);
  1086. dest->len = mpn_or(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1087. dest->neg = 0;
  1088. } else {
  1089. mpz_need_dig(dest, lhs->len + 1);
  1090. dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
  1091. 0 != lhs->neg, 0 != rhs->neg);
  1092. dest->neg = 1;
  1093. }
  1094. #else
  1095. mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
  1096. dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
  1097. (lhs->neg || rhs->neg), lhs->neg, rhs->neg);
  1098. dest->neg = lhs->neg | rhs->neg;
  1099. #endif
  1100. }
  1101. /* computes dest = lhs ^ rhs
  1102. can have dest, lhs, rhs the same
  1103. */
  1104. void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1105. // make sure lhs has the most digits
  1106. if (lhs->len < rhs->len) {
  1107. const mpz_t *temp = lhs;
  1108. lhs = rhs;
  1109. rhs = temp;
  1110. }
  1111. #if MICROPY_OPT_MPZ_BITWISE
  1112. if (lhs->neg == rhs->neg) {
  1113. mpz_need_dig(dest, lhs->len);
  1114. if (lhs->neg == 0) {
  1115. dest->len = mpn_xor(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1116. } else {
  1117. dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len, 0, 0, 0);
  1118. }
  1119. dest->neg = 0;
  1120. } else {
  1121. mpz_need_dig(dest, lhs->len + 1);
  1122. dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len, 1,
  1123. 0 == lhs->neg, 0 == rhs->neg);
  1124. dest->neg = 1;
  1125. }
  1126. #else
  1127. mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
  1128. dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
  1129. (lhs->neg != rhs->neg), 0 == lhs->neg, 0 == rhs->neg);
  1130. dest->neg = lhs->neg ^ rhs->neg;
  1131. #endif
  1132. }
  1133. /* computes dest = lhs * rhs
  1134. can have dest, lhs, rhs the same
  1135. */
  1136. void mpz_mul_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1137. if (lhs->len == 0 || rhs->len == 0) {
  1138. mpz_set_from_int(dest, 0);
  1139. return;
  1140. }
  1141. mpz_t *temp = NULL;
  1142. if (lhs == dest) {
  1143. lhs = temp = mpz_clone(lhs);
  1144. if (rhs == dest) {
  1145. rhs = lhs;
  1146. }
  1147. } else if (rhs == dest) {
  1148. rhs = temp = mpz_clone(rhs);
  1149. }
  1150. mpz_need_dig(dest, lhs->len + rhs->len); // min mem l+r-1, max mem l+r
  1151. memset(dest->dig, 0, dest->alloc * sizeof(mpz_dig_t));
  1152. dest->len = mpn_mul(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
  1153. if (lhs->neg == rhs->neg) {
  1154. dest->neg = 0;
  1155. } else {
  1156. dest->neg = 1;
  1157. }
  1158. mpz_free(temp);
  1159. }
  1160. /* computes dest = lhs ** rhs
  1161. can have dest, lhs, rhs the same
  1162. */
  1163. void mpz_pow_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
  1164. if (lhs->len == 0 || rhs->neg != 0) {
  1165. mpz_set_from_int(dest, 0);
  1166. return;
  1167. }
  1168. if (rhs->len == 0) {
  1169. mpz_set_from_int(dest, 1);
  1170. return;
  1171. }
  1172. mpz_t *x = mpz_clone(lhs);
  1173. mpz_t *n = mpz_clone(rhs);
  1174. mpz_set_from_int(dest, 1);
  1175. while (n->len > 0) {
  1176. if ((n->dig[0] & 1) != 0) {
  1177. mpz_mul_inpl(dest, dest, x);
  1178. }
  1179. n->len = mpn_shr(n->dig, n->dig, n->len, 1);
  1180. if (n->len == 0) {
  1181. break;
  1182. }
  1183. mpz_mul_inpl(x, x, x);
  1184. }
  1185. mpz_free(x);
  1186. mpz_free(n);
  1187. }
  1188. /* computes dest = (lhs ** rhs) % mod
  1189. can have dest, lhs, rhs the same; mod can't be the same as dest
  1190. */
  1191. void mpz_pow3_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs, const mpz_t *mod) {
  1192. if (lhs->len == 0 || rhs->neg != 0) {
  1193. mpz_set_from_int(dest, 0);
  1194. return;
  1195. }
  1196. if (rhs->len == 0) {
  1197. mpz_set_from_int(dest, 1);
  1198. return;
  1199. }
  1200. mpz_t *x = mpz_clone(lhs);
  1201. mpz_t *n = mpz_clone(rhs);
  1202. mpz_t quo; mpz_init_zero(&quo);
  1203. mpz_set_from_int(dest, 1);
  1204. while (n->len > 0) {
  1205. if ((n->dig[0] & 1) != 0) {
  1206. mpz_mul_inpl(dest, dest, x);
  1207. mpz_divmod_inpl(&quo, dest, dest, mod);
  1208. }
  1209. n->len = mpn_shr(n->dig, n->dig, n->len, 1);
  1210. if (n->len == 0) {
  1211. break;
  1212. }
  1213. mpz_mul_inpl(x, x, x);
  1214. mpz_divmod_inpl(&quo, x, x, mod);
  1215. }
  1216. mpz_deinit(&quo);
  1217. mpz_free(x);
  1218. mpz_free(n);
  1219. }
  1220. #if 0
  1221. these functions are unused
  1222. /* computes gcd(z1, z2)
  1223. based on Knuth's modified gcd algorithm (I think?)
  1224. gcd(z1, z2) >= 0
  1225. gcd(0, 0) = 0
  1226. gcd(z, 0) = abs(z)
  1227. */
  1228. mpz_t *mpz_gcd(const mpz_t *z1, const mpz_t *z2) {
  1229. if (z1->len == 0) {
  1230. mpz_t *a = mpz_clone(z2);
  1231. a->neg = 0;
  1232. return a;
  1233. } else if (z2->len == 0) {
  1234. mpz_t *a = mpz_clone(z1);
  1235. a->neg = 0;
  1236. return a;
  1237. }
  1238. mpz_t *a = mpz_clone(z1);
  1239. mpz_t *b = mpz_clone(z2);
  1240. mpz_t c; mpz_init_zero(&c);
  1241. a->neg = 0;
  1242. b->neg = 0;
  1243. for (;;) {
  1244. if (mpz_cmp(a, b) < 0) {
  1245. if (a->len == 0) {
  1246. mpz_free(a);
  1247. mpz_deinit(&c);
  1248. return b;
  1249. }
  1250. mpz_t *t = a; a = b; b = t;
  1251. }
  1252. if (!(b->len >= 2 || (b->len == 1 && b->dig[0] > 1))) { // compute b > 0; could be mpz_cmp_small_int(b, 1) > 0
  1253. break;
  1254. }
  1255. mpz_set(&c, b);
  1256. do {
  1257. mpz_add_inpl(&c, &c, &c);
  1258. } while (mpz_cmp(&c, a) <= 0);
  1259. c.len = mpn_shr(c.dig, c.dig, c.len, 1);
  1260. mpz_sub_inpl(a, a, &c);
  1261. }
  1262. mpz_deinit(&c);
  1263. if (b->len == 1 && b->dig[0] == 1) { // compute b == 1; could be mpz_cmp_small_int(b, 1) == 0
  1264. mpz_free(a);
  1265. return b;
  1266. } else {
  1267. mpz_free(b);
  1268. return a;
  1269. }
  1270. }
  1271. /* computes lcm(z1, z2)
  1272. = abs(z1) / gcd(z1, z2) * abs(z2)
  1273. lcm(z1, z1) >= 0
  1274. lcm(0, 0) = 0
  1275. lcm(z, 0) = 0
  1276. */
  1277. mpz_t *mpz_lcm(const mpz_t *z1, const mpz_t *z2) {
  1278. if (z1->len == 0 || z2->len == 0) {
  1279. return mpz_zero();
  1280. }
  1281. mpz_t *gcd = mpz_gcd(z1, z2);
  1282. mpz_t *quo = mpz_zero();
  1283. mpz_t *rem = mpz_zero();
  1284. mpz_divmod_inpl(quo, rem, z1, gcd);
  1285. mpz_mul_inpl(rem, quo, z2);
  1286. mpz_free(gcd);
  1287. mpz_free(quo);
  1288. rem->neg = 0;
  1289. return rem;
  1290. }
  1291. #endif
  1292. /* computes new integers in quo and rem such that:
  1293. quo * rhs + rem = lhs
  1294. 0 <= rem < rhs
  1295. can have lhs, rhs the same
  1296. assumes rhs != 0 (undefined behaviour if it is)
  1297. */
  1298. void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs) {
  1299. assert(!mpz_is_zero(rhs));
  1300. mpz_need_dig(dest_quo, lhs->len + 1); // +1 necessary?
  1301. memset(dest_quo->dig, 0, (lhs->len + 1) * sizeof(mpz_dig_t));
  1302. dest_quo->len = 0;
  1303. mpz_need_dig(dest_rem, lhs->len + 1); // +1 necessary?
  1304. mpz_set(dest_rem, lhs);
  1305. mpn_div(dest_rem->dig, &dest_rem->len, rhs->dig, rhs->len, dest_quo->dig, &dest_quo->len);
  1306. // check signs and do Python style modulo
  1307. if (lhs->neg != rhs->neg) {
  1308. dest_quo->neg = 1;
  1309. if (!mpz_is_zero(dest_rem)) {
  1310. mpz_t mpzone; mpz_init_from_int(&mpzone, -1);
  1311. mpz_add_inpl(dest_quo, dest_quo, &mpzone);
  1312. mpz_add_inpl(dest_rem, dest_rem, rhs);
  1313. }
  1314. }
  1315. }
  1316. #if 0
  1317. these functions are unused
  1318. /* computes floor(lhs / rhs)
  1319. can have lhs, rhs the same
  1320. */
  1321. mpz_t *mpz_div(const mpz_t *lhs, const mpz_t *rhs) {
  1322. mpz_t *quo = mpz_zero();
  1323. mpz_t rem; mpz_init_zero(&rem);
  1324. mpz_divmod_inpl(quo, &rem, lhs, rhs);
  1325. mpz_deinit(&rem);
  1326. return quo;
  1327. }
  1328. /* computes lhs % rhs ( >= 0)
  1329. can have lhs, rhs the same
  1330. */
  1331. mpz_t *mpz_mod(const mpz_t *lhs, const mpz_t *rhs) {
  1332. mpz_t quo; mpz_init_zero(&quo);
  1333. mpz_t *rem = mpz_zero();
  1334. mpz_divmod_inpl(&quo, rem, lhs, rhs);
  1335. mpz_deinit(&quo);
  1336. return rem;
  1337. }
  1338. #endif
  1339. // must return actual int value if it fits in mp_int_t
  1340. mp_int_t mpz_hash(const mpz_t *z) {
  1341. mp_int_t val = 0;
  1342. mpz_dig_t *d = z->dig + z->len;
  1343. while (d-- > z->dig) {
  1344. val = (val << DIG_SIZE) | *d;
  1345. }
  1346. if (z->neg != 0) {
  1347. val = -val;
  1348. }
  1349. return val;
  1350. }
  1351. bool mpz_as_int_checked(const mpz_t *i, mp_int_t *value) {
  1352. mp_uint_t val = 0;
  1353. mpz_dig_t *d = i->dig + i->len;
  1354. while (d-- > i->dig) {
  1355. if (val > (~(WORD_MSBIT_HIGH) >> DIG_SIZE)) {
  1356. // will overflow
  1357. return false;
  1358. }
  1359. val = (val << DIG_SIZE) | *d;
  1360. }
  1361. if (i->neg != 0) {
  1362. val = -val;
  1363. }
  1364. *value = val;
  1365. return true;
  1366. }
  1367. bool mpz_as_uint_checked(const mpz_t *i, mp_uint_t *value) {
  1368. if (i->neg != 0) {
  1369. // can't represent signed values
  1370. return false;
  1371. }
  1372. mp_uint_t val = 0;
  1373. mpz_dig_t *d = i->dig + i->len;
  1374. while (d-- > i->dig) {
  1375. if (val > (~(WORD_MSBIT_HIGH) >> (DIG_SIZE - 1))) {
  1376. // will overflow
  1377. return false;
  1378. }
  1379. val = (val << DIG_SIZE) | *d;
  1380. }
  1381. *value = val;
  1382. return true;
  1383. }
  1384. // writes at most len bytes to buf (so buf should be zeroed before calling)
  1385. void mpz_as_bytes(const mpz_t *z, bool big_endian, size_t len, byte *buf) {
  1386. byte *b = buf;
  1387. if (big_endian) {
  1388. b += len;
  1389. }
  1390. mpz_dig_t *zdig = z->dig;
  1391. int bits = 0;
  1392. mpz_dbl_dig_t d = 0;
  1393. mpz_dbl_dig_t carry = 1;
  1394. for (size_t zlen = z->len; zlen > 0; --zlen) {
  1395. bits += DIG_SIZE;
  1396. d = (d << DIG_SIZE) | *zdig++;
  1397. for (; bits >= 8; bits -= 8, d >>= 8) {
  1398. mpz_dig_t val = d;
  1399. if (z->neg) {
  1400. val = (~val & 0xff) + carry;
  1401. carry = val >> 8;
  1402. }
  1403. if (big_endian) {
  1404. *--b = val;
  1405. if (b == buf) {
  1406. return;
  1407. }
  1408. } else {
  1409. *b++ = val;
  1410. if (b == buf + len) {
  1411. return;
  1412. }
  1413. }
  1414. }
  1415. }
  1416. }
  1417. #if MICROPY_PY_BUILTINS_FLOAT
  1418. mp_float_t mpz_as_float(const mpz_t *i) {
  1419. mp_float_t val = 0;
  1420. mpz_dig_t *d = i->dig + i->len;
  1421. while (d-- > i->dig) {
  1422. val = val * DIG_BASE + *d;
  1423. }
  1424. if (i->neg != 0) {
  1425. val = -val;
  1426. }
  1427. return val;
  1428. }
  1429. #endif
  1430. #if 0
  1431. this function is unused
  1432. char *mpz_as_str(const mpz_t *i, unsigned int base) {
  1433. char *s = m_new(char, mp_int_format_size(mpz_max_num_bits(i), base, NULL, '\0'));
  1434. mpz_as_str_inpl(i, base, NULL, 'a', '\0', s);
  1435. return s;
  1436. }
  1437. #endif
  1438. // assumes enough space as calculated by mp_int_format_size
  1439. // returns length of string, not including null byte
  1440. size_t mpz_as_str_inpl(const mpz_t *i, unsigned int base, const char *prefix, char base_char, char comma, char *str) {
  1441. if (str == NULL) {
  1442. return 0;
  1443. }
  1444. if (base < 2 || base > 32) {
  1445. str[0] = 0;
  1446. return 0;
  1447. }
  1448. size_t ilen = i->len;
  1449. char *s = str;
  1450. if (ilen == 0) {
  1451. if (prefix) {
  1452. while (*prefix)
  1453. *s++ = *prefix++;
  1454. }
  1455. *s++ = '0';
  1456. *s = '\0';
  1457. return s - str;
  1458. }
  1459. // make a copy of mpz digits, so we can do the div/mod calculation
  1460. mpz_dig_t *dig = m_new(mpz_dig_t, ilen);
  1461. memcpy(dig, i->dig, ilen * sizeof(mpz_dig_t));
  1462. // convert
  1463. char *last_comma = str;
  1464. bool done;
  1465. do {
  1466. mpz_dig_t *d = dig + ilen;
  1467. mpz_dbl_dig_t a = 0;
  1468. // compute next remainder
  1469. while (--d >= dig) {
  1470. a = (a << DIG_SIZE) | *d;
  1471. *d = a / base;
  1472. a %= base;
  1473. }
  1474. // convert to character
  1475. a += '0';
  1476. if (a > '9') {
  1477. a += base_char - '9' - 1;
  1478. }
  1479. *s++ = a;
  1480. // check if number is zero
  1481. done = true;
  1482. for (d = dig; d < dig + ilen; ++d) {
  1483. if (*d != 0) {
  1484. done = false;
  1485. break;
  1486. }
  1487. }
  1488. if (comma && (s - last_comma) == 3) {
  1489. *s++ = comma;
  1490. last_comma = s;
  1491. }
  1492. }
  1493. while (!done);
  1494. // free the copy of the digits array
  1495. m_del(mpz_dig_t, dig, ilen);
  1496. if (prefix) {
  1497. const char *p = &prefix[strlen(prefix)];
  1498. while (p > prefix) {
  1499. *s++ = *--p;
  1500. }
  1501. }
  1502. if (i->neg != 0) {
  1503. *s++ = '-';
  1504. }
  1505. // reverse string
  1506. for (char *u = str, *v = s - 1; u < v; ++u, --v) {
  1507. char temp = *u;
  1508. *u = *v;
  1509. *v = temp;
  1510. }
  1511. *s = '\0'; // null termination
  1512. return s - str;
  1513. }
  1514. #endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ