allpatches 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720
  1. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  2. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:40:46.838268769 +0000
  3. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:40:46.870268475 +0000
  4. @@ -0,0 +1 @@
  5. +sub1sp1n-reuse
  6. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  7. --- mpfr-4.0.1-a/VERSION 2018-02-07 12:50:31.000000000 +0000
  8. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:40:46.870268475 +0000
  9. @@ -1 +1 @@
  10. -4.0.1
  11. +4.0.1-p1
  12. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  13. --- mpfr-4.0.1-a/src/mpfr.h 2018-02-07 12:50:31.000000000 +0000
  14. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:40:46.870268475 +0000
  15. @@ -27,7 +27,7 @@
  16. #define MPFR_VERSION_MAJOR 4
  17. #define MPFR_VERSION_MINOR 0
  18. #define MPFR_VERSION_PATCHLEVEL 1
  19. -#define MPFR_VERSION_STRING "4.0.1"
  20. +#define MPFR_VERSION_STRING "4.0.1-p1"
  21. /* User macros:
  22. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  23. diff -Naurd mpfr-4.0.1-a/src/sub1sp.c mpfr-4.0.1-b/src/sub1sp.c
  24. --- mpfr-4.0.1-a/src/sub1sp.c 2018-01-09 12:30:58.000000000 +0000
  25. +++ mpfr-4.0.1-b/src/sub1sp.c 2018-04-27 12:40:46.858268585 +0000
  26. @@ -375,13 +375,15 @@
  27. }
  28. else /* cases (a), (c), (d) and (e) */
  29. {
  30. - ap[0] = -MPFR_LIMB_ONE;
  31. /* rb=1 in case (e) and case (c) */
  32. rb = d > GMP_NUMB_BITS + 1
  33. || (d == GMP_NUMB_BITS + 1 && cp[0] == MPFR_LIMB_HIGHBIT);
  34. /* sb = 1 in case (d) and (e) */
  35. sb = d > GMP_NUMB_BITS + 1
  36. || (d == GMP_NUMB_BITS + 1 && cp[0] > MPFR_LIMB_HIGHBIT);
  37. + /* Warning: only set ap[0] last, otherwise in case ap=cp,
  38. + the above comparisons involving cp[0] would be wrong */
  39. + ap[0] = -MPFR_LIMB_ONE;
  40. }
  41. }
  42. }
  43. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  44. --- mpfr-4.0.1-a/src/version.c 2018-02-07 12:50:31.000000000 +0000
  45. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:40:46.870268475 +0000
  46. @@ -25,5 +25,5 @@
  47. const char *
  48. mpfr_get_version (void)
  49. {
  50. - return "4.0.1";
  51. + return "4.0.1-p1";
  52. }
  53. diff -Naurd mpfr-4.0.1-a/tests/tsub.c mpfr-4.0.1-b/tests/tsub.c
  54. --- mpfr-4.0.1-a/tests/tsub.c 2018-01-09 12:30:58.000000000 +0000
  55. +++ mpfr-4.0.1-b/tests/tsub.c 2018-04-27 12:40:46.858268585 +0000
  56. @@ -22,12 +22,13 @@
  57. #include "mpfr-test.h"
  58. -#ifdef CHECK_EXTERNAL
  59. static int
  60. test_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
  61. {
  62. +#ifdef CHECK_EXTERNAL
  63. int res;
  64. int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
  65. +
  66. if (ok)
  67. {
  68. mpfr_print_raw (b);
  69. @@ -42,10 +43,69 @@
  70. printf ("\n");
  71. }
  72. return res;
  73. -}
  74. -#else
  75. -#define test_sub mpfr_sub
  76. +#else /* reuse test */
  77. + int inex;
  78. +
  79. + inex = mpfr_sub (a, b, c, rnd_mode);
  80. +
  81. + if (a != b && a != c && ! MPFR_IS_NAN (a))
  82. + {
  83. + mpfr_t t;
  84. + int reuse_b, reuse_c, inex_r;
  85. +
  86. + reuse_b = MPFR_PREC (a) == MPFR_PREC (b);
  87. + reuse_c = MPFR_PREC (a) == MPFR_PREC (c);
  88. +
  89. + if (reuse_b || reuse_c)
  90. + mpfr_init2 (t, MPFR_PREC (a));
  91. +
  92. + if (reuse_b)
  93. + {
  94. + mpfr_set (t, b, MPFR_RNDN);
  95. + inex_r = mpfr_sub (t, t, c, rnd_mode);
  96. + if (!(mpfr_equal_p (t, a) && SAME_SIGN (inex_r, inex)))
  97. + {
  98. + printf ("reuse of b error in b - c in %s for\n",
  99. + mpfr_print_rnd_mode (rnd_mode));
  100. + printf ("b = ");
  101. + mpfr_dump (b);
  102. + printf ("c = ");
  103. + mpfr_dump (c);
  104. + printf ("Expected "); mpfr_dump (a);
  105. + printf (" with inex = %d\n", inex);
  106. + printf ("Got "); mpfr_dump (t);
  107. + printf (" with inex = %d\n", inex_r);
  108. + exit (1);
  109. + }
  110. + }
  111. +
  112. + if (reuse_c)
  113. + {
  114. + mpfr_set (t, c, MPFR_RNDN);
  115. + inex_r = mpfr_sub (t, b, t, rnd_mode);
  116. + if (!(mpfr_equal_p (t, a) && SAME_SIGN (inex_r, inex)))
  117. + {
  118. + printf ("reuse of c error in b - c in %s for\n",
  119. + mpfr_print_rnd_mode (rnd_mode));
  120. + printf ("b = ");
  121. + mpfr_dump (b);
  122. + printf ("c = ");
  123. + mpfr_dump (c);
  124. + printf ("Expected "); mpfr_dump (a);
  125. + printf (" with inex = %d\n", inex);
  126. + printf ("Got "); mpfr_dump (t);
  127. + printf (" with inex = %d\n", inex_r);
  128. + exit (1);
  129. + }
  130. + }
  131. +
  132. + if (reuse_b || reuse_c)
  133. + mpfr_clear (t);
  134. + }
  135. +
  136. + return inex;
  137. #endif
  138. +}
  139. static void
  140. check_diverse (void)
  141. @@ -940,6 +1000,80 @@
  142. }
  143. }
  144. +/* Fails with r12281: "reuse of c error in b - c in MPFR_RNDN". */
  145. +static void
  146. +bug20180217 (void)
  147. +{
  148. + mpfr_t x, y, z1, z2;
  149. + int r, p, d, i, inex1, inex2;
  150. +
  151. + for (p = 3; p <= 3 + 4 * GMP_NUMB_BITS; p++)
  152. + {
  153. + mpfr_inits2 (p, x, y, z1, z2, (mpfr_ptr) 0);
  154. + for (d = p; d <= p+4; d++)
  155. + {
  156. + mpfr_set_ui (x, 1, MPFR_RNDN);
  157. + mpfr_set_ui_2exp (y, 1, -d, MPFR_RNDN);
  158. + for (i = 0; i < 3; i++)
  159. + {
  160. + RND_LOOP_NO_RNDF (r)
  161. + {
  162. + mpfr_set (z1, x, MPFR_RNDN);
  163. + if (d == p)
  164. + {
  165. + mpfr_nextbelow (z1);
  166. + if (i == 0)
  167. + inex1 = 0;
  168. + else if (r == MPFR_RNDD || r == MPFR_RNDZ ||
  169. + (r == MPFR_RNDN && i > 1))
  170. + {
  171. + mpfr_nextbelow (z1);
  172. + inex1 = -1;
  173. + }
  174. + else
  175. + inex1 = 1;
  176. + }
  177. + else if (r == MPFR_RNDD || r == MPFR_RNDZ ||
  178. + (r == MPFR_RNDN && d == p+1 && i > 0))
  179. + {
  180. + mpfr_nextbelow (z1);
  181. + inex1 = -1;
  182. + }
  183. + else
  184. + inex1 = 1;
  185. + inex2 = test_sub (z2, x, y, (mpfr_rnd_t) r);
  186. + if (!(mpfr_equal_p (z1, z2) && SAME_SIGN (inex1, inex2)))
  187. + {
  188. + printf ("Error in bug20180217 with "
  189. + "p=%d, d=%d, i=%d, %s\n", p, d, i,
  190. + mpfr_print_rnd_mode ((mpfr_rnd_t) r));
  191. + printf ("x = ");
  192. + mpfr_dump (x);
  193. + printf ("y = ");
  194. + mpfr_dump (y);
  195. + printf ("Expected "); mpfr_dump (z1);
  196. + printf (" with inex = %d\n", inex1);
  197. + printf ("Got "); mpfr_dump (z2);
  198. + printf (" with inex = %d\n", inex2);
  199. + exit (1);
  200. + }
  201. + }
  202. + if (i == 0)
  203. + mpfr_nextabove (y);
  204. + else
  205. + {
  206. + if (p < 6)
  207. + break;
  208. + mpfr_nextbelow (y);
  209. + mpfr_mul_ui (y, y, 25, MPFR_RNDD);
  210. + mpfr_div_2ui (y, y, 4, MPFR_RNDN);
  211. + }
  212. + }
  213. + }
  214. + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
  215. + }
  216. +}
  217. +
  218. #define TEST_FUNCTION test_sub
  219. #define TWO_ARGS
  220. #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
  221. @@ -962,6 +1096,7 @@
  222. check_inexact ();
  223. check_max_almosteven ();
  224. bug_ddefour ();
  225. + bug20180217 ();
  226. for (p=2; p<200; p++)
  227. for (i=0; i<50; i++)
  228. check_two_sum (p);
  229. diff -Naurd mpfr-4.0.1-a/tests/tsub1sp.c mpfr-4.0.1-b/tests/tsub1sp.c
  230. --- mpfr-4.0.1-a/tests/tsub1sp.c 2018-01-09 12:30:58.000000000 +0000
  231. +++ mpfr-4.0.1-b/tests/tsub1sp.c 2018-04-27 12:40:46.858268585 +0000
  232. @@ -284,6 +284,91 @@
  233. }
  234. }
  235. +static void
  236. +coverage (void)
  237. +{
  238. + mpfr_t a, b, c, d, u;
  239. + int inex;
  240. +
  241. + /* coverage test in mpfr_sub1sp: case d=1, limb > MPFR_LIMB_HIGHBIT, RNDF
  242. + and also RNDZ */
  243. + mpfr_init2 (a, 3 * GMP_NUMB_BITS);
  244. + mpfr_init2 (b, 3 * GMP_NUMB_BITS);
  245. + mpfr_init2 (c, 3 * GMP_NUMB_BITS);
  246. + mpfr_init2 (d, 3 * GMP_NUMB_BITS);
  247. + mpfr_init2 (u, 3 * GMP_NUMB_BITS);
  248. + mpfr_set_ui (b, 1, MPFR_RNDN);
  249. + mpfr_nextbelow (b); /* b = 1 - 2^(-p) */
  250. + mpfr_set_prec (c, GMP_NUMB_BITS);
  251. + mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);
  252. + mpfr_nextbelow (c);
  253. + mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) */
  254. + mpfr_prec_round (c, 3 * GMP_NUMB_BITS, MPFR_RNDN);
  255. + mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) - 2^(-p-1) */
  256. + /* b-c = c */
  257. + mpfr_sub (a, b, c, MPFR_RNDF);
  258. + mpfr_sub (d, b, c, MPFR_RNDD);
  259. + mpfr_sub (u, b, c, MPFR_RNDU);
  260. + /* check a = d or u */
  261. + MPFR_ASSERTN(mpfr_equal_p (a, d) || mpfr_equal_p (a, u));
  262. +
  263. + /* coverage test in mpfr_sub1sp: case d=p, RNDN, sb = 0, significand of b
  264. + is even but b<>2^e, (case 1e) */
  265. + mpfr_set_prec (a, 3 * GMP_NUMB_BITS);
  266. + mpfr_set_prec (b, 3 * GMP_NUMB_BITS);
  267. + mpfr_set_prec (c, 3 * GMP_NUMB_BITS);
  268. + mpfr_set_ui (b, 1, MPFR_RNDN);
  269. + mpfr_nextabove (b);
  270. + mpfr_nextabove (b);
  271. + mpfr_set_ui_2exp (c, 1, -3 * GMP_NUMB_BITS, MPFR_RNDN);
  272. + inex = mpfr_sub (a, b, c, MPFR_RNDN);
  273. + MPFR_ASSERTN(inex > 0);
  274. + MPFR_ASSERTN(mpfr_equal_p (a, b));
  275. +
  276. + mpfr_clear (a);
  277. + mpfr_clear (b);
  278. + mpfr_clear (c);
  279. + mpfr_clear (d);
  280. + mpfr_clear (u);
  281. +}
  282. +
  283. +/* bug in mpfr_sub1sp1n, made generic */
  284. +static void
  285. +bug20180217 (mpfr_prec_t pmax)
  286. +{
  287. + mpfr_t a, b, c;
  288. + int inex;
  289. + mpfr_prec_t p;
  290. +
  291. + for (p = MPFR_PREC_MIN; p <= pmax; p++)
  292. + {
  293. + mpfr_init2 (a, p);
  294. + mpfr_init2 (b, p);
  295. + mpfr_init2 (c, p);
  296. + mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
  297. + mpfr_set_ui_2exp (c, 1, -p-1, MPFR_RNDN); /* c = 2^(-p-1) */
  298. + /* a - b = 1 - 2^(-p-1) and should be rounded to 1 (case 2f of
  299. + mpfr_sub1sp) */
  300. + inex = mpfr_sub (a, b, c, MPFR_RNDN);
  301. + MPFR_ASSERTN(inex > 0);
  302. + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
  303. + /* check also when a=b */
  304. + mpfr_set_ui (a, 1, MPFR_RNDN);
  305. + inex = mpfr_sub (a, a, c, MPFR_RNDN);
  306. + MPFR_ASSERTN(inex > 0);
  307. + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
  308. + /* and when a=c */
  309. + mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
  310. + mpfr_set_ui_2exp (a, 1, -p-1, MPFR_RNDN);
  311. + inex = mpfr_sub (a, b, a, MPFR_RNDN);
  312. + MPFR_ASSERTN(inex > 0);
  313. + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
  314. + mpfr_clear (a);
  315. + mpfr_clear (b);
  316. + mpfr_clear (c);
  317. + }
  318. +}
  319. +
  320. int
  321. main (void)
  322. {
  323. @@ -291,6 +376,8 @@
  324. tests_start_mpfr ();
  325. + bug20180217 (1024);
  326. + coverage ();
  327. compare_sub_sub1sp ();
  328. test20170208 ();
  329. bug20170109 ();
  330. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  331. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:45:53.139452673 +0000
  332. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:45:53.171452379 +0000
  333. @@ -0,0 +1 @@
  334. +fma
  335. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  336. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:40:46.870268475 +0000
  337. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:45:53.171452379 +0000
  338. @@ -1 +1 @@
  339. -4.0.1-p1
  340. +4.0.1-p2
  341. diff -Naurd mpfr-4.0.1-a/src/fma.c mpfr-4.0.1-b/src/fma.c
  342. --- mpfr-4.0.1-a/src/fma.c 2018-01-09 12:30:58.000000000 +0000
  343. +++ mpfr-4.0.1-b/src/fma.c 2018-04-27 12:45:53.159452489 +0000
  344. @@ -225,194 +225,73 @@
  345. if (MPFR_IS_INF (u)) /* overflow */
  346. {
  347. + int sign_u = MPFR_SIGN (u);
  348. +
  349. MPFR_LOG_MSG (("Overflow on x*y\n", 0));
  350. + MPFR_GROUP_CLEAR (group); /* we no longer need u */
  351. /* Let's eliminate the obvious case where x*y and z have the
  352. same sign. No possible cancellation -> real overflow.
  353. Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
  354. - then |x*y| >= 2^(emax+1), and |x*y + z| >= 2^emax. This case
  355. + then |x*y| >= 2^(emax+1), and |x*y + z| > 2^emax. This case
  356. is also an overflow. */
  357. - if (MPFR_SIGN (u) == MPFR_SIGN (z) || e >= __gmpfr_emax + 3)
  358. + if (sign_u == MPFR_SIGN (z) || e >= __gmpfr_emax + 3)
  359. {
  360. - MPFR_GROUP_CLEAR (group);
  361. MPFR_SAVE_EXPO_FREE (expo);
  362. - return mpfr_overflow (s, rnd_mode, MPFR_SIGN (z));
  363. + return mpfr_overflow (s, rnd_mode, sign_u);
  364. }
  365. -
  366. - /* E(x) + E(y) <= emax+2, therefore |x*y| < 2^(emax+2), and
  367. - (x/4)*y does not overflow (let's recall that the result
  368. - is exact with an unbounded exponent range). It does not
  369. - underflow either, because x*y overflows and the exponent
  370. - range is large enough. */
  371. - inexact = mpfr_div_2ui (u, x, 2, MPFR_RNDN);
  372. - MPFR_ASSERTN (inexact == 0);
  373. - inexact = mpfr_mul (u, u, y, MPFR_RNDN);
  374. - MPFR_ASSERTN (inexact == 0);
  375. -
  376. - /* Now, we need to add z/4... But it may underflow! */
  377. - {
  378. - mpfr_t zo4;
  379. - mpfr_srcptr zz;
  380. - MPFR_BLOCK_DECL (flags);
  381. -
  382. - if (MPFR_GET_EXP (u) > MPFR_GET_EXP (z) &&
  383. - MPFR_GET_EXP (u) - MPFR_GET_EXP (z) > MPFR_PREC (u))
  384. - {
  385. - /* |z| < ulp(u)/2, therefore one can use z instead of z/4. */
  386. - zz = z;
  387. - }
  388. - else
  389. - {
  390. - mpfr_init2 (zo4, MPFR_PREC (z));
  391. - if (mpfr_div_2ui (zo4, z, 2, MPFR_RNDZ))
  392. - {
  393. - /* The division by 4 underflowed! */
  394. - MPFR_ASSERTN (0); /* TODO... */
  395. - }
  396. - zz = zo4;
  397. - }
  398. -
  399. - /* Let's recall that u = x*y/4 and zz = z/4 (or z if the
  400. - following addition would give the same result). */
  401. - MPFR_BLOCK (flags, inexact = mpfr_add (s, u, zz, rnd_mode));
  402. - /* u and zz have different signs, so that an overflow
  403. - is not possible. But an underflow is theoretically
  404. - possible! */
  405. - if (MPFR_UNDERFLOW (flags))
  406. - {
  407. - MPFR_ASSERTN (zz != z);
  408. - MPFR_ASSERTN (0); /* TODO... */
  409. - mpfr_clears (zo4, u, (mpfr_ptr) 0);
  410. - }
  411. - else
  412. - {
  413. - int inex2;
  414. -
  415. - if (zz != z)
  416. - mpfr_clear (zo4);
  417. - MPFR_GROUP_CLEAR (group);
  418. - MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
  419. - inex2 = mpfr_mul_2ui (s, s, 2, rnd_mode);
  420. - if (inex2) /* overflow */
  421. - {
  422. - inexact = inex2;
  423. - MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
  424. - }
  425. - goto end;
  426. - }
  427. - }
  428. }
  429. - else /* underflow: one has |xy| < 2^(emin-1). */
  430. + else /* underflow: one has |x*y| < 2^(emin-1). */
  431. {
  432. - unsigned long scale = 0;
  433. - mpfr_t scaled_z;
  434. - mpfr_srcptr new_z;
  435. - mpfr_exp_t diffexp;
  436. - mpfr_prec_t pzs;
  437. - int xy_underflows;
  438. -
  439. MPFR_LOG_MSG (("Underflow on x*y\n", 0));
  440. - /* Let's scale z so that ulp(z) > 2^emin and ulp(s) > 2^emin
  441. - (the + 1 on MPFR_PREC (s) is necessary because the exponent
  442. - of the result can be EXP(z) - 1). */
  443. - diffexp = MPFR_GET_EXP (z) - __gmpfr_emin;
  444. - pzs = MAX (MPFR_PREC (z), MPFR_PREC (s) + 1);
  445. - MPFR_LOG_MSG (("diffexp=%" MPFR_EXP_FSPEC "d pzs=%Pd\n",
  446. - diffexp, pzs));
  447. - if (diffexp <= pzs)
  448. - {
  449. - mpfr_uexp_t uscale;
  450. - mpfr_t scaled_v;
  451. - MPFR_BLOCK_DECL (flags);
  452. -
  453. - uscale = (mpfr_uexp_t) pzs - diffexp + 1;
  454. - MPFR_ASSERTN (uscale > 0);
  455. - MPFR_ASSERTN (uscale <= ULONG_MAX);
  456. - scale = uscale;
  457. - mpfr_init2 (scaled_z, MPFR_PREC (z));
  458. - inexact = mpfr_mul_2ui (scaled_z, z, scale, MPFR_RNDN);
  459. - MPFR_ASSERTN (inexact == 0); /* TODO: overflow case */
  460. - new_z = scaled_z;
  461. - /* Now we need to recompute u = xy * 2^scale. */
  462. - MPFR_BLOCK (flags,
  463. - if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
  464. - {
  465. - mpfr_init2 (scaled_v, precx);
  466. - mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
  467. - mpfr_mul (u, scaled_v, y, MPFR_RNDN);
  468. - }
  469. - else
  470. - {
  471. - mpfr_init2 (scaled_v, precy);
  472. - mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
  473. - mpfr_mul (u, x, scaled_v, MPFR_RNDN);
  474. - });
  475. - mpfr_clear (scaled_v);
  476. - MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
  477. - xy_underflows = MPFR_UNDERFLOW (flags);
  478. - }
  479. - else
  480. - {
  481. - new_z = z;
  482. - xy_underflows = 1;
  483. - }
  484. -
  485. - MPFR_LOG_MSG (("scale=%lu xy_underflows=%d\n",
  486. - scale, xy_underflows));
  487. -
  488. - if (xy_underflows)
  489. + /* Easy cases: when 2^(emin-1) <= 1/2 * min(ulp(z),ulp(s)),
  490. + one can replace x*y by sign(x*y) * 2^(emin-1). Note that
  491. + this is even true in case of equality for MPFR_RNDN thanks
  492. + to the even-rounding rule.
  493. + The + 1 on MPFR_PREC (s) is necessary because the exponent
  494. + of the result can be EXP(z) - 1. */
  495. + if (MPFR_GET_EXP (z) - __gmpfr_emin >=
  496. + MAX (MPFR_PREC (z), MPFR_PREC (s) + 1))
  497. {
  498. - /* Let's replace xy by sign(xy) * 2^(emin-1). */
  499. MPFR_PREC (u) = MPFR_PREC_MIN;
  500. mpfr_setmin (u, __gmpfr_emin);
  501. MPFR_SET_SIGN (u, MPFR_MULT_SIGN (MPFR_SIGN (x),
  502. MPFR_SIGN (y)));
  503. + mpfr_clear_flags ();
  504. + goto add;
  505. }
  506. - {
  507. - MPFR_BLOCK_DECL (flags);
  508. + MPFR_GROUP_CLEAR (group); /* we no longer need u */
  509. + }
  510. - MPFR_BLOCK (flags, inexact = mpfr_add (s, u, new_z, rnd_mode));
  511. - MPFR_LOG_MSG (("inexact=%d\n", inexact));
  512. - MPFR_GROUP_CLEAR (group);
  513. - if (scale != 0)
  514. - {
  515. - int inex2;
  516. + /* Let's use UBF to resolve the overflow/underflow issues. */
  517. + {
  518. + mpfr_ubf_t uu;
  519. + mp_size_t un;
  520. + mpfr_limb_ptr up;
  521. + MPFR_TMP_DECL(marker);
  522. - mpfr_clear (scaled_z);
  523. - /* Here an overflow is theoretically possible, in which case
  524. - the result may be wrong, hence the assert. An underflow
  525. - is not possible, but let's check that anyway. */
  526. - MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
  527. - MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
  528. - if (rnd_mode == MPFR_RNDN &&
  529. - MPFR_GET_EXP (s) == __gmpfr_emin - 1 + scale &&
  530. - mpfr_powerof2_raw (s))
  531. - {
  532. - MPFR_LOG_MSG (("Double rounding\n", 0));
  533. - rnd_mode = (MPFR_IS_NEG (s) ? inexact <= 0 : inexact >= 0)
  534. - ? MPFR_RNDZ : MPFR_RNDA;
  535. - }
  536. - inex2 = mpfr_div_2ui (s, s, scale, rnd_mode);
  537. - MPFR_LOG_MSG (("inex2=%d\n", inex2));
  538. - if (inex2) /* underflow */
  539. - inexact = inex2;
  540. - }
  541. - }
  542. + MPFR_LOG_MSG (("Use UBF\n", 0));
  543. - /* FIXME/TODO: I'm not sure that the following is correct.
  544. - Check for possible spurious exceptions due to intermediate
  545. - computations. */
  546. - MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
  547. - goto end;
  548. - }
  549. + MPFR_TMP_MARK (marker);
  550. + un = MPFR_LIMB_SIZE (x) + MPFR_LIMB_SIZE (y);
  551. + MPFR_TMP_INIT (up, uu, (mpfr_prec_t) un * GMP_NUMB_BITS, un);
  552. + mpfr_ubf_mul_exact (uu, x, y);
  553. + mpfr_clear_flags ();
  554. + inexact = mpfr_add (s, (mpfr_srcptr) uu, z, rnd_mode);
  555. + MPFR_UBF_CLEAR_EXP (uu);
  556. + MPFR_TMP_FREE (marker);
  557. + }
  558. + }
  559. + else
  560. + {
  561. + add:
  562. + inexact = mpfr_add (s, u, z, rnd_mode);
  563. + MPFR_GROUP_CLEAR (group);
  564. }
  565. - inexact = mpfr_add (s, u, z, rnd_mode);
  566. - MPFR_GROUP_CLEAR (group);
  567. MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
  568. - end:
  569. MPFR_SAVE_EXPO_FREE (expo);
  570. return mpfr_check_range (s, inexact, rnd_mode);
  571. }
  572. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  573. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:40:46.870268475 +0000
  574. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:45:53.171452379 +0000
  575. @@ -27,7 +27,7 @@
  576. #define MPFR_VERSION_MAJOR 4
  577. #define MPFR_VERSION_MINOR 0
  578. #define MPFR_VERSION_PATCHLEVEL 1
  579. -#define MPFR_VERSION_STRING "4.0.1-p1"
  580. +#define MPFR_VERSION_STRING "4.0.1-p2"
  581. /* User macros:
  582. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  583. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  584. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:40:46.870268475 +0000
  585. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:45:53.171452379 +0000
  586. @@ -25,5 +25,5 @@
  587. const char *
  588. mpfr_get_version (void)
  589. {
  590. - return "4.0.1-p1";
  591. + return "4.0.1-p2";
  592. }
  593. diff -Naurd mpfr-4.0.1-a/tests/tfma.c mpfr-4.0.1-b/tests/tfma.c
  594. --- mpfr-4.0.1-a/tests/tfma.c 2018-01-09 12:30:58.000000000 +0000
  595. +++ mpfr-4.0.1-b/tests/tfma.c 2018-04-27 12:45:53.163452452 +0000
  596. @@ -196,6 +196,238 @@
  597. }
  598. static void
  599. +test_overflow3 (void)
  600. +{
  601. + mpfr_t x, y, z, r;
  602. + int inex;
  603. + mpfr_prec_t p = 8;
  604. + mpfr_flags_t ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT, flags;
  605. + int i, j, k;
  606. + unsigned int neg;
  607. +
  608. + mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
  609. + for (i = 0; i < 2; i++)
  610. + {
  611. + mpfr_init2 (r, 2 * p + i);
  612. + mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
  613. + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
  614. + for (j = 1; j <= 2; j++)
  615. + for (k = 0; k <= 1; k++)
  616. + {
  617. + mpfr_set_si_2exp (z, -1, mpfr_get_emax () - mpfr_get_prec (r) - j,
  618. + MPFR_RNDN);
  619. + if (k)
  620. + mpfr_nextabove (z);
  621. + for (neg = 0; neg <= 3; neg++)
  622. + {
  623. + mpfr_clear_flags ();
  624. + /* (The following applies for neg = 0 or 2, all the signs
  625. + need to be reversed for neg = 1 or 3.)
  626. + We have x*y = 2^emax and
  627. + z = - 2^(emax-2p-i-j) * (1-k*2^(-p)), thus
  628. + x*y+z = 2^emax - 2^(emax-2p-i-j) + k*2^(emax-3p-i-j)
  629. + should overflow. Indeed it is >= the midpoint of
  630. + 2^emax - 2^(emax-2p-i) and 2^emax, the midpoint
  631. + being obtained for j = 1 and k = 0. */
  632. + inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
  633. + flags = __gmpfr_flags;
  634. + if (! mpfr_inf_p (r) || flags != ex_flags ||
  635. + ((neg & 1) == 0 ?
  636. + (inex <= 0 || MPFR_IS_NEG (r)) :
  637. + (inex >= 0 || MPFR_IS_POS (r))))
  638. + {
  639. + printf ("Error in test_overflow3 for "
  640. + "i=%d j=%d k=%d neg=%u\n", i, j, k, neg);
  641. + printf ("Expected %c@Inf@\n with inex %c 0 and flags:",
  642. + (neg & 1) == 0 ? '+' : '-',
  643. + (neg & 1) == 0 ? '>' : '<');
  644. + flags_out (ex_flags);
  645. + printf ("Got ");
  646. + mpfr_dump (r);
  647. + printf (" with inex = %d and flags:", inex);
  648. + flags_out (flags);
  649. + exit (1);
  650. + }
  651. + if (neg == 0 || neg == 2)
  652. + mpfr_neg (x, x, MPFR_RNDN);
  653. + if (neg == 1 || neg == 3)
  654. + mpfr_neg (y, y, MPFR_RNDN);
  655. + mpfr_neg (z, z, MPFR_RNDN);
  656. + } /* neg */
  657. + } /* k */
  658. + mpfr_clear (r);
  659. + } /* i */
  660. + mpfr_clears (x, y, z, (mpfr_ptr) 0);
  661. +}
  662. +
  663. +static void
  664. +test_overflow4 (void)
  665. +{
  666. + mpfr_t x, y, z, r1, r2;
  667. + mpfr_exp_t emax, e;
  668. + mpfr_prec_t px;
  669. + mpfr_flags_t flags1, flags2;
  670. + int inex1, inex2;
  671. + int ei, i, j;
  672. + int below;
  673. + unsigned int neg;
  674. +
  675. + emax = mpfr_get_emax ();
  676. +
  677. + mpfr_init2 (y, MPFR_PREC_MIN);
  678. + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
  679. +
  680. + mpfr_init2 (z, 8);
  681. +
  682. + for (px = 17; px < 256; px *= 2)
  683. + {
  684. + mpfr_init2 (x, px);
  685. + mpfr_inits2 (px - 8, r1, r2, (mpfr_ptr) 0);
  686. + for (ei = 0; ei <= 1; ei++)
  687. + {
  688. + e = ei ? emax : 0;
  689. + mpfr_set_ui_2exp (x, 1, e - 1, MPFR_RNDN);
  690. + mpfr_nextabove (x); /* x = 2^(e - 1) + 2^(e - px) */
  691. + /* x*y = 2^e + 2^(e - px + 1), which internally overflows
  692. + when e = emax. */
  693. + for (i = -4; i <= 4; i++)
  694. + for (j = 2; j <= 3; j++)
  695. + {
  696. + mpfr_set_si_2exp (z, -j, e - px + i, MPFR_RNDN);
  697. + /* If |z| <= 2^(e - px + 1), then x*y + z >= 2^e and
  698. + RZ(x*y + z) = 2^e with an unbounded exponent range.
  699. + If |z| > 2^(e - px + 1), then RZ(x*y + z) is the
  700. + predecessor of 2^e (since |z| < ulp(r)/2); this
  701. + occurs when i > 0 and when i = 0 and j > 2 */
  702. + mpfr_set_ui_2exp (r1, 1, e - 1, MPFR_RNDN);
  703. + below = i > 0 || (i == 0 && j > 2);
  704. + if (below)
  705. + mpfr_nextbelow (r1);
  706. + mpfr_clear_flags ();
  707. + inex1 = mpfr_mul_2ui (r1, r1, 1, MPFR_RNDZ);
  708. + if (below || e < emax)
  709. + {
  710. + inex1 = i == 0 && j == 2 ? 0 : -1;
  711. + flags1 = inex1 ? MPFR_FLAGS_INEXACT : 0;
  712. + }
  713. + else
  714. + {
  715. + MPFR_ASSERTN (inex1 < 0);
  716. + flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  717. + MPFR_ASSERTN (flags1 == __gmpfr_flags);
  718. + }
  719. + for (neg = 0; neg <= 3; neg++)
  720. + {
  721. + mpfr_clear_flags ();
  722. + inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDZ);
  723. + flags2 = __gmpfr_flags;
  724. + if (! (mpfr_equal_p (r1, r2) &&
  725. + SAME_SIGN (inex1, inex2) &&
  726. + flags1 == flags2))
  727. + {
  728. + printf ("Error in test_overflow4 for "
  729. + "px=%d ei=%d i=%d j=%d neg=%u\n",
  730. + (int) px, ei, i, j, neg);
  731. + printf ("Expected ");
  732. + mpfr_dump (r1);
  733. + printf ("with inex = %d and flags:", inex1);
  734. + flags_out (flags1);
  735. + printf ("Got ");
  736. + mpfr_dump (r2);
  737. + printf ("with inex = %d and flags:", inex2);
  738. + flags_out (flags2);
  739. + exit (1);
  740. + }
  741. + if (neg == 0 || neg == 2)
  742. + mpfr_neg (x, x, MPFR_RNDN);
  743. + if (neg == 1 || neg == 3)
  744. + mpfr_neg (y, y, MPFR_RNDN);
  745. + mpfr_neg (z, z, MPFR_RNDN);
  746. + mpfr_neg (r1, r1, MPFR_RNDN);
  747. + inex1 = - inex1;
  748. + }
  749. + }
  750. + }
  751. + mpfr_clears (x, r1, r2, (mpfr_ptr) 0);
  752. + }
  753. +
  754. + mpfr_clears (y, z, (mpfr_ptr) 0);
  755. +}
  756. +
  757. +static void
  758. +test_overflow5 (void)
  759. +{
  760. + mpfr_t x, y, z, r1, r2;
  761. + mpfr_exp_t emax;
  762. + int inex1, inex2;
  763. + int i, rnd;
  764. + unsigned int neg, negr;
  765. +
  766. + emax = mpfr_get_emax ();
  767. +
  768. + mpfr_init2 (x, 123);
  769. + mpfr_init2 (y, 45);
  770. + mpfr_init2 (z, 67);
  771. + mpfr_inits2 (89, r1, r2, (mpfr_ptr) 0);
  772. +
  773. + mpfr_set_ui_2exp (x, 1, emax - 1, MPFR_RNDN);
  774. +
  775. + for (i = 3; i <= 17; i++)
  776. + {
  777. + mpfr_set_ui (y, i, MPFR_RNDN);
  778. + mpfr_set_ui_2exp (z, 1, emax - 1, MPFR_RNDN);
  779. + for (neg = 0; neg < 8; neg++)
  780. + {
  781. + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
  782. + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
  783. + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
  784. +
  785. + /* |x*y + z| = (i +/- 1) * 2^(emax - 1) >= 2^emax (overflow)
  786. + and x*y + z has the same sign as x*y. */
  787. + negr = (neg ^ (neg >> 1)) & 1;
  788. +
  789. + RND_LOOP (rnd)
  790. + {
  791. + mpfr_set_inf (r1, 1);
  792. + if (MPFR_IS_LIKE_RNDZ ((mpfr_rnd_t) rnd, negr))
  793. + {
  794. + mpfr_nextbelow (r1);
  795. + inex1 = -1;
  796. + }
  797. + else
  798. + inex1 = 1;
  799. +
  800. + if (negr)
  801. + {
  802. + mpfr_neg (r1, r1, MPFR_RNDN);
  803. + inex1 = - inex1;
  804. + }
  805. +
  806. + mpfr_clear_flags ();
  807. + inex2 = mpfr_fma (r2, x, y, z, (mpfr_rnd_t) rnd);
  808. + MPFR_ASSERTN (__gmpfr_flags ==
  809. + (MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW));
  810. +
  811. + if (! (mpfr_equal_p (r1, r2) && SAME_SIGN (inex1, inex2)))
  812. + {
  813. + printf ("Error in test_overflow5 for i=%d neg=%u %s\n",
  814. + i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
  815. + printf ("Expected ");
  816. + mpfr_dump (r1);
  817. + printf ("with inex = %d\n", inex1);
  818. + printf ("Got ");
  819. + mpfr_dump (r2);
  820. + printf ("with inex = %d\n", inex2);
  821. + exit (1);
  822. + }
  823. + } /* rnd */
  824. + } /* neg */
  825. + } /* i */
  826. +
  827. + mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
  828. +}
  829. +
  830. +static void
  831. test_underflow1 (void)
  832. {
  833. mpfr_t x, y, z, r;
  834. @@ -281,59 +513,128 @@
  835. static void
  836. test_underflow2 (void)
  837. {
  838. - mpfr_t x, y, z, r;
  839. - int b, i, inex, same, err = 0;
  840. + mpfr_t x, y, z, r1, r2;
  841. + int e, b, i, prec = 32, pz, inex;
  842. + unsigned int neg;
  843. - mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0);
  844. + mpfr_init2 (x, MPFR_PREC_MIN);
  845. + mpfr_inits2 (prec, y, z, r1, r2, (mpfr_ptr) 0);
  846. - mpfr_set_si_2exp (z, 1, mpfr_get_emin (), MPFR_RNDN); /* z = 2^emin */
  847. - mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */
  848. + mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
  849. + /* x = 2^(emin-1) */
  850. - for (b = 0; b <= 1; b++)
  851. + for (e = -1; e <= prec + 2; e++)
  852. {
  853. - for (i = 15; i <= 17; i++)
  854. + mpfr_set (z, x, MPFR_RNDN);
  855. + /* z = x = 2^(emin+e) */
  856. + for (b = 0; b <= 1; b++)
  857. {
  858. - mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN);
  859. - /* z = 1.000...00b
  860. - * xy = 01111
  861. - * or 10000
  862. - * or 10001
  863. - */
  864. - mpfr_clear_flags ();
  865. - inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
  866. -#define STRTU2 "Error in test_underflow2 (b = %d, i = %d)\n "
  867. - if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
  868. - {
  869. - printf (STRTU2 "flags = %u instead of %u\n", b, i,
  870. - (unsigned int) __gmpfr_flags,
  871. - (unsigned int) MPFR_FLAGS_INEXACT);
  872. - err = 1;
  873. - }
  874. - same = i == 15 || (i == 16 && b == 0);
  875. - if (same ? (inex >= 0) : (inex <= 0))
  876. - {
  877. - printf (STRTU2 "incorrect ternary value (%d instead of %c 0)\n",
  878. - b, i, inex, same ? '<' : '>');
  879. - err = 1;
  880. - }
  881. - mpfr_set (y, z, MPFR_RNDN);
  882. - if (!same)
  883. - mpfr_nextabove (y);
  884. - if (! mpfr_equal_p (r, y))
  885. + for (pz = prec - 4 * (b == 0); pz <= prec + 4; pz++)
  886. {
  887. - printf (STRTU2 "expected ", b, i);
  888. - mpfr_dump (y);
  889. - printf (" got ");
  890. - mpfr_dump (r);
  891. - err = 1;
  892. - }
  893. - }
  894. - mpfr_nextabove (z);
  895. - }
  896. + inex = mpfr_prec_round (z, pz, MPFR_RNDZ);
  897. + MPFR_ASSERTN (inex == 0);
  898. + for (i = 15; i <= 17; i++)
  899. + {
  900. + mpfr_flags_t flags1, flags2;
  901. + int inex1, inex2;
  902. - if (err)
  903. - exit (1);
  904. - mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
  905. + mpfr_set_si_2exp (y, i, -4 - prec, MPFR_RNDN);
  906. +
  907. + /* <--- r --->
  908. + * z = 1.000...00b with b = 0 or 1
  909. + * xy = 01111 (i = 15)
  910. + * or 10000 (i = 16)
  911. + * or 10001 (i = 17)
  912. + *
  913. + * x, y, and z will be modified to test the different sign
  914. + * combinations. In the case b = 0 (i.e. |z| is a power of
  915. + * 2) and x*y has a different sign from z, then y will be
  916. + * divided by 2, so that i = 16 corresponds to a midpoint.
  917. + */
  918. +
  919. + for (neg = 0; neg < 8; neg++)
  920. + {
  921. + int xyneg, prev_binade;
  922. +
  923. + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
  924. + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
  925. + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
  926. +
  927. + xyneg = (neg ^ (neg >> 1)) & 1; /* true iff x*y < 0 */
  928. +
  929. + /* If a change of binade occurs by adding x*y to z
  930. + exactly, then take into account the fact that the
  931. + midpoint has a different exponent. */
  932. + prev_binade = b == 0 && (xyneg ^ MPFR_IS_NEG (z));
  933. + if (prev_binade)
  934. + mpfr_div_2ui (y, y, 1, MPFR_RNDN);
  935. +
  936. + mpfr_set (r1, z, MPFR_RNDN);
  937. + flags1 = MPFR_FLAGS_INEXACT;
  938. +
  939. + if (e == -1 && i == 17 && b == 0 &&
  940. + (xyneg ^ (neg >> 2)) != 0)
  941. + {
  942. + /* Special underflow case. */
  943. + flags1 |= MPFR_FLAGS_UNDERFLOW;
  944. + inex1 = xyneg ? 1 : -1;
  945. + }
  946. + else if (i == 15 || (i == 16 && b == 0))
  947. + {
  948. + /* round toward z */
  949. + inex1 = xyneg ? 1 : -1;
  950. + }
  951. + else if (xyneg)
  952. + {
  953. + /* round away from z, with x*y < 0 */
  954. + mpfr_nextbelow (r1);
  955. + inex1 = -1;
  956. + }
  957. + else
  958. + {
  959. + /* round away from z, with x*y > 0 */
  960. + mpfr_nextabove (r1);
  961. + inex1 = 1;
  962. + }
  963. +
  964. + mpfr_clear_flags ();
  965. + inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDN);
  966. + flags2 = __gmpfr_flags;
  967. +
  968. + if (! (mpfr_equal_p (r1, r2) &&
  969. + SAME_SIGN (inex1, inex2) &&
  970. + flags1 == flags2))
  971. + {
  972. + printf ("Error in test_underflow2 for "
  973. + "e=%d b=%d pz=%d i=%d neg=%u\n",
  974. + e, b, pz, i, neg);
  975. + printf ("Expected ");
  976. + mpfr_dump (r1);
  977. + printf ("with inex = %d and flags:", inex1);
  978. + flags_out (flags1);
  979. + printf ("Got ");
  980. + mpfr_dump (r2);
  981. + printf ("with inex = %d and flags:", inex2);
  982. + flags_out (flags2);
  983. + exit (1);
  984. + }
  985. +
  986. + /* Restore y. */
  987. + if (prev_binade)
  988. + mpfr_mul_2ui (y, y, 1, MPFR_RNDN);
  989. + } /* neg */
  990. + } /* i */
  991. + } /* pz */
  992. +
  993. + inex = mpfr_prec_round (z, prec, MPFR_RNDZ);
  994. + MPFR_ASSERTN (inex == 0);
  995. + MPFR_SET_POS (z);
  996. + mpfr_nextabove (z);
  997. + } /* b */
  998. + mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
  999. + } /* e */
  1000. +
  1001. + mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
  1002. }
  1003. static void
  1004. @@ -397,6 +698,185 @@
  1005. mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0);
  1006. }
  1007. +/* Test s = x*y + z with PREC(z) > PREC(s) + 1, x*y underflows, where
  1008. + z + x*y and z + sign(x*y) * 2^(emin-1) do not give the same result.
  1009. + x = 2^emin
  1010. + y = 2^(-8)
  1011. + z = 2^emin * (2^PREC(s) + k - 2^(-1))
  1012. + with k = 3 for MPFR_RNDN and k = 2 for the directed rounding modes.
  1013. + Also test the opposite versions with neg != 0.
  1014. +*/
  1015. +static void
  1016. +test_underflow4 (void)
  1017. +{
  1018. + mpfr_t x, y, z, s1, s2;
  1019. + mpfr_prec_t ps = 32;
  1020. + int inex, rnd;
  1021. +
  1022. + mpfr_inits2 (MPFR_PREC_MIN, x, y, (mpfr_ptr) 0);
  1023. + mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
  1024. + mpfr_init2 (z, ps + 2);
  1025. +
  1026. + inex = mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN);
  1027. + MPFR_ASSERTN (inex == 0);
  1028. + inex = mpfr_set_si_2exp (y, 1, -8, MPFR_RNDN);
  1029. + MPFR_ASSERTN (inex == 0);
  1030. +
  1031. + RND_LOOP_NO_RNDF (rnd)
  1032. + {
  1033. + mpfr_flags_t flags1, flags2;
  1034. + int inex1, inex2;
  1035. + unsigned int neg;
  1036. +
  1037. + inex = mpfr_set_si_2exp (z, 1 << 1, ps, MPFR_RNDN);
  1038. + MPFR_ASSERTN (inex == 0);
  1039. + inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
  1040. + MPFR_ASSERTN (inex == 0);
  1041. + inex = mpfr_div_2ui (z, z, 1, MPFR_RNDN);
  1042. + MPFR_ASSERTN (inex == 0);
  1043. + inex = mpfr_add_ui (z, z, rnd == MPFR_RNDN ? 3 : 2, MPFR_RNDN);
  1044. + MPFR_ASSERTN (inex == 0);
  1045. + inex = mpfr_mul (z, z, x, MPFR_RNDN);
  1046. + MPFR_ASSERTN (inex == 0);
  1047. +
  1048. + for (neg = 0; neg <= 3; neg++)
  1049. + {
  1050. + inex1 = mpfr_set (s1, z, (mpfr_rnd_t) rnd);
  1051. + flags1 = MPFR_FLAGS_INEXACT;
  1052. +
  1053. + mpfr_clear_flags ();
  1054. + inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
  1055. + flags2 = __gmpfr_flags;
  1056. +
  1057. + if (! (mpfr_equal_p (s1, s2) &&
  1058. + SAME_SIGN (inex1, inex2) &&
  1059. + flags1 == flags2))
  1060. + {
  1061. + printf ("Error in test_underflow4 for neg=%u %s\n",
  1062. + neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
  1063. + printf ("Expected ");
  1064. + mpfr_dump (s1);
  1065. + printf (" with inex ~ %d, flags =", inex1);
  1066. + flags_out (flags1);
  1067. + printf ("Got ");
  1068. + mpfr_dump (s2);
  1069. + printf (" with inex ~ %d, flags =", inex2);
  1070. + flags_out (flags2);
  1071. + exit (1);
  1072. + }
  1073. +
  1074. + if (neg == 0 || neg == 2)
  1075. + mpfr_neg (x, x, MPFR_RNDN);
  1076. + if (neg == 1 || neg == 3)
  1077. + mpfr_neg (y, y, MPFR_RNDN);
  1078. + mpfr_neg (z, z, MPFR_RNDN);
  1079. + }
  1080. + }
  1081. +
  1082. + mpfr_clears (x, y, z, s1, s2, (mpfr_ptr) 0);
  1083. +}
  1084. +
  1085. +/* Test s = x*y + z on:
  1086. + x = +/- 2^emin
  1087. + y = +/- 2^(-3)
  1088. + z = +/- 2^(emin + PREC(s)) and MPFR numbers close to this value.
  1089. + with PREC(z) from PREC(s) - 2 to PREC(s) + 8.
  1090. +*/
  1091. +static void
  1092. +test_underflow5 (void)
  1093. +{
  1094. + mpfr_t w, x, y, z, s1, s2, t;
  1095. + mpfr_exp_t emin;
  1096. + mpfr_prec_t ps = 32;
  1097. + int inex, i, j, rnd;
  1098. + unsigned int neg;
  1099. +
  1100. + mpfr_inits2 (MPFR_PREC_MIN, w, x, y, (mpfr_ptr) 0);
  1101. + mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
  1102. + mpfr_init2 (t, ps + 9);
  1103. +
  1104. + emin = mpfr_get_emin ();
  1105. +
  1106. + inex = mpfr_set_si_2exp (w, 1, emin, MPFR_RNDN); /* w = 2^emin */
  1107. + MPFR_ASSERTN (inex == 0);
  1108. + inex = mpfr_set_si (x, 1, MPFR_RNDN);
  1109. + MPFR_ASSERTN (inex == 0);
  1110. + inex = mpfr_set_si_2exp (y, 1, -3, MPFR_RNDN);
  1111. + MPFR_ASSERTN (inex == 0);
  1112. +
  1113. + for (i = -2; i <= 8; i++)
  1114. + {
  1115. + mpfr_init2 (z, ps + i);
  1116. + inex = mpfr_set_si_2exp (z, 1, ps, MPFR_RNDN);
  1117. + MPFR_ASSERTN (inex == 0);
  1118. +
  1119. + for (j = 1; j <= 32; j++)
  1120. + mpfr_nextbelow (z);
  1121. +
  1122. + for (j = -32; j <= 32; j++)
  1123. + {
  1124. + for (neg = 0; neg < 8; neg++)
  1125. + {
  1126. + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
  1127. + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
  1128. + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
  1129. +
  1130. + inex = mpfr_fma (t, x, y, z, MPFR_RNDN);
  1131. + MPFR_ASSERTN (inex == 0);
  1132. +
  1133. + inex = mpfr_mul (x, x, w, MPFR_RNDN);
  1134. + MPFR_ASSERTN (inex == 0);
  1135. + inex = mpfr_mul (z, z, w, MPFR_RNDN);
  1136. + MPFR_ASSERTN (inex == 0);
  1137. +
  1138. + RND_LOOP_NO_RNDF (rnd)
  1139. + {
  1140. + mpfr_flags_t flags1, flags2;
  1141. + int inex1, inex2;
  1142. +
  1143. + mpfr_clear_flags ();
  1144. + inex1 = mpfr_mul (s1, w, t, (mpfr_rnd_t) rnd);
  1145. + flags1 = __gmpfr_flags;
  1146. +
  1147. + mpfr_clear_flags ();
  1148. + inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
  1149. + flags2 = __gmpfr_flags;
  1150. +
  1151. + if (! (mpfr_equal_p (s1, s2) &&
  1152. + SAME_SIGN (inex1, inex2) &&
  1153. + flags1 == flags2))
  1154. + {
  1155. + printf ("Error in test_underflow5 on "
  1156. + "i=%d j=%d neg=%u %s\n", i, j, neg,
  1157. + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
  1158. + printf ("Expected ");
  1159. + mpfr_dump (s1);
  1160. + printf (" with inex ~ %d, flags =", inex1);
  1161. + flags_out (flags1);
  1162. + printf ("Got ");
  1163. + mpfr_dump (s2);
  1164. + printf (" with inex ~ %d, flags =", inex2);
  1165. + flags_out (flags2);
  1166. + exit (1);
  1167. + }
  1168. + } /* rnd */
  1169. +
  1170. + inex = mpfr_div (x, x, w, MPFR_RNDN);
  1171. + MPFR_ASSERTN (inex == 0);
  1172. + inex = mpfr_div (z, z, w, MPFR_RNDN);
  1173. + MPFR_ASSERTN (inex == 0);
  1174. + } /* neg */
  1175. +
  1176. + MPFR_SET_POS (z); /* restore the value before the loop on neg */
  1177. + mpfr_nextabove (z);
  1178. + } /* j */
  1179. +
  1180. + mpfr_clear (z);
  1181. + } /* i */
  1182. +
  1183. + mpfr_clears (w, x, y, s1, s2, t, (mpfr_ptr) 0);
  1184. +}
  1185. +
  1186. static void
  1187. bug20101018 (void)
  1188. {
  1189. @@ -533,6 +1013,7 @@
  1190. {
  1191. mpfr_t x, y, z, s;
  1192. mpfr_exp_t emin, emax;
  1193. + int i;
  1194. tests_start_mpfr ();
  1195. @@ -823,21 +1304,39 @@
  1196. test_exact ();
  1197. - test_overflow1 ();
  1198. - test_overflow2 ();
  1199. - test_underflow1 ();
  1200. - test_underflow2 ();
  1201. - test_underflow3 (1);
  1202. + for (i = 0; i <= 2; i++)
  1203. + {
  1204. + if (i == 0)
  1205. + {
  1206. + /* corresponds to the generic code + mpfr_check_range */
  1207. + set_emin (-1024);
  1208. + set_emax (1024);
  1209. + }
  1210. + else if (i == 1)
  1211. + {
  1212. + set_emin (MPFR_EMIN_MIN);
  1213. + set_emax (MPFR_EMAX_MAX);
  1214. + }
  1215. + else
  1216. + {
  1217. + MPFR_ASSERTN (i == 2);
  1218. + if (emin == MPFR_EMIN_MIN && emax == MPFR_EMAX_MAX)
  1219. + break;
  1220. + set_emin (emin);
  1221. + set_emax (emax);
  1222. + }
  1223. - set_emin (MPFR_EMIN_MIN);
  1224. - set_emax (MPFR_EMAX_MAX);
  1225. - test_overflow1 ();
  1226. - test_overflow2 ();
  1227. - test_underflow1 ();
  1228. - test_underflow2 ();
  1229. - test_underflow3 (2);
  1230. - set_emin (emin);
  1231. - set_emax (emax);
  1232. + test_overflow1 ();
  1233. + test_overflow2 ();
  1234. + test_overflow3 ();
  1235. + test_overflow4 ();
  1236. + test_overflow5 ();
  1237. + test_underflow1 ();
  1238. + test_underflow2 ();
  1239. + test_underflow3 (i);
  1240. + test_underflow4 ();
  1241. + test_underflow5 ();
  1242. + }
  1243. tests_end_mpfr ();
  1244. return 0;
  1245. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  1246. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:47:54.194308761 +0000
  1247. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:47:54.230308407 +0000
  1248. @@ -0,0 +1 @@
  1249. +sqr_1n-underflow
  1250. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  1251. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:45:53.171452379 +0000
  1252. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:47:54.226308446 +0000
  1253. @@ -1 +1 @@
  1254. -4.0.1-p2
  1255. +4.0.1-p3
  1256. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  1257. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:45:53.171452379 +0000
  1258. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:47:54.226308446 +0000
  1259. @@ -27,7 +27,7 @@
  1260. #define MPFR_VERSION_MAJOR 4
  1261. #define MPFR_VERSION_MINOR 0
  1262. #define MPFR_VERSION_PATCHLEVEL 1
  1263. -#define MPFR_VERSION_STRING "4.0.1-p2"
  1264. +#define MPFR_VERSION_STRING "4.0.1-p3"
  1265. /* User macros:
  1266. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  1267. diff -Naurd mpfr-4.0.1-a/src/sqr.c mpfr-4.0.1-b/src/sqr.c
  1268. --- mpfr-4.0.1-a/src/sqr.c 2018-01-09 12:30:58.000000000 +0000
  1269. +++ mpfr-4.0.1-b/src/sqr.c 2018-04-27 12:47:54.218308525 +0000
  1270. @@ -161,15 +161,18 @@
  1271. if (MPFR_UNLIKELY(ax < __gmpfr_emin))
  1272. {
  1273. /* As seen in mpfr_mul_1, we cannot have a0 = 111...111 here if there
  1274. - was not exponent decrease (ax--) above.
  1275. - In the case of an exponent decrease, it is not possible for
  1276. - GMP_NUMB_BITS=32 since the largest b0 such that b0^2 < 2^(2*32-1)
  1277. - is b0=3037000499, but its square has only 30 leading ones.
  1278. - For GMP_NUMB_BITS=64 it is possible: the largest b0 is
  1279. - 13043817825332782212, and its square has 64 leading ones. */
  1280. - if ((ax == __gmpfr_emin - 1) && (ap[0] == ~MPFR_LIMB_HIGHBIT) &&
  1281. - ((rnd_mode == MPFR_RNDN && rb) ||
  1282. - (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
  1283. + was not an exponent decrease (ax--) above.
  1284. + In the case of an exponent decrease:
  1285. + - For GMP_NUMB_BITS=32, a0 = 111...111 is not possible since the
  1286. + largest b0 such that b0^2 < 2^(2*32-1) is b0=3037000499, but
  1287. + its square has only 30 leading ones.
  1288. + - For GMP_NUMB_BITS=64, a0 = 111...111 is possible: the largest b0
  1289. + is 13043817825332782212, and its square has 64 leading ones; but
  1290. + since the next bit is rb=0, for RNDN, we always have an underflow.
  1291. + For the test below, note that a is positive.
  1292. + */
  1293. + if (ax == __gmpfr_emin - 1 && ap[0] == MPFR_LIMB_MAX &&
  1294. + MPFR_IS_LIKE_RNDA (rnd_mode, 0))
  1295. goto rounding; /* no underflow */
  1296. /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
  1297. we have to change to RNDZ. This corresponds to:
  1298. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  1299. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:45:53.171452379 +0000
  1300. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:47:54.226308446 +0000
  1301. @@ -25,5 +25,5 @@
  1302. const char *
  1303. mpfr_get_version (void)
  1304. {
  1305. - return "4.0.1-p2";
  1306. + return "4.0.1-p3";
  1307. }
  1308. diff -Naurd mpfr-4.0.1-a/tests/tsqr.c mpfr-4.0.1-b/tests/tsqr.c
  1309. --- mpfr-4.0.1-a/tests/tsqr.c 2018-01-09 12:30:58.000000000 +0000
  1310. +++ mpfr-4.0.1-b/tests/tsqr.c 2018-04-27 12:47:54.218308525 +0000
  1311. @@ -188,6 +188,156 @@
  1312. #endif
  1313. }
  1314. +static void
  1315. +coverage (mpfr_prec_t pmax)
  1316. +{
  1317. + mpfr_prec_t p;
  1318. +
  1319. + for (p = MPFR_PREC_MIN; p <= pmax; p++)
  1320. + {
  1321. + mpfr_t a, b, c;
  1322. + int inex;
  1323. + mpfr_exp_t emin;
  1324. +
  1325. + mpfr_init2 (a, p);
  1326. + mpfr_init2 (b, p);
  1327. + mpfr_init2 (c, p);
  1328. +
  1329. + /* exercise carry in most significant bits of a, with overflow */
  1330. + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
  1331. + mpfr_sqrt (b, b, MPFR_RNDU);
  1332. + mpfr_div_2exp (c, b, 1, MPFR_RNDN);
  1333. + mpfr_sqr (c, c, MPFR_RNDN);
  1334. + mpfr_clear_flags ();
  1335. + inex = mpfr_sqr (a, b, MPFR_RNDN);
  1336. + /* if EXP(c) > emax-2, there is overflow */
  1337. + if (mpfr_get_exp (c) > mpfr_get_emax () - 2)
  1338. + {
  1339. + MPFR_ASSERTN(inex > 0);
  1340. + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
  1341. + MPFR_ASSERTN(mpfr_overflow_p ());
  1342. + }
  1343. + else /* no overflow */
  1344. + {
  1345. + /* 2^p-1 is a square only for p=1 */
  1346. + MPFR_ASSERTN((p == 1 && inex == 0) || (p > 1 && inex < 0));
  1347. + MPFR_ASSERTN(!mpfr_overflow_p ());
  1348. + mpfr_set_ui_2exp (c, 1, mpfr_get_emax (), MPFR_RNDZ);
  1349. + MPFR_ASSERTN(mpfr_equal_p (a, c));
  1350. + }
  1351. +
  1352. + /* same as above, with RNDU */
  1353. + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
  1354. + mpfr_sqrt (b, b, MPFR_RNDU);
  1355. + mpfr_div_2exp (c, b, 1, MPFR_RNDN);
  1356. + mpfr_sqr (c, c, MPFR_RNDU);
  1357. + mpfr_clear_flags ();
  1358. + inex = mpfr_sqr (a, b, MPFR_RNDU);
  1359. + /* if EXP(c) > emax-2, there is overflow */
  1360. + if (mpfr_get_exp (c) > mpfr_get_emax () - 2)
  1361. + {
  1362. + MPFR_ASSERTN(inex > 0);
  1363. + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
  1364. + MPFR_ASSERTN(mpfr_overflow_p ());
  1365. + }
  1366. + else /* no overflow */
  1367. + {
  1368. + /* 2^p-1 is a square only for p=1 */
  1369. + MPFR_ASSERTN((p == 1 && inex == 0) || (p > 1 && inex < 0));
  1370. + MPFR_ASSERTN(!mpfr_overflow_p ());
  1371. + mpfr_set_ui_2exp (c, 1, mpfr_get_emax (), MPFR_RNDZ);
  1372. + MPFR_ASSERTN(mpfr_equal_p (a, c));
  1373. + }
  1374. +
  1375. + /* exercise trivial overflow */
  1376. + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
  1377. + mpfr_sqrt (b, b, MPFR_RNDU);
  1378. + mpfr_mul_2exp (b, b, 1, MPFR_RNDN);
  1379. + mpfr_clear_flags ();
  1380. + inex = mpfr_sqr (a, b, MPFR_RNDN);
  1381. + MPFR_ASSERTN(inex > 0);
  1382. + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
  1383. + MPFR_ASSERTN(mpfr_overflow_p ());
  1384. +
  1385. + /* exercise trivial underflow */
  1386. + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDZ);
  1387. + mpfr_sqrt (b, b, MPFR_RNDU);
  1388. + mpfr_div_2exp (b, b, 1, MPFR_RNDN);
  1389. + mpfr_clear_flags ();
  1390. + inex = mpfr_sqr (a, b, MPFR_RNDN);
  1391. + MPFR_ASSERTN(inex < 0);
  1392. + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
  1393. + MPFR_ASSERTN(mpfr_underflow_p ());
  1394. +
  1395. + /* exercise square between 0.5*2^emin and its predecessor (emin even) */
  1396. + emin = mpfr_get_emin ();
  1397. + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
  1398. + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDN);
  1399. + inex = mpfr_sqrt (b, b, MPFR_RNDZ);
  1400. + MPFR_ASSERTN(inex != 0); /* sqrt(2) is not exact */
  1401. + mpfr_mul_2exp (c, b, 1, MPFR_RNDN);
  1402. + mpfr_sqr (c, c, MPFR_RNDN);
  1403. + mpfr_clear_flags ();
  1404. + inex = mpfr_sqr (a, b, MPFR_RNDN);
  1405. + if (mpfr_get_exp (c) < mpfr_get_emin () + 2) /* underflow */
  1406. + {
  1407. + /* if c > 0.5*2^(emin+1), we should round to 0.5*2^emin */
  1408. + if (mpfr_cmp_ui_2exp (c, 1, mpfr_get_emin ()) > 0)
  1409. + {
  1410. + MPFR_ASSERTN(inex > 0);
  1411. + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
  1412. + MPFR_ASSERTN(mpfr_underflow_p ());
  1413. + }
  1414. + else /* we should round to 0 */
  1415. + {
  1416. + MPFR_ASSERTN(inex < 0);
  1417. + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
  1418. + MPFR_ASSERTN(mpfr_underflow_p ());
  1419. + }
  1420. + }
  1421. + else
  1422. + {
  1423. + MPFR_ASSERTN(inex > 0);
  1424. + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
  1425. + MPFR_ASSERTN(!mpfr_underflow_p ());
  1426. + }
  1427. + mpfr_set_emin (emin);
  1428. +
  1429. + /* exercise exact square root 2^(emin-2) for emin even */
  1430. + emin = mpfr_get_emin ();
  1431. + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
  1432. + mpfr_set_ui_2exp (b, 1, (mpfr_get_emin () - 2) / 2, MPFR_RNDN);
  1433. + inex = mpfr_sqr (a, b, MPFR_RNDN);
  1434. + MPFR_ASSERTN(inex < 0);
  1435. + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
  1436. + MPFR_ASSERTN(mpfr_underflow_p ());
  1437. + mpfr_set_emin (emin);
  1438. +
  1439. + /* same as above, for RNDU */
  1440. + emin = mpfr_get_emin ();
  1441. + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
  1442. + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDN);
  1443. + inex = mpfr_sqrt (b, b, MPFR_RNDZ);
  1444. + MPFR_ASSERTN(inex != 0); /* sqrt(2) is not exact */
  1445. + mpfr_mul_2exp (c, b, 1, MPFR_RNDN);
  1446. + mpfr_sqr (c, c, MPFR_RNDU);
  1447. + mpfr_clear_flags ();
  1448. + inex = mpfr_sqr (a, b, MPFR_RNDU);
  1449. + MPFR_ASSERTN(inex > 0);
  1450. + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
  1451. + /* we have underflow if c < 2^(emin+1) */
  1452. + if (mpfr_cmp_ui_2exp (c, 1, mpfr_get_emin () + 1) < 0)
  1453. + MPFR_ASSERTN(mpfr_underflow_p ());
  1454. + else
  1455. + MPFR_ASSERTN(!mpfr_underflow_p ());
  1456. + mpfr_set_emin (emin);
  1457. +
  1458. + mpfr_clear (a);
  1459. + mpfr_clear (b);
  1460. + mpfr_clear (c);
  1461. + }
  1462. +}
  1463. +
  1464. int
  1465. main (void)
  1466. {
  1467. @@ -195,6 +345,7 @@
  1468. tests_start_mpfr ();
  1469. + coverage (1024);
  1470. check_mpn_sqr ();
  1471. check_special ();
  1472. test_underflow ();
  1473. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  1474. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:50:10.592974822 +0000
  1475. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:50:10.624974512 +0000
  1476. @@ -0,0 +1 @@
  1477. +get_str
  1478. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  1479. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:47:54.226308446 +0000
  1480. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:50:10.624974512 +0000
  1481. @@ -1 +1 @@
  1482. -4.0.1-p3
  1483. +4.0.1-p4
  1484. diff -Naurd mpfr-4.0.1-a/doc/mpfr.info mpfr-4.0.1-b/doc/mpfr.info
  1485. --- mpfr-4.0.1-a/doc/mpfr.info 2018-02-07 12:58:03.000000000 +0000
  1486. +++ mpfr-4.0.1-b/doc/mpfr.info 2018-04-27 12:50:17.128911341 +0000
  1487. @@ -1321,10 +1321,9 @@
  1488. size_t N, mpfr_t OP, mpfr_rnd_t RND)
  1489. Convert OP to a string of digits in base B, with rounding in the
  1490. direction RND, where N is either zero (see below) or the number of
  1491. - significant digits output in the string; in the latter case, N must
  1492. - be greater or equal to 2. The base may vary from 2 to 62;
  1493. - otherwise the function does nothing and immediately returns a null
  1494. - pointer.
  1495. + significant digits output in the string. The base may vary from 2
  1496. + to 62; otherwise the function does nothing and immediately returns
  1497. + a null pointer.
  1498. If the input is NaN, then the returned string is ‘@NaN@’ and the
  1499. NaN flag is set. If the input is +Inf (resp. −Inf), then the
  1500. @@ -4471,21 +4470,21 @@
  1501. * mpfr_expm1: Special Functions. (line 40)
  1502. * mpfr_fac_ui: Special Functions. (line 136)
  1503. * mpfr_fits_intmax_p: Conversion Functions.
  1504. - (line 168)
  1505. + (line 167)
  1506. * mpfr_fits_sint_p: Conversion Functions.
  1507. - (line 164)
  1508. + (line 163)
  1509. * mpfr_fits_slong_p: Conversion Functions.
  1510. - (line 162)
  1511. + (line 161)
  1512. * mpfr_fits_sshort_p: Conversion Functions.
  1513. - (line 166)
  1514. + (line 165)
  1515. * mpfr_fits_uintmax_p: Conversion Functions.
  1516. - (line 167)
  1517. + (line 166)
  1518. * mpfr_fits_uint_p: Conversion Functions.
  1519. - (line 163)
  1520. + (line 162)
  1521. * mpfr_fits_ulong_p: Conversion Functions.
  1522. - (line 161)
  1523. + (line 160)
  1524. * mpfr_fits_ushort_p: Conversion Functions.
  1525. - (line 165)
  1526. + (line 164)
  1527. * mpfr_flags_clear: Exception Related Functions.
  1528. (line 190)
  1529. * mpfr_flags_restore: Exception Related Functions.
  1530. @@ -4520,7 +4519,7 @@
  1531. * mpfr_free_cache2: Special Functions. (line 295)
  1532. * mpfr_free_pool: Special Functions. (line 309)
  1533. * mpfr_free_str: Conversion Functions.
  1534. - (line 156)
  1535. + (line 155)
  1536. * mpfr_frexp: Conversion Functions.
  1537. (line 49)
  1538. * mpfr_gamma: Special Functions. (line 155)
  1539. @@ -4928,30 +4927,30 @@
  1540. Node: Assignment Functions47553
  1541. Node: Combined Initialization and Assignment Functions57499
  1542. Node: Conversion Functions58800
  1543. -Node: Basic Arithmetic Functions69381
  1544. -Node: Comparison Functions80277
  1545. -Node: Special Functions83765
  1546. -Node: Input and Output Functions101974
  1547. -Node: Formatted Output Functions106751
  1548. -Node: Integer and Remainder Related Functions116956
  1549. -Node: Rounding-Related Functions124484
  1550. -Node: Miscellaneous Functions131001
  1551. -Node: Exception Related Functions141493
  1552. -Node: Compatibility with MPF151733
  1553. -Node: Custom Interface154679
  1554. -Node: Internals159310
  1555. -Node: API Compatibility160854
  1556. -Node: Type and Macro Changes162802
  1557. -Node: Added Functions165985
  1558. -Node: Changed Functions170499
  1559. -Node: Removed Functions177095
  1560. -Node: Other Changes177825
  1561. -Node: MPFR and the IEEE 754 Standard179526
  1562. -Node: Contributors182143
  1563. -Node: References185200
  1564. -Node: GNU Free Documentation License187084
  1565. -Node: Concept Index209677
  1566. -Node: Function and Type Index216049
  1567. +Node: Basic Arithmetic Functions69323
  1568. +Node: Comparison Functions80219
  1569. +Node: Special Functions83707
  1570. +Node: Input and Output Functions101916
  1571. +Node: Formatted Output Functions106693
  1572. +Node: Integer and Remainder Related Functions116898
  1573. +Node: Rounding-Related Functions124426
  1574. +Node: Miscellaneous Functions130943
  1575. +Node: Exception Related Functions141435
  1576. +Node: Compatibility with MPF151675
  1577. +Node: Custom Interface154621
  1578. +Node: Internals159252
  1579. +Node: API Compatibility160796
  1580. +Node: Type and Macro Changes162744
  1581. +Node: Added Functions165927
  1582. +Node: Changed Functions170441
  1583. +Node: Removed Functions177037
  1584. +Node: Other Changes177767
  1585. +Node: MPFR and the IEEE 754 Standard179468
  1586. +Node: Contributors182085
  1587. +Node: References185142
  1588. +Node: GNU Free Documentation License187026
  1589. +Node: Concept Index209619
  1590. +Node: Function and Type Index215991
  1591. 
  1592. End Tag Table
  1593. diff -Naurd mpfr-4.0.1-a/doc/mpfr.texi mpfr-4.0.1-b/doc/mpfr.texi
  1594. --- mpfr-4.0.1-a/doc/mpfr.texi 2018-02-07 12:50:31.000000000 +0000
  1595. +++ mpfr-4.0.1-b/doc/mpfr.texi 2018-04-27 12:50:10.612974628 +0000
  1596. @@ -1655,8 +1655,8 @@
  1597. @deftypefun {char *} mpfr_get_str (char *@var{str}, mpfr_exp_t *@var{expptr}, int @var{b}, size_t @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
  1598. Convert @var{op} to a string of digits in base @var{b}, with rounding in
  1599. the direction @var{rnd}, where @var{n} is either zero (see below) or the
  1600. -number of significant digits output in the string; in the latter case,
  1601. -@var{n} must be greater or equal to 2. The base may vary from 2 to 62;
  1602. +number of significant digits output in the string.
  1603. +The base may vary from 2 to 62;
  1604. otherwise the function does nothing and immediately returns a null pointer.
  1605. If the input is NaN, then the returned string is @samp{@@NaN@@} and the
  1606. @@ -1699,8 +1699,7 @@
  1607. but in some very rare cases, it might be @math{m+1}
  1608. (the smallest case for bases up to 62 is when @var{p} equals 186564318007
  1609. for bases 7 and 49).
  1610. -@c In the source src/get_str.c, this is due to the approximate mpfr_ceil_mul,
  1611. -@c but also m = 1 is changed to 2.
  1612. +@c In the source src/get_str.c, this is due to the approximate mpfr_ceil_mul.
  1613. If @var{str} is a null pointer, space for the significand is allocated using
  1614. the allocation function (@pxref{Memory Handling}) and a pointer to the string
  1615. diff -Naurd mpfr-4.0.1-a/src/get_str.c mpfr-4.0.1-b/src/get_str.c
  1616. --- mpfr-4.0.1-a/src/get_str.c 2018-01-09 12:30:58.000000000 +0000
  1617. +++ mpfr-4.0.1-b/src/get_str.c 2018-04-27 12:50:10.612974628 +0000
  1618. @@ -2325,15 +2325,12 @@
  1619. */
  1620. m = 1 +
  1621. mpfr_ceil_mul (IS_POW2(b) ? MPFR_PREC(x) - 1 : MPFR_PREC(x), b, 1);
  1622. - if (m < 2)
  1623. - m = 2;
  1624. }
  1625. MPFR_LOG_MSG (("m=%zu\n", m));
  1626. - /* The code below for non-power-of-two bases works for m=1;
  1627. - this is important for the internal use of mpfr_get_str. */
  1628. - MPFR_ASSERTN (m >= 2 || (!IS_POW2(b) && m >= 1));
  1629. + /* The code below works for m=1, both for power-of-two and non-power-of-two
  1630. + bases; this is important for the internal use of mpfr_get_str. */
  1631. /* x is a floating-point number */
  1632. @@ -2376,6 +2373,8 @@
  1633. /* the first digit will contain only r bits */
  1634. prec = (m - 1) * pow2 + r; /* total number of bits */
  1635. + /* if m=1 then 1 <= prec <= pow2, and since prec=1 is now valid in MPFR,
  1636. + the power-of-two code also works for m=1 */
  1637. n = MPFR_PREC2LIMBS (prec);
  1638. MPFR_TMP_MARK (marker);
  1639. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  1640. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:47:54.226308446 +0000
  1641. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:50:10.620974551 +0000
  1642. @@ -27,7 +27,7 @@
  1643. #define MPFR_VERSION_MAJOR 4
  1644. #define MPFR_VERSION_MINOR 0
  1645. #define MPFR_VERSION_PATCHLEVEL 1
  1646. -#define MPFR_VERSION_STRING "4.0.1-p3"
  1647. +#define MPFR_VERSION_STRING "4.0.1-p4"
  1648. /* User macros:
  1649. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  1650. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  1651. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:47:54.226308446 +0000
  1652. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:50:10.624974512 +0000
  1653. @@ -25,5 +25,5 @@
  1654. const char *
  1655. mpfr_get_version (void)
  1656. {
  1657. - return "4.0.1-p3";
  1658. + return "4.0.1-p4";
  1659. }
  1660. diff -Naurd mpfr-4.0.1-a/tests/tget_str.c mpfr-4.0.1-b/tests/tget_str.c
  1661. --- mpfr-4.0.1-a/tests/tget_str.c 2018-01-09 12:30:58.000000000 +0000
  1662. +++ mpfr-4.0.1-b/tests/tget_str.c 2018-04-27 12:50:10.612974628 +0000
  1663. @@ -1267,6 +1267,41 @@
  1664. #define ITER 1000
  1665. +static void
  1666. +coverage (void)
  1667. +{
  1668. + mpfr_t x;
  1669. + char s[42];
  1670. + mpfr_exp_t e;
  1671. + int b = 3;
  1672. + size_t m = 40;
  1673. +
  1674. + mpfr_init2 (x, 128);
  1675. +
  1676. + /* exercise corner case in mpfr_get_str_aux: exact case (e < 0), where r
  1677. + rounds to a power of 2, and f is a multiple of GMP_NUMB_BITS */
  1678. + mpfr_set_ui_2exp (x, 1, 64, MPFR_RNDU);
  1679. + mpfr_nextbelow (x);
  1680. + /* x = 2^64 - 2^(-64) */
  1681. + mpfr_get_str (s, &e, b, m, x, MPFR_RNDU);
  1682. + /* s is the base-3 string for 6148914691236517206 (in base 10) */
  1683. + MPFR_ASSERTN(strcmp (s, "1111222002212212010121102012021021021200") == 0);
  1684. + MPFR_ASSERTN(e == 41);
  1685. +
  1686. + /* exercise corner case in mpfr_get_str: input is m=0, then it is changed
  1687. + to m=1 */
  1688. + mpfr_set_prec (x, 1);
  1689. + mpfr_set_ui (x, 1, MPFR_RNDN);
  1690. + mpfr_get_str (s, &e, 2, 0, x, MPFR_RNDN);
  1691. + MPFR_ASSERTN(strcmp (s, "1") == 0);
  1692. + MPFR_ASSERTN(e == 1);
  1693. + mpfr_get_str (s, &e, 2, 1, x, MPFR_RNDN);
  1694. + MPFR_ASSERTN(strcmp (s, "1") == 0);
  1695. + MPFR_ASSERTN(e == 1);
  1696. +
  1697. + mpfr_clear (x);
  1698. +}
  1699. +
  1700. int
  1701. main (int argc, char *argv[])
  1702. {
  1703. @@ -1281,6 +1316,7 @@
  1704. tests_start_mpfr ();
  1705. + coverage ();
  1706. check_small ();
  1707. check_special (2, 2);
  1708. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  1709. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:52:13.875783093 +0000
  1710. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:52:13.911782747 +0000
  1711. @@ -0,0 +1 @@
  1712. +cmp_q-special
  1713. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  1714. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:50:10.624974512 +0000
  1715. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:52:13.911782747 +0000
  1716. @@ -1 +1 @@
  1717. -4.0.1-p4
  1718. +4.0.1-p5
  1719. diff -Naurd mpfr-4.0.1-a/src/gmp_op.c mpfr-4.0.1-b/src/gmp_op.c
  1720. --- mpfr-4.0.1-a/src/gmp_op.c 2018-01-09 12:30:58.000000000 +0000
  1721. +++ mpfr-4.0.1-b/src/gmp_op.c 2018-04-27 12:52:13.899782862 +0000
  1722. @@ -452,11 +452,15 @@
  1723. mpfr_prec_t p;
  1724. MPFR_SAVE_EXPO_DECL (expo);
  1725. - if (MPFR_UNLIKELY (mpq_denref (q) == 0))
  1726. + if (MPFR_UNLIKELY (mpz_sgn (mpq_denref (q)) == 0))
  1727. {
  1728. /* q is an infinity or NaN */
  1729. - mpfr_init2 (t, 2);
  1730. + mpfr_flags_t old_flags;
  1731. +
  1732. + mpfr_init2 (t, MPFR_PREC_MIN);
  1733. + old_flags = __gmpfr_flags;
  1734. mpfr_set_q (t, q, MPFR_RNDN);
  1735. + __gmpfr_flags = old_flags;
  1736. res = mpfr_cmp (x, t);
  1737. mpfr_clear (t);
  1738. return res;
  1739. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  1740. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:50:10.620974551 +0000
  1741. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:52:13.907782785 +0000
  1742. @@ -27,7 +27,7 @@
  1743. #define MPFR_VERSION_MAJOR 4
  1744. #define MPFR_VERSION_MINOR 0
  1745. #define MPFR_VERSION_PATCHLEVEL 1
  1746. -#define MPFR_VERSION_STRING "4.0.1-p4"
  1747. +#define MPFR_VERSION_STRING "4.0.1-p5"
  1748. /* User macros:
  1749. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  1750. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  1751. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:50:10.624974512 +0000
  1752. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:52:13.911782747 +0000
  1753. @@ -25,5 +25,5 @@
  1754. const char *
  1755. mpfr_get_version (void)
  1756. {
  1757. - return "4.0.1-p4";
  1758. + return "4.0.1-p5";
  1759. }
  1760. diff -Naurd mpfr-4.0.1-a/tests/tgmpop.c mpfr-4.0.1-b/tests/tgmpop.c
  1761. --- mpfr-4.0.1-a/tests/tgmpop.c 2018-01-09 12:30:58.000000000 +0000
  1762. +++ mpfr-4.0.1-b/tests/tgmpop.c 2018-04-27 12:52:13.899782862 +0000
  1763. @@ -307,16 +307,39 @@
  1764. mpfr_init2 (z, MPFR_PREC_MIN);
  1765. mpq_init (y);
  1766. - /* check the erange flag when x is NaN */
  1767. + /* Check the flags when x is NaN: the erange flags must be set, and
  1768. + only this one. */
  1769. mpfr_set_nan (x);
  1770. mpq_set_ui (y, 17, 1);
  1771. - mpfr_clear_erangeflag ();
  1772. + mpfr_clear_flags ();
  1773. res1 = mpfr_cmp_q (x, y);
  1774. - if (res1 != 0 || mpfr_erangeflag_p () == 0)
  1775. + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
  1776. {
  1777. printf ("Error for mpfr_cmp_q (NaN, 17)\n");
  1778. printf ("Return value: expected 0, got %d\n", res1);
  1779. - printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
  1780. + printf ("Expected flags:");
  1781. + flags_out (MPFR_FLAGS_ERANGE);
  1782. + printf ("Got flags: ");
  1783. + flags_out (__gmpfr_flags);
  1784. + exit (1);
  1785. + }
  1786. +
  1787. + /* Check the flags when y is NaN: the erange flags must be set, and
  1788. + only this one. */
  1789. + mpfr_set_ui (x, 42, MPFR_RNDN);
  1790. + /* A NaN rational is represented by 0/0 (MPFR extension). */
  1791. + mpz_set_ui (mpq_numref (y), 0);
  1792. + mpz_set_ui (mpq_denref (y), 0);
  1793. + mpfr_clear_flags ();
  1794. + res1 = mpfr_cmp_q (x, y);
  1795. + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
  1796. + {
  1797. + printf ("Error for mpfr_cmp_q (42, NaN)\n");
  1798. + printf ("Return value: expected 0, got %d\n", res1);
  1799. + printf ("Expected flags:");
  1800. + flags_out (MPFR_FLAGS_ERANGE);
  1801. + printf ("Got flags: ");
  1802. + flags_out (__gmpfr_flags);
  1803. exit (1);
  1804. }
  1805. @@ -341,6 +364,55 @@
  1806. }
  1807. }
  1808. }
  1809. +
  1810. + /* check for y = 1/0 */
  1811. + mpz_set_ui (mpq_numref (y), 1);
  1812. + mpz_set_ui (mpq_denref (y), 0);
  1813. + mpfr_set_ui (x, 1, MPFR_RNDN);
  1814. + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0);
  1815. + mpfr_set_inf (x, -1);
  1816. + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0);
  1817. + mpfr_set_inf (x, +1);
  1818. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1819. + mpfr_set_nan (x);
  1820. + mpfr_clear_erangeflag ();
  1821. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1822. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1823. +
  1824. + /* check for y = -1/0 */
  1825. + mpz_set_si (mpq_numref (y), -1);
  1826. + mpz_set_ui (mpq_denref (y), 0);
  1827. + mpfr_set_ui (x, 1, MPFR_RNDN);
  1828. + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0);
  1829. + mpfr_set_inf (x, -1);
  1830. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1831. + mpfr_set_inf (x, +1);
  1832. + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0);
  1833. + mpfr_set_nan (x);
  1834. + mpfr_clear_erangeflag ();
  1835. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1836. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1837. +
  1838. + /* check for y = 0/0 */
  1839. + mpz_set_ui (mpq_numref (y), 0);
  1840. + mpz_set_ui (mpq_denref (y), 0);
  1841. + mpfr_set_ui (x, 1, MPFR_RNDN);
  1842. + mpfr_clear_erangeflag ();
  1843. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1844. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1845. + mpfr_set_inf (x, -1);
  1846. + mpfr_clear_erangeflag ();
  1847. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1848. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1849. + mpfr_set_inf (x, +1);
  1850. + mpfr_clear_erangeflag ();
  1851. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1852. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1853. + mpfr_set_nan (x);
  1854. + mpfr_clear_erangeflag ();
  1855. + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
  1856. + MPFR_ASSERTN(mpfr_erangeflag_p ());
  1857. +
  1858. mpq_clear (y);
  1859. mpfr_clear (x);
  1860. mpfr_clear (z);
  1861. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  1862. --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:54:17.862594948 +0000
  1863. +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:54:17.894594642 +0000
  1864. @@ -0,0 +1 @@
  1865. +io-null-stream
  1866. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  1867. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:52:13.911782747 +0000
  1868. +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:54:17.894594642 +0000
  1869. @@ -1 +1 @@
  1870. -4.0.1-p5
  1871. +4.0.1-p6
  1872. diff -Naurd mpfr-4.0.1-a/src/inp_str.c mpfr-4.0.1-b/src/inp_str.c
  1873. --- mpfr-4.0.1-a/src/inp_str.c 2018-01-09 12:30:58.000000000 +0000
  1874. +++ mpfr-4.0.1-b/src/inp_str.c 2018-04-27 12:54:17.882594757 +0000
  1875. @@ -37,9 +37,6 @@
  1876. int retval;
  1877. size_t nread;
  1878. - if (stream == NULL)
  1879. - stream = stdin;
  1880. -
  1881. alloc_size = 100;
  1882. str = (unsigned char *) mpfr_allocate_func (alloc_size);
  1883. str_size = 0;
  1884. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  1885. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:52:13.907782785 +0000
  1886. +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:54:17.894594642 +0000
  1887. @@ -27,7 +27,7 @@
  1888. #define MPFR_VERSION_MAJOR 4
  1889. #define MPFR_VERSION_MINOR 0
  1890. #define MPFR_VERSION_PATCHLEVEL 1
  1891. -#define MPFR_VERSION_STRING "4.0.1-p5"
  1892. +#define MPFR_VERSION_STRING "4.0.1-p6"
  1893. /* User macros:
  1894. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  1895. diff -Naurd mpfr-4.0.1-a/src/out_str.c mpfr-4.0.1-b/src/out_str.c
  1896. --- mpfr-4.0.1-a/src/out_str.c 2018-01-09 12:30:58.000000000 +0000
  1897. +++ mpfr-4.0.1-b/src/out_str.c 2018-04-27 12:54:17.882594757 +0000
  1898. @@ -43,10 +43,6 @@
  1899. MPFR_ASSERTN (base >= 2 && base <= 62);
  1900. - /* when stream=NULL, output to stdout */
  1901. - if (stream == NULL)
  1902. - stream = stdout;
  1903. -
  1904. if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
  1905. {
  1906. if (MPFR_IS_NAN (op))
  1907. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  1908. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:52:13.911782747 +0000
  1909. +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:54:17.894594642 +0000
  1910. @@ -25,5 +25,5 @@
  1911. const char *
  1912. mpfr_get_version (void)
  1913. {
  1914. - return "4.0.1-p5";
  1915. + return "4.0.1-p6";
  1916. }
  1917. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  1918. --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:29:07.937776370 +0000
  1919. +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:29:08.017776303 +0000
  1920. @@ -0,0 +1 @@
  1921. +tstckintc-casts
  1922. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  1923. --- mpfr-4.0.1-a/VERSION 2018-04-27 12:54:17.894594642 +0000
  1924. +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:29:08.017776303 +0000
  1925. @@ -1 +1 @@
  1926. -4.0.1-p6
  1927. +4.0.1-p7
  1928. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  1929. --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:54:17.894594642 +0000
  1930. +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:29:08.013776307 +0000
  1931. @@ -27,7 +27,7 @@
  1932. #define MPFR_VERSION_MAJOR 4
  1933. #define MPFR_VERSION_MINOR 0
  1934. #define MPFR_VERSION_PATCHLEVEL 1
  1935. -#define MPFR_VERSION_STRING "4.0.1-p6"
  1936. +#define MPFR_VERSION_STRING "4.0.1-p7"
  1937. /* User macros:
  1938. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  1939. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  1940. --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:54:17.894594642 +0000
  1941. +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:29:08.017776303 +0000
  1942. @@ -25,5 +25,5 @@
  1943. const char *
  1944. mpfr_get_version (void)
  1945. {
  1946. - return "4.0.1-p6";
  1947. + return "4.0.1-p7";
  1948. }
  1949. diff -Naurd mpfr-4.0.1-a/tests/tstckintc.c mpfr-4.0.1-b/tests/tstckintc.c
  1950. --- mpfr-4.0.1-a/tests/tstckintc.c 2018-01-09 12:30:58.000000000 +0000
  1951. +++ mpfr-4.0.1-b/tests/tstckintc.c 2018-07-10 15:29:07.989776327 +0000
  1952. @@ -32,6 +32,22 @@
  1953. #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long))
  1954. +/* This code ensures alignment to "long". However, this might not be
  1955. + sufficient on some platforms. GCC's -Wcast-align=strict option can
  1956. + be useful, but this needs successive casts to help GCC, e.g.
  1957. +
  1958. + newx = (mpfr_ptr) (long *) (void *) old_stack;
  1959. +
  1960. + successively casts old_stack (of type char *) to
  1961. + - void *: avoid a false positive for the following cast to long *
  1962. + (as the code takes care of alignment to "long");
  1963. + - long *: this corresponds to the alignment checked by MPFR; coming
  1964. + from void *, it will not trigger a warning (even if incorrect);
  1965. + - mpfr_ptr: -Wcast-align=strict will emit a warning if mpfr_ptr has
  1966. + an alignment requirement stronger than long *. In such a case,
  1967. + the code will have to be fixed.
  1968. +*/
  1969. +
  1970. static void *
  1971. new_st (size_t s)
  1972. {
  1973. @@ -94,12 +110,14 @@
  1974. void *mantissa = mpfr_custom_get_significand (x);
  1975. size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x));
  1976. mpfr_ptr newx;
  1977. + long *newx2;
  1978. memmove (old_stack, x, sizeof (mpfr_t));
  1979. memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
  1980. - newx = (mpfr_ptr) old_stack;
  1981. - mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
  1982. - stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
  1983. + newx = (mpfr_ptr) (long *) (void *) old_stack;
  1984. + newx2 = (long *) (void *) (old_stack + ALIGNED (sizeof (mpfr_t)));
  1985. + mpfr_custom_move (newx, newx2);
  1986. + stack = (char *) newx2 + ALIGNED (size_mantissa);
  1987. return newx;
  1988. }
  1989. @@ -113,7 +131,7 @@
  1990. memmove (old_stack, x, sizeof (mpfr_t));
  1991. memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
  1992. - newx = (mpfr_ptr) old_stack;
  1993. + newx = (mpfr_ptr) (long *) (void *) old_stack;
  1994. (mpfr_custom_move) (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
  1995. stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
  1996. return newx;
  1997. @@ -127,7 +145,7 @@
  1998. mpfr_ptr x, y;
  1999. reset_stack ();
  2000. - org = (long *) stack;
  2001. + org = (long *) (void *) stack;
  2002. x = new_mpfr (p);
  2003. y = new_mpfr (p);
  2004. @@ -277,7 +295,7 @@
  2005. long *a, *b, *c;
  2006. reset_stack ();
  2007. - org = (long *) stack;
  2008. + org = (long *) (void *) stack;
  2009. a = dummy_set_si (42);
  2010. b = dummy_set_si (17);
  2011. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  2012. --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:33:45.189532503 +0000
  2013. +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:33:45.265532432 +0000
  2014. @@ -0,0 +1 @@
  2015. +set_d64-ternary
  2016. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  2017. --- mpfr-4.0.1-a/VERSION 2018-07-10 15:29:08.017776303 +0000
  2018. +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:33:45.261532435 +0000
  2019. @@ -1 +1 @@
  2020. -4.0.1-p7
  2021. +4.0.1-p8
  2022. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  2023. --- mpfr-4.0.1-a/src/mpfr.h 2018-07-10 15:29:08.013776307 +0000
  2024. +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:33:45.261532435 +0000
  2025. @@ -27,7 +27,7 @@
  2026. #define MPFR_VERSION_MAJOR 4
  2027. #define MPFR_VERSION_MINOR 0
  2028. #define MPFR_VERSION_PATCHLEVEL 1
  2029. -#define MPFR_VERSION_STRING "4.0.1-p7"
  2030. +#define MPFR_VERSION_STRING "4.0.1-p8"
  2031. /* User macros:
  2032. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  2033. diff -Naurd mpfr-4.0.1-a/src/set_d64.c mpfr-4.0.1-b/src/set_d64.c
  2034. --- mpfr-4.0.1-a/src/set_d64.c 2018-01-09 12:30:58.000000000 +0000
  2035. +++ mpfr-4.0.1-b/src/set_d64.c 2018-07-10 15:33:45.237532458 +0000
  2036. @@ -425,7 +425,7 @@
  2037. 1 character for terminating \0. */
  2038. decimal64_to_string (s, d);
  2039. - return mpfr_set_str (r, s, 10, rnd_mode);
  2040. + return mpfr_strtofr (r, s, NULL, 10, rnd_mode);
  2041. }
  2042. #endif /* MPFR_WANT_DECIMAL_FLOATS */
  2043. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  2044. --- mpfr-4.0.1-a/src/version.c 2018-07-10 15:29:08.017776303 +0000
  2045. +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:33:45.261532435 +0000
  2046. @@ -25,5 +25,5 @@
  2047. const char *
  2048. mpfr_get_version (void)
  2049. {
  2050. - return "4.0.1-p7";
  2051. + return "4.0.1-p8";
  2052. }
  2053. diff -Naurd mpfr-4.0.1-a/tests/tget_set_d64.c mpfr-4.0.1-b/tests/tget_set_d64.c
  2054. --- mpfr-4.0.1-a/tests/tget_set_d64.c 2018-01-09 12:30:58.000000000 +0000
  2055. +++ mpfr-4.0.1-b/tests/tget_set_d64.c 2018-07-10 15:33:45.237532458 +0000
  2056. @@ -381,6 +381,66 @@
  2057. mpfr_clear (x);
  2058. }
  2059. +static void
  2060. +powers_of_10 (void)
  2061. +{
  2062. + mpfr_t x1, x2;
  2063. + _Decimal64 d[2];
  2064. + int i, rnd;
  2065. + unsigned int neg;
  2066. +
  2067. + mpfr_inits2 (200, x1, x2, (mpfr_ptr) 0);
  2068. + for (i = 0, d[0] = 1, d[1] = 1; i < 150; i++, d[0] *= 10, d[1] /= 10)
  2069. + for (neg = 0; neg <= 3; neg++)
  2070. + RND_LOOP_NO_RNDF (rnd)
  2071. + {
  2072. + int inex1, inex2;
  2073. + mpfr_flags_t flags1, flags2;
  2074. + mpfr_rnd_t rx1;
  2075. + _Decimal64 dd;
  2076. +
  2077. + inex1 = mpfr_set_si (x1, (neg >> 1) ? -i : i, MPFR_RNDN);
  2078. + MPFR_ASSERTN (inex1 == 0);
  2079. +
  2080. + rx1 = (neg & 1) ?
  2081. + MPFR_INVERT_RND ((mpfr_rnd_t) rnd) : (mpfr_rnd_t) rnd;
  2082. + mpfr_clear_flags ();
  2083. + inex1 = mpfr_exp10 (x1, x1, rx1);
  2084. + flags1 = __gmpfr_flags;
  2085. +
  2086. + dd = d[neg >> 1];
  2087. +
  2088. + if (neg & 1)
  2089. + {
  2090. + MPFR_SET_NEG (x1);
  2091. + inex1 = -inex1;
  2092. + dd = -dd;
  2093. + }
  2094. +
  2095. + mpfr_clear_flags ();
  2096. + inex2 = mpfr_set_decimal64 (x2, dd, (mpfr_rnd_t) rnd);
  2097. + flags2 = __gmpfr_flags;
  2098. +
  2099. + if (!(mpfr_equal_p (x1, x2) &&
  2100. + SAME_SIGN (inex1, inex2) &&
  2101. + flags1 == flags2))
  2102. + {
  2103. + printf ("Error in powers_of_10 for i=%d, neg=%d, %s\n",
  2104. + i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
  2105. + printf ("Expected ");
  2106. + mpfr_dump (x1);
  2107. + printf ("with inex = %d and flags =", inex1);
  2108. + flags_out (flags1);
  2109. + printf ("Got ");
  2110. + mpfr_dump (x2);
  2111. + printf ("with inex = %d and flags =", inex2);
  2112. + flags_out (flags2);
  2113. + exit (1);
  2114. + }
  2115. + }
  2116. + mpfr_clears (x1, x2, (mpfr_ptr) 0);
  2117. +}
  2118. +
  2119. int
  2120. main (void)
  2121. {
  2122. @@ -401,6 +461,7 @@
  2123. check_overflow ();
  2124. #endif
  2125. check_tiny ();
  2126. + powers_of_10 ();
  2127. tests_end_mpfr ();
  2128. return 0;
  2129. diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
  2130. --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:46:13.596797032 +0000
  2131. +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:46:13.676796949 +0000
  2132. @@ -0,0 +1 @@
  2133. +buffer_sandwich
  2134. diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
  2135. --- mpfr-4.0.1-a/VERSION 2018-07-10 15:33:45.261532435 +0000
  2136. +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:46:13.676796949 +0000
  2137. @@ -1 +1 @@
  2138. -4.0.1-p8
  2139. +4.0.1-p9
  2140. diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
  2141. --- mpfr-4.0.1-a/src/mpfr.h 2018-07-10 15:33:45.261532435 +0000
  2142. +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:46:13.672796954 +0000
  2143. @@ -27,7 +27,7 @@
  2144. #define MPFR_VERSION_MAJOR 4
  2145. #define MPFR_VERSION_MINOR 0
  2146. #define MPFR_VERSION_PATCHLEVEL 1
  2147. -#define MPFR_VERSION_STRING "4.0.1-p8"
  2148. +#define MPFR_VERSION_STRING "4.0.1-p9"
  2149. /* User macros:
  2150. MPFR_USE_FILE: Define it to make MPFR define functions dealing
  2151. diff -Naurd mpfr-4.0.1-a/src/vasprintf.c mpfr-4.0.1-b/src/vasprintf.c
  2152. --- mpfr-4.0.1-a/src/vasprintf.c 2018-01-09 12:30:58.000000000 +0000
  2153. +++ mpfr-4.0.1-b/src/vasprintf.c 2018-07-10 15:46:13.648796978 +0000
  2154. @@ -683,20 +683,31 @@
  2155. else
  2156. {
  2157. const size_t step = 3;
  2158. - const size_t size = len + tz;
  2159. - const size_t r = size % step == 0 ? step : size % step;
  2160. - const size_t q = size % step == 0 ? size / step - 1 : size / step;
  2161. - const size_t fullsize = size + q;
  2162. - size_t i;
  2163. + size_t size, q, r, fullsize;
  2164. + /* check that len + tz does not overflow */
  2165. + if (len > (size_t) -1 - tz)
  2166. + return 1;
  2167. +
  2168. + size = len + tz; /* number of digits */
  2169. MPFR_ASSERTD (size > 0);
  2170. + q = (size - 1) / step; /* number of separators C */
  2171. + r = ((size - 1) % step) + 1; /* number of digits in the leftmost block */
  2172. +
  2173. + /* check that size + q does not overflow */
  2174. + if (size > (size_t) -1 - q)
  2175. + return 1;
  2176. +
  2177. + fullsize = size + q; /* number of digits and separators */
  2178. +
  2179. if (buffer_incr_len (b, fullsize))
  2180. return 1;
  2181. if (b->size != 0)
  2182. {
  2183. char *oldcurr;
  2184. + size_t i;
  2185. MPFR_ASSERTD (*b->curr == '\0');
  2186. MPFR_ASSERTN (b->size < ((size_t) -1) - fullsize);
  2187. @@ -705,11 +716,21 @@
  2188. MPFR_DBGRES (oldcurr = b->curr);
  2189. - /* first R significant digits */
  2190. - memcpy (b->curr, str, r);
  2191. + /* first r significant digits (leftmost block) */
  2192. + if (r <= len)
  2193. + {
  2194. + memcpy (b->curr, str, r);
  2195. + str += r;
  2196. + len -= r;
  2197. + }
  2198. + else
  2199. + {
  2200. + MPFR_ASSERTD (r > len);
  2201. + memcpy (b->curr, str, len);
  2202. + memset (b->curr + len, '0', r - len);
  2203. + len = 0;
  2204. + }
  2205. b->curr += r;
  2206. - str += r;
  2207. - len -= r;
  2208. /* blocks of thousands. Warning: STR might end in the middle of a block */
  2209. for (i = 0; i < q; ++i)
  2210. @@ -722,6 +743,7 @@
  2211. {
  2212. memcpy (b->curr, str, step);
  2213. len -= step;
  2214. + str += step;
  2215. }
  2216. else
  2217. /* last digits in STR, fill up thousand block with zeros */
  2218. @@ -736,7 +758,6 @@
  2219. memset (b->curr, '0', step);
  2220. b->curr += step;
  2221. - str += step;
  2222. }
  2223. MPFR_ASSERTD (b->curr - oldcurr == fullsize);
  2224. @@ -1920,8 +1941,14 @@
  2225. /* integral part (may also be "nan" or "inf") */
  2226. MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
  2227. if (MPFR_UNLIKELY (np.thousands_sep))
  2228. - buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
  2229. - np.thousands_sep);
  2230. + {
  2231. + if (buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
  2232. + np.thousands_sep))
  2233. + {
  2234. + buf->len = -1;
  2235. + goto clear_and_exit;
  2236. + }
  2237. + }
  2238. else
  2239. {
  2240. buffer_cat (buf, np.ip_ptr, np.ip_size);
  2241. diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
  2242. --- mpfr-4.0.1-a/src/version.c 2018-07-10 15:33:45.261532435 +0000
  2243. +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:46:13.672796954 +0000
  2244. @@ -25,5 +25,5 @@
  2245. const char *
  2246. mpfr_get_version (void)
  2247. {
  2248. - return "4.0.1-p8";
  2249. + return "4.0.1-p9";
  2250. }
  2251. diff -Naurd mpfr-4.0.1-a/tests/tprintf.c mpfr-4.0.1-b/tests/tprintf.c
  2252. --- mpfr-4.0.1-a/tests/tprintf.c 2018-01-09 12:30:58.000000000 +0000
  2253. +++ mpfr-4.0.1-b/tests/tprintf.c 2018-07-10 15:46:13.648796978 +0000
  2254. @@ -31,6 +31,10 @@
  2255. #include <stddef.h>
  2256. #include <errno.h>
  2257. +#ifdef HAVE_LOCALE_H
  2258. +#include <locale.h>
  2259. +#endif
  2260. +
  2261. #include "mpfr-intmax.h"
  2262. #include "mpfr-test.h"
  2263. #define STDOUT_FILENO 1
  2264. @@ -474,30 +478,41 @@
  2265. mpfr_clear (x);
  2266. }
  2267. -#ifdef HAVE_LOCALE_H
  2268. -
  2269. -#include <locale.h>
  2270. -
  2271. -const char * const tab_locale[] = {
  2272. - "en_US",
  2273. - "en_US.iso88591",
  2274. - "en_US.iso885915",
  2275. - "en_US.utf8"
  2276. -};
  2277. +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
  2278. static void
  2279. test_locale (void)
  2280. {
  2281. + const char * const tab_locale[] = {
  2282. + "en_US",
  2283. + "en_US.iso88591",
  2284. + "en_US.iso885915",
  2285. + "en_US.utf8"
  2286. + };
  2287. int i;
  2288. - char *s = NULL;
  2289. mpfr_t x;
  2290. int count;
  2291. + char v[] = "99999999999999999999999.5";
  2292. - for(i = 0; i < numberof(tab_locale) && s == NULL; i++)
  2293. - s = setlocale (LC_ALL, tab_locale[i]);
  2294. + for (i = 0; i < numberof(tab_locale); i++)
  2295. + {
  2296. + char *s;
  2297. - if (s == NULL || MPFR_THOUSANDS_SEPARATOR != ',')
  2298. - return;
  2299. + s = setlocale (LC_ALL, tab_locale[i]);
  2300. +
  2301. + if (s != NULL && MPFR_THOUSANDS_SEPARATOR == ',')
  2302. + break;
  2303. + }
  2304. +
  2305. + if (i == numberof(tab_locale))
  2306. + {
  2307. + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
  2308. + return;
  2309. +
  2310. + fprintf (stderr, "Cannot find a locale with ',' thousands separator.\n"
  2311. + "Please install one of the en_US based locales.\n");
  2312. + exit (1);
  2313. + }
  2314. mpfr_init2 (x, 113);
  2315. mpfr_set_ui (x, 10000, MPFR_RNDN);
  2316. @@ -507,6 +522,50 @@
  2317. count = mpfr_printf ("(2) 10000=%'Rf \n", x);
  2318. check_length (10001, count, 25, d);
  2319. + mpfr_set_ui (x, 1000, MPFR_RNDN);
  2320. + count = mpfr_printf ("(3) 1000=%'Rf \n", x);
  2321. + check_length (10002, count, 23, d);
  2322. +
  2323. + for (i = 1; i <= sizeof (v) - 3; i++)
  2324. + {
  2325. + mpfr_set_str (x, v + sizeof (v) - 3 - i, 10, MPFR_RNDN);
  2326. + count = mpfr_printf ("(4) 10^i=%'.0Rf \n", x);
  2327. + check_length (10002 + i, count, 12 + i + i/3, d);
  2328. + }
  2329. +
  2330. +#define N0 20
  2331. +
  2332. + for (i = 1; i <= N0; i++)
  2333. + {
  2334. + char s[N0+4];
  2335. + int j, rnd;
  2336. +
  2337. + s[0] = '1';
  2338. + for (j = 1; j <= i; j++)
  2339. + s[j] = '0';
  2340. + s[i+1] = '\0';
  2341. +
  2342. + mpfr_set_str (x, s, 10, MPFR_RNDN);
  2343. +
  2344. + RND_LOOP (rnd)
  2345. + {
  2346. + count = mpfr_printf ("(5) 10^i=%'.0R*f \n", (mpfr_rnd_t) rnd, x);
  2347. + check_length (11000 + 10 * i + rnd, count, 12 + i + i/3, d);
  2348. + }
  2349. +
  2350. + strcat (s + (i + 1), ".5");
  2351. + count = mpfr_printf ("(5) 10^i=%'.0Rf \n", x);
  2352. + check_length (11000 + 10 * i + 9, count, 12 + i + i/3, d);
  2353. + }
  2354. +
  2355. + mpfr_set_str (x, "1000", 10, MPFR_RNDN);
  2356. + count = mpfr_printf ("%'012.3Rg\n", x);
  2357. + check_length (12000, count, 13, d);
  2358. + count = mpfr_printf ("%'012.4Rg\n", x);
  2359. + check_length (12001, count, 13, d);
  2360. + count = mpfr_printf ("%'013.4Rg\n", x);
  2361. + check_length (12002, count, 14, d);
  2362. +
  2363. mpfr_clear (x);
  2364. }
  2365. @@ -515,7 +574,11 @@
  2366. static void
  2367. test_locale (void)
  2368. {
  2369. - /* Nothing */
  2370. + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
  2371. + {
  2372. + fprintf (stderr, "Cannot test locales.\n");
  2373. + exit (1);
  2374. + }
  2375. }
  2376. #endif
  2377. diff -Naurd mpfr-4.0.1-a/tests/tsprintf.c mpfr-4.0.1-b/tests/tsprintf.c
  2378. --- mpfr-4.0.1-a/tests/tsprintf.c 2018-01-10 10:15:30.000000000 +0000
  2379. +++ mpfr-4.0.1-b/tests/tsprintf.c 2018-07-10 15:46:13.648796978 +0000
  2380. @@ -380,7 +380,7 @@
  2381. check_sprintf ("1.00 ", "%-#20.3RG", x);
  2382. check_sprintf ("0.9999 ", "%-#20.4RG", x);
  2383. - /* multiple of 10 */
  2384. + /* powers of 10 */
  2385. mpfr_set_str (x, "1e17", 10, MPFR_RNDN);
  2386. check_sprintf ("1e+17", "%Re", x);
  2387. check_sprintf ("1.000e+17", "%.3Re", x);
  2388. @@ -402,7 +402,7 @@
  2389. check_sprintf ("1", "%.0RUf", x);
  2390. check_sprintf ("1", "%.0RYf", x);
  2391. - /* multiple of 10 with 'g' style */
  2392. + /* powers of 10 with 'g' style */
  2393. mpfr_set_str (x, "10", 10, MPFR_RNDN);
  2394. check_sprintf ("10", "%Rg", x);
  2395. check_sprintf ("1e+01", "%.0Rg", x);
  2396. @@ -419,6 +419,12 @@
  2397. check_sprintf ("1e+03", "%.0Rg", x);
  2398. check_sprintf ("1e+03", "%.3Rg", x);
  2399. check_sprintf ("1000", "%.4Rg", x);
  2400. + check_sprintf ("1e+03", "%.3Rg", x);
  2401. + check_sprintf ("1000", "%.4Rg", x);
  2402. + check_sprintf (" 1e+03", "%9.3Rg", x);
  2403. + check_sprintf (" 1000", "%9.4Rg", x);
  2404. + check_sprintf ("00001e+03", "%09.3Rg", x);
  2405. + check_sprintf ("000001000", "%09.4Rg", x);
  2406. mpfr_ui_div (x, 1, x, MPFR_RNDN);
  2407. check_sprintf ("0.001", "%Rg", x);
  2408. @@ -430,6 +436,10 @@
  2409. check_sprintf ("1e+05", "%.0Rg", x);
  2410. check_sprintf ("1e+05", "%.5Rg", x);
  2411. check_sprintf ("100000", "%.6Rg", x);
  2412. + check_sprintf (" 1e+05", "%17.5Rg", x);
  2413. + check_sprintf (" 100000", "%17.6Rg", x);
  2414. + check_sprintf ("0000000000001e+05", "%017.5Rg", x);
  2415. + check_sprintf ("00000000000100000", "%017.6Rg", x);
  2416. mpfr_ui_div (x, 1, x, MPFR_RNDN);
  2417. check_sprintf ("1e-05", "%Rg", x);
  2418. @@ -857,6 +867,12 @@
  2419. "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
  2420. #endif
  2421. + /* check invalid spec.spec */
  2422. + check_vsprintf ("%,", "%,");
  2423. +
  2424. + /* check empty format */
  2425. + check_vsprintf ("%", "%");
  2426. +
  2427. mpf_clear (mpf);
  2428. mpq_clear (mpq);
  2429. mpz_clear (mpz);
  2430. @@ -864,12 +880,12 @@
  2431. return 0;
  2432. }
  2433. -#if MPFR_LCONV_DPTS
  2434. +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
  2435. /* Check with locale "da_DK". On most platforms, decimal point is ','
  2436. and thousands separator is '.'; the test is not performed if this
  2437. is not the case or if the locale doesn't exist. */
  2438. -static int
  2439. +static void
  2440. locale_da_DK (void)
  2441. {
  2442. mpfr_prec_t p = 128;
  2443. @@ -878,7 +894,16 @@
  2444. if (setlocale (LC_ALL, "da_DK") == 0 ||
  2445. localeconv()->decimal_point[0] != ',' ||
  2446. localeconv()->thousands_sep[0] != '.')
  2447. - return 0;
  2448. + {
  2449. + setlocale (LC_ALL, "C");
  2450. +
  2451. + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
  2452. + return;
  2453. +
  2454. + fprintf (stderr,
  2455. + "Cannot test the da_DK locale (not found or inconsistent).\n");
  2456. + exit (1);
  2457. + }
  2458. mpfr_init2 (x, p);
  2459. @@ -917,10 +942,11 @@
  2460. check_sprintf ("100" S2 "0000", "%'.4Rf", x);
  2461. mpfr_clear (x);
  2462. - return 0;
  2463. +
  2464. + setlocale (LC_ALL, "C");
  2465. }
  2466. -#endif /* MPFR_LCONV_DPTS */
  2467. +#endif /* ... && MPFR_LCONV_DPTS */
  2468. /* check concordance between mpfr_asprintf result with a regular mpfr float
  2469. and with a regular double float */
  2470. @@ -1425,6 +1451,117 @@
  2471. exit (1);
  2472. }
  2473. +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
  2474. +
  2475. +/* The following tests should be equivalent to those from test_locale()
  2476. + in tprintf.c (remove the \n at the end of the test strings). */
  2477. +
  2478. +static void
  2479. +test_locale (void)
  2480. +{
  2481. + const char * const tab_locale[] = {
  2482. + "en_US",
  2483. + "en_US.iso88591",
  2484. + "en_US.iso885915",
  2485. + "en_US.utf8"
  2486. + };
  2487. + int i;
  2488. + mpfr_t x;
  2489. + char v[] = "99999999999999999999999.5";
  2490. +
  2491. + for (i = 0; i < numberof(tab_locale); i++)
  2492. + {
  2493. + char *s;
  2494. +
  2495. + s = setlocale (LC_ALL, tab_locale[i]);
  2496. +
  2497. + if (s != NULL && MPFR_THOUSANDS_SEPARATOR == ',')
  2498. + break;
  2499. + }
  2500. +
  2501. + if (i == numberof(tab_locale))
  2502. + {
  2503. + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
  2504. + return;
  2505. +
  2506. + fprintf (stderr, "Cannot find a locale with ',' thousands separator.\n"
  2507. + "Please install one of the en_US based locales.\n");
  2508. + exit (1);
  2509. + }
  2510. +
  2511. + mpfr_init2 (x, 113);
  2512. + mpfr_set_ui (x, 10000, MPFR_RNDN);
  2513. +
  2514. + check_sprintf ("(1) 10000=10,000 ", "(1) 10000=%'Rg ", x);
  2515. + check_sprintf ("(2) 10000=10,000.000000 ", "(2) 10000=%'Rf ", x);
  2516. +
  2517. + mpfr_set_ui (x, 1000, MPFR_RNDN);
  2518. + check_sprintf ("(3) 1000=1,000.000000 ", "(3) 1000=%'Rf ", x);
  2519. +
  2520. + for (i = 1; i <= sizeof (v) - 3; i++)
  2521. + {
  2522. + char buf[64];
  2523. + int j;
  2524. +
  2525. + strcpy (buf, "(4) 10^i=1");
  2526. + for (j = i; j > 0; j--)
  2527. + strcat (buf, ",0" + (j % 3 != 0));
  2528. + strcat (buf, " ");
  2529. + mpfr_set_str (x, v + sizeof (v) - 3 - i, 10, MPFR_RNDN);
  2530. + check_sprintf (buf, "(4) 10^i=%'.0Rf ", x);
  2531. + }
  2532. +
  2533. +#define N0 20
  2534. +
  2535. + for (i = 1; i <= N0; i++)
  2536. + {
  2537. + char s[N0+4], buf[64];
  2538. + int j;
  2539. +
  2540. + s[0] = '1';
  2541. + for (j = 1; j <= i; j++)
  2542. + s[j] = '0';
  2543. + s[i+1] = '\0';
  2544. +
  2545. + strcpy (buf, "(5) 10^i=1");
  2546. + for (j = i; j > 0; j--)
  2547. + strcat (buf, ",0" + (j % 3 != 0));
  2548. + strcat (buf, " ");
  2549. +
  2550. + mpfr_set_str (x, s, 10, MPFR_RNDN);
  2551. +
  2552. + check_sprintf (buf, "(5) 10^i=%'.0RNf ", x);
  2553. + check_sprintf (buf, "(5) 10^i=%'.0RZf ", x);
  2554. + check_sprintf (buf, "(5) 10^i=%'.0RUf ", x);
  2555. + check_sprintf (buf, "(5) 10^i=%'.0RDf ", x);
  2556. + check_sprintf (buf, "(5) 10^i=%'.0RYf ", x);
  2557. +
  2558. + strcat (s + (i + 1), ".5");
  2559. + check_sprintf (buf, "(5) 10^i=%'.0Rf ", x);
  2560. + }
  2561. +
  2562. + mpfr_set_str (x, "1000", 10, MPFR_RNDN);
  2563. + check_sprintf ("00000001e+03", "%'012.3Rg", x);
  2564. + check_sprintf ("00000001,000", "%'012.4Rg", x);
  2565. + check_sprintf ("000000001,000", "%'013.4Rg", x);
  2566. +
  2567. + mpfr_clear (x);
  2568. +}
  2569. +
  2570. +#else
  2571. +
  2572. +static void
  2573. +test_locale (void)
  2574. +{
  2575. + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
  2576. + {
  2577. + fprintf (stderr, "Cannot test locales.\n");
  2578. + exit (1);
  2579. + }
  2580. +}
  2581. +
  2582. +#endif
  2583. +
  2584. int
  2585. main (int argc, char **argv)
  2586. {
  2587. @@ -1446,12 +1583,14 @@
  2588. binary ();
  2589. decimal ();
  2590. -#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
  2591. -#if MPFR_LCONV_DPTS
  2592. +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
  2593. locale_da_DK ();
  2594. - /* Avoid a warning by doing the setlocale outside of this #if */
  2595. -#endif
  2596. - setlocale (LC_ALL, "C");
  2597. +#else
  2598. + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
  2599. + {
  2600. + fprintf (stderr, "Cannot test locales.\n");
  2601. + exit (1);
  2602. + }
  2603. #endif
  2604. }
  2605. @@ -1462,6 +1601,7 @@
  2606. snprintf_size ();
  2607. percent_n ();
  2608. mixed ();
  2609. + test_locale ();
  2610. if (getenv ("MPFR_CHECK_LIBC_PRINTF"))
  2611. {