bid128_round_integral.c 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951
  1. /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
  2. This file is part of GCC.
  3. GCC is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free
  5. Software Foundation; either version 3, or (at your option) any later
  6. version.
  7. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  8. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  10. for more details.
  11. Under Section 7 of GPL version 3, you are granted additional
  12. permissions described in the GCC Runtime Library Exception, version
  13. 3.1, as published by the Free Software Foundation.
  14. You should have received a copy of the GNU General Public License and
  15. a copy of the GCC Runtime Library Exception along with this program;
  16. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  17. <http://www.gnu.org/licenses/>. */
  18. #define BID_128RES
  19. #include "bid_internal.h"
  20. /*****************************************************************************
  21. * BID128_round_integral_exact
  22. ****************************************************************************/
  23. BID128_FUNCTION_ARG1 (bid128_round_integral_exact, x)
  24. UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
  25. };
  26. UINT64 x_sign;
  27. UINT64 x_exp;
  28. int exp; // unbiased exponent
  29. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
  30. UINT64 tmp64;
  31. BID_UI64DOUBLE tmp1;
  32. unsigned int x_nr_bits;
  33. int q, ind, shift;
  34. UINT128 C1;
  35. UINT256 fstar;
  36. UINT256 P256;
  37. // check for NaN or Infinity
  38. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  39. // x is special
  40. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  41. // if x = NaN, then res = Q (x)
  42. // check first for non-canonical NaN payload
  43. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  44. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  45. (x.w[0] > 0x38c15b09ffffffffull))) {
  46. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  47. x.w[0] = 0x0ull;
  48. }
  49. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  50. // set invalid flag
  51. *pfpsf |= INVALID_EXCEPTION;
  52. // return quiet (x)
  53. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  54. res.w[0] = x.w[0];
  55. } else { // x is QNaN
  56. // return x
  57. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  58. res.w[0] = x.w[0];
  59. }
  60. BID_RETURN (res)
  61. } else { // x is not a NaN, so it must be infinity
  62. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  63. // return +inf
  64. res.w[1] = 0x7800000000000000ull;
  65. res.w[0] = 0x0000000000000000ull;
  66. } else { // x is -inf
  67. // return -inf
  68. res.w[1] = 0xf800000000000000ull;
  69. res.w[0] = 0x0000000000000000ull;
  70. }
  71. BID_RETURN (res);
  72. }
  73. }
  74. // unpack x
  75. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  76. C1.w[1] = x.w[1] & MASK_COEFF;
  77. C1.w[0] = x.w[0];
  78. // check for non-canonical values (treated as zero)
  79. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  80. // non-canonical
  81. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  82. C1.w[1] = 0; // significand high
  83. C1.w[0] = 0; // significand low
  84. } else { // G0_G1 != 11
  85. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  86. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  87. (C1.w[1] == 0x0001ed09bead87c0ull
  88. && C1.w[0] > 0x378d8e63ffffffffull)) {
  89. // x is non-canonical if coefficient is larger than 10^34 -1
  90. C1.w[1] = 0;
  91. C1.w[0] = 0;
  92. } else { // canonical
  93. ;
  94. }
  95. }
  96. // test for input equal to zero
  97. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  98. // x is 0
  99. // return 0 preserving the sign bit and the preferred exponent
  100. // of MAX(Q(x), 0)
  101. if (x_exp <= (0x1820ull << 49)) {
  102. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  103. } else {
  104. res.w[1] = x_sign | x_exp;
  105. }
  106. res.w[0] = 0x0000000000000000ull;
  107. BID_RETURN (res);
  108. }
  109. // x is not special and is not zero
  110. switch (rnd_mode) {
  111. case ROUNDING_TO_NEAREST:
  112. case ROUNDING_TIES_AWAY:
  113. // if (exp <= -(p+1)) return 0.0
  114. if (x_exp <= 0x2ffa000000000000ull) { // 0x2ffa000000000000ull == -35
  115. res.w[1] = x_sign | 0x3040000000000000ull;
  116. res.w[0] = 0x0000000000000000ull;
  117. *pfpsf |= INEXACT_EXCEPTION;
  118. BID_RETURN (res);
  119. }
  120. break;
  121. case ROUNDING_DOWN:
  122. // if (exp <= -p) return -1.0 or +0.0
  123. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffa000000000000ull == -34
  124. if (x_sign) {
  125. // if negative, return negative 1, because we know coefficient
  126. // is non-zero (would have been caught above)
  127. res.w[1] = 0xb040000000000000ull;
  128. res.w[0] = 0x0000000000000001ull;
  129. } else {
  130. // if positive, return positive 0, because we know coefficient is
  131. // non-zero (would have been caught above)
  132. res.w[1] = 0x3040000000000000ull;
  133. res.w[0] = 0x0000000000000000ull;
  134. }
  135. *pfpsf |= INEXACT_EXCEPTION;
  136. BID_RETURN (res);
  137. }
  138. break;
  139. case ROUNDING_UP:
  140. // if (exp <= -p) return -0.0 or +1.0
  141. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffc000000000000ull == -34
  142. if (x_sign) {
  143. // if negative, return negative 0, because we know the coefficient
  144. // is non-zero (would have been caught above)
  145. res.w[1] = 0xb040000000000000ull;
  146. res.w[0] = 0x0000000000000000ull;
  147. } else {
  148. // if positive, return positive 1, because we know coefficient is
  149. // non-zero (would have been caught above)
  150. res.w[1] = 0x3040000000000000ull;
  151. res.w[0] = 0x0000000000000001ull;
  152. }
  153. *pfpsf |= INEXACT_EXCEPTION;
  154. BID_RETURN (res);
  155. }
  156. break;
  157. case ROUNDING_TO_ZERO:
  158. // if (exp <= -p) return -0.0 or +0.0
  159. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffc000000000000ull == -34
  160. res.w[1] = x_sign | 0x3040000000000000ull;
  161. res.w[0] = 0x0000000000000000ull;
  162. *pfpsf |= INEXACT_EXCEPTION;
  163. BID_RETURN (res);
  164. }
  165. break;
  166. }
  167. // q = nr. of decimal digits in x
  168. // determine first the nr. of bits in x
  169. if (C1.w[1] == 0) {
  170. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  171. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  172. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  173. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  174. x_nr_bits =
  175. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  176. } else { // x < 2^32
  177. tmp1.d = (double) (C1.w[0]); // exact conversion
  178. x_nr_bits =
  179. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  180. }
  181. } else { // if x < 2^53
  182. tmp1.d = (double) C1.w[0]; // exact conversion
  183. x_nr_bits =
  184. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  185. }
  186. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  187. tmp1.d = (double) C1.w[1]; // exact conversion
  188. x_nr_bits =
  189. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  190. }
  191. q = nr_digits[x_nr_bits - 1].digits;
  192. if (q == 0) {
  193. q = nr_digits[x_nr_bits - 1].digits1;
  194. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
  195. (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  196. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  197. q++;
  198. }
  199. exp = (x_exp >> 49) - 6176;
  200. if (exp >= 0) { // -exp <= 0
  201. // the argument is an integer already
  202. res.w[1] = x.w[1];
  203. res.w[0] = x.w[0];
  204. BID_RETURN (res);
  205. }
  206. // exp < 0
  207. switch (rnd_mode) {
  208. case ROUNDING_TO_NEAREST:
  209. if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
  210. // need to shift right -exp digits from the coefficient; exp will be 0
  211. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  212. // chop off ind digits from the lower part of C1
  213. // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
  214. tmp64 = C1.w[0];
  215. if (ind <= 19) {
  216. C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  217. } else {
  218. C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  219. C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  220. }
  221. if (C1.w[0] < tmp64)
  222. C1.w[1]++;
  223. // calculate C* and f*
  224. // C* is actually floor(C*) in this case
  225. // C* and f* need shifting and masking, as shown by
  226. // shiftright128[] and maskhigh128[]
  227. // 1 <= x <= 34
  228. // kx = 10^(-x) = ten2mk128[ind - 1]
  229. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  230. // the approximation of 10^(-x) was rounded up to 118 bits
  231. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  232. // determine the value of res and fstar
  233. // determine inexactness of the rounding of C*
  234. // if (0 < f* - 1/2 < 10^(-x)) then
  235. // the result is exact
  236. // else // if (f* - 1/2 > T*) then
  237. // the result is inexact
  238. // Note: we are going to use ten2mk128[] instead of ten2mk128trunc[]
  239. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  240. // redundant shift = shiftright128[ind - 1]; // shift = 0
  241. res.w[1] = P256.w[3];
  242. res.w[0] = P256.w[2];
  243. // redundant fstar.w[3] = 0;
  244. // redundant fstar.w[2] = 0;
  245. fstar.w[1] = P256.w[1];
  246. fstar.w[0] = P256.w[0];
  247. // fraction f* < 10^(-x) <=> midpoint
  248. // f* is in the right position to be compared with
  249. // 10^(-x) from ten2mk128[]
  250. // if 0 < fstar < 10^(-x), subtract 1 if odd (for rounding to even)
  251. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  252. ((fstar.w[1] < (ten2mk128[ind - 1].w[1]))
  253. || ((fstar.w[1] == ten2mk128[ind - 1].w[1])
  254. && (fstar.w[0] < ten2mk128[ind - 1].w[0])))) {
  255. // subract 1 to make even
  256. if (res.w[0]-- == 0) {
  257. res.w[1]--;
  258. }
  259. }
  260. if (fstar.w[1] > 0x8000000000000000ull ||
  261. (fstar.w[1] == 0x8000000000000000ull
  262. && fstar.w[0] > 0x0ull)) {
  263. // f* > 1/2 and the result may be exact
  264. tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2
  265. if (tmp64 > ten2mk128[ind - 1].w[1] ||
  266. (tmp64 == ten2mk128[ind - 1].w[1] &&
  267. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  268. // set the inexact flag
  269. *pfpsf |= INEXACT_EXCEPTION;
  270. } // else the result is exact
  271. } else { // the result is inexact; f2* <= 1/2
  272. // set the inexact flag
  273. *pfpsf |= INEXACT_EXCEPTION;
  274. }
  275. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  276. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  277. res.w[1] = (P256.w[3] >> shift);
  278. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  279. // redundant fstar.w[3] = 0;
  280. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  281. fstar.w[1] = P256.w[1];
  282. fstar.w[0] = P256.w[0];
  283. // fraction f* < 10^(-x) <=> midpoint
  284. // f* is in the right position to be compared with
  285. // 10^(-x) from ten2mk128[]
  286. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  287. fstar.w[2] == 0 && (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
  288. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  289. fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
  290. // subract 1 to make even
  291. if (res.w[0]-- == 0) {
  292. res.w[1]--;
  293. }
  294. }
  295. if (fstar.w[2] > onehalf128[ind - 1] ||
  296. (fstar.w[2] == onehalf128[ind - 1]
  297. && (fstar.w[1] || fstar.w[0]))) {
  298. // f2* > 1/2 and the result may be exact
  299. // Calculate f2* - 1/2
  300. tmp64 = fstar.w[2] - onehalf128[ind - 1];
  301. if (tmp64 || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  302. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  303. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  304. // set the inexact flag
  305. *pfpsf |= INEXACT_EXCEPTION;
  306. } // else the result is exact
  307. } else { // the result is inexact; f2* <= 1/2
  308. // set the inexact flag
  309. *pfpsf |= INEXACT_EXCEPTION;
  310. }
  311. } else { // 22 <= ind - 1 <= 33
  312. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  313. res.w[1] = 0;
  314. res.w[0] = P256.w[3] >> shift;
  315. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  316. fstar.w[2] = P256.w[2];
  317. fstar.w[1] = P256.w[1];
  318. fstar.w[0] = P256.w[0];
  319. // fraction f* < 10^(-x) <=> midpoint
  320. // f* is in the right position to be compared with
  321. // 10^(-x) from ten2mk128[]
  322. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  323. fstar.w[3] == 0 && fstar.w[2] == 0 &&
  324. (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
  325. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  326. fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
  327. // subract 1 to make even
  328. if (res.w[0]-- == 0) {
  329. res.w[1]--;
  330. }
  331. }
  332. if (fstar.w[3] > onehalf128[ind - 1] ||
  333. (fstar.w[3] == onehalf128[ind - 1] &&
  334. (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
  335. // f2* > 1/2 and the result may be exact
  336. // Calculate f2* - 1/2
  337. tmp64 = fstar.w[3] - onehalf128[ind - 1];
  338. if (tmp64 || fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1]
  339. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  340. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  341. // set the inexact flag
  342. *pfpsf |= INEXACT_EXCEPTION;
  343. } // else the result is exact
  344. } else { // the result is inexact; f2* <= 1/2
  345. // set the inexact flag
  346. *pfpsf |= INEXACT_EXCEPTION;
  347. }
  348. }
  349. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  350. BID_RETURN (res);
  351. } else { // if ((q + exp) < 0) <=> q < -exp
  352. // the result is +0 or -0
  353. res.w[1] = x_sign | 0x3040000000000000ull;
  354. res.w[0] = 0x0000000000000000ull;
  355. *pfpsf |= INEXACT_EXCEPTION;
  356. BID_RETURN (res);
  357. }
  358. break;
  359. case ROUNDING_TIES_AWAY:
  360. if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
  361. // need to shift right -exp digits from the coefficient; exp will be 0
  362. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  363. // chop off ind digits from the lower part of C1
  364. // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
  365. tmp64 = C1.w[0];
  366. if (ind <= 19) {
  367. C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  368. } else {
  369. C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  370. C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  371. }
  372. if (C1.w[0] < tmp64)
  373. C1.w[1]++;
  374. // calculate C* and f*
  375. // C* is actually floor(C*) in this case
  376. // C* and f* need shifting and masking, as shown by
  377. // shiftright128[] and maskhigh128[]
  378. // 1 <= x <= 34
  379. // kx = 10^(-x) = ten2mk128[ind - 1]
  380. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  381. // the approximation of 10^(-x) was rounded up to 118 bits
  382. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  383. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
  384. // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
  385. // if (0 < f* < 10^(-x)) then the result is a midpoint
  386. // if floor(C*) is even then C* = floor(C*) - logical right
  387. // shift; C* has p decimal digits, correct by Prop. 1)
  388. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  389. // shift; C* has p decimal digits, correct by Pr. 1)
  390. // else
  391. // C* = floor(C*) (logical right shift; C has p decimal digits,
  392. // correct by Property 1)
  393. // n = C* * 10^(e+x)
  394. // determine also the inexactness of the rounding of C*
  395. // if (0 < f* - 1/2 < 10^(-x)) then
  396. // the result is exact
  397. // else // if (f* - 1/2 > T*) then
  398. // the result is inexact
  399. // Note: we are going to use ten2mk128[] instead of ten2mk128trunc[]
  400. // shift right C* by Ex-128 = shiftright128[ind]
  401. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  402. // redundant shift = shiftright128[ind - 1]; // shift = 0
  403. res.w[1] = P256.w[3];
  404. res.w[0] = P256.w[2];
  405. // redundant fstar.w[3] = 0;
  406. // redundant fstar.w[2] = 0;
  407. fstar.w[1] = P256.w[1];
  408. fstar.w[0] = P256.w[0];
  409. if (fstar.w[1] > 0x8000000000000000ull ||
  410. (fstar.w[1] == 0x8000000000000000ull
  411. && fstar.w[0] > 0x0ull)) {
  412. // f* > 1/2 and the result may be exact
  413. tmp64 = fstar.w[1] - 0x8000000000000000ull; // f* - 1/2
  414. if ((tmp64 > ten2mk128[ind - 1].w[1] ||
  415. (tmp64 == ten2mk128[ind - 1].w[1] &&
  416. fstar.w[0] >= ten2mk128[ind - 1].w[0]))) {
  417. // set the inexact flag
  418. *pfpsf |= INEXACT_EXCEPTION;
  419. } // else the result is exact
  420. } else { // the result is inexact; f2* <= 1/2
  421. // set the inexact flag
  422. *pfpsf |= INEXACT_EXCEPTION;
  423. }
  424. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  425. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  426. res.w[1] = (P256.w[3] >> shift);
  427. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  428. // redundant fstar.w[3] = 0;
  429. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  430. fstar.w[1] = P256.w[1];
  431. fstar.w[0] = P256.w[0];
  432. if (fstar.w[2] > onehalf128[ind - 1] ||
  433. (fstar.w[2] == onehalf128[ind - 1]
  434. && (fstar.w[1] || fstar.w[0]))) {
  435. // f2* > 1/2 and the result may be exact
  436. // Calculate f2* - 1/2
  437. tmp64 = fstar.w[2] - onehalf128[ind - 1];
  438. if (tmp64 || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  439. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  440. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  441. // set the inexact flag
  442. *pfpsf |= INEXACT_EXCEPTION;
  443. } // else the result is exact
  444. } else { // the result is inexact; f2* <= 1/2
  445. // set the inexact flag
  446. *pfpsf |= INEXACT_EXCEPTION;
  447. }
  448. } else { // 22 <= ind - 1 <= 33
  449. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  450. res.w[1] = 0;
  451. res.w[0] = P256.w[3] >> shift;
  452. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  453. fstar.w[2] = P256.w[2];
  454. fstar.w[1] = P256.w[1];
  455. fstar.w[0] = P256.w[0];
  456. if (fstar.w[3] > onehalf128[ind - 1] ||
  457. (fstar.w[3] == onehalf128[ind - 1] &&
  458. (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
  459. // f2* > 1/2 and the result may be exact
  460. // Calculate f2* - 1/2
  461. tmp64 = fstar.w[3] - onehalf128[ind - 1];
  462. if (tmp64 || fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1]
  463. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  464. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  465. // set the inexact flag
  466. *pfpsf |= INEXACT_EXCEPTION;
  467. } // else the result is exact
  468. } else { // the result is inexact; f2* <= 1/2
  469. // set the inexact flag
  470. *pfpsf |= INEXACT_EXCEPTION;
  471. }
  472. }
  473. // if the result was a midpoint, it was already rounded away from zero
  474. res.w[1] |= x_sign | 0x3040000000000000ull;
  475. BID_RETURN (res);
  476. } else { // if ((q + exp) < 0) <=> q < -exp
  477. // the result is +0 or -0
  478. res.w[1] = x_sign | 0x3040000000000000ull;
  479. res.w[0] = 0x0000000000000000ull;
  480. *pfpsf |= INEXACT_EXCEPTION;
  481. BID_RETURN (res);
  482. }
  483. break;
  484. case ROUNDING_DOWN:
  485. if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  486. // need to shift right -exp digits from the coefficient; exp will be 0
  487. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  488. // (number of digits to be chopped off)
  489. // chop off ind digits from the lower part of C1
  490. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  491. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  492. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  493. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  494. // tmp64 = C1.w[0];
  495. // if (ind <= 19) {
  496. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  497. // } else {
  498. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  499. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  500. // }
  501. // if (C1.w[0] < tmp64) C1.w[1]++;
  502. // if carry-out from C1.w[0], increment C1.w[1]
  503. // calculate C* and f*
  504. // C* is actually floor(C*) in this case
  505. // C* and f* need shifting and masking, as shown by
  506. // shiftright128[] and maskhigh128[]
  507. // 1 <= x <= 34
  508. // kx = 10^(-x) = ten2mk128[ind - 1]
  509. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  510. // the approximation of 10^(-x) was rounded up to 118 bits
  511. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  512. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  513. res.w[1] = P256.w[3];
  514. res.w[0] = P256.w[2];
  515. // redundant fstar.w[3] = 0;
  516. // redundant fstar.w[2] = 0;
  517. // redundant fstar.w[1] = P256.w[1];
  518. // redundant fstar.w[0] = P256.w[0];
  519. // fraction f* > 10^(-x) <=> inexact
  520. // f* is in the right position to be compared with
  521. // 10^(-x) from ten2mk128[]
  522. if ((P256.w[1] > ten2mk128[ind - 1].w[1])
  523. || (P256.w[1] == ten2mk128[ind - 1].w[1]
  524. && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
  525. *pfpsf |= INEXACT_EXCEPTION;
  526. // if positive, the truncated value is already the correct result
  527. if (x_sign) { // if negative
  528. if (++res.w[0] == 0) {
  529. res.w[1]++;
  530. }
  531. }
  532. }
  533. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  534. shift = shiftright128[ind - 1]; // 0 <= shift <= 102
  535. res.w[1] = (P256.w[3] >> shift);
  536. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  537. // redundant fstar.w[3] = 0;
  538. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  539. fstar.w[1] = P256.w[1];
  540. fstar.w[0] = P256.w[0];
  541. // fraction f* > 10^(-x) <=> inexact
  542. // f* is in the right position to be compared with
  543. // 10^(-x) from ten2mk128[]
  544. if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  545. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  546. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  547. *pfpsf |= INEXACT_EXCEPTION;
  548. // if positive, the truncated value is already the correct result
  549. if (x_sign) { // if negative
  550. if (++res.w[0] == 0) {
  551. res.w[1]++;
  552. }
  553. }
  554. }
  555. } else { // 22 <= ind - 1 <= 33
  556. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  557. res.w[1] = 0;
  558. res.w[0] = P256.w[3] >> shift;
  559. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  560. fstar.w[2] = P256.w[2];
  561. fstar.w[1] = P256.w[1];
  562. fstar.w[0] = P256.w[0];
  563. // fraction f* > 10^(-x) <=> inexact
  564. // f* is in the right position to be compared with
  565. // 10^(-x) from ten2mk128[]
  566. if (fstar.w[3] || fstar.w[2]
  567. || fstar.w[1] > ten2mk128[ind - 1].w[1]
  568. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  569. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  570. *pfpsf |= INEXACT_EXCEPTION;
  571. // if positive, the truncated value is already the correct result
  572. if (x_sign) { // if negative
  573. if (++res.w[0] == 0) {
  574. res.w[1]++;
  575. }
  576. }
  577. }
  578. }
  579. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  580. BID_RETURN (res);
  581. } else { // if exp < 0 and q + exp <= 0
  582. if (x_sign) { // negative rounds down to -1.0
  583. res.w[1] = 0xb040000000000000ull;
  584. res.w[0] = 0x0000000000000001ull;
  585. } else { // positive rpunds down to +0.0
  586. res.w[1] = 0x3040000000000000ull;
  587. res.w[0] = 0x0000000000000000ull;
  588. }
  589. *pfpsf |= INEXACT_EXCEPTION;
  590. BID_RETURN (res);
  591. }
  592. break;
  593. case ROUNDING_UP:
  594. if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  595. // need to shift right -exp digits from the coefficient; exp will be 0
  596. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  597. // (number of digits to be chopped off)
  598. // chop off ind digits from the lower part of C1
  599. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  600. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  601. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  602. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  603. // tmp64 = C1.w[0];
  604. // if (ind <= 19) {
  605. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  606. // } else {
  607. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  608. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  609. // }
  610. // if (C1.w[0] < tmp64) C1.w[1]++;
  611. // if carry-out from C1.w[0], increment C1.w[1]
  612. // calculate C* and f*
  613. // C* is actually floor(C*) in this case
  614. // C* and f* need shifting and masking, as shown by
  615. // shiftright128[] and maskhigh128[]
  616. // 1 <= x <= 34
  617. // kx = 10^(-x) = ten2mk128[ind - 1]
  618. // C* = C1 * 10^(-x)
  619. // the approximation of 10^(-x) was rounded up to 118 bits
  620. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  621. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  622. res.w[1] = P256.w[3];
  623. res.w[0] = P256.w[2];
  624. // redundant fstar.w[3] = 0;
  625. // redundant fstar.w[2] = 0;
  626. // redundant fstar.w[1] = P256.w[1];
  627. // redundant fstar.w[0] = P256.w[0];
  628. // fraction f* > 10^(-x) <=> inexact
  629. // f* is in the right position to be compared with
  630. // 10^(-x) from ten2mk128[]
  631. if ((P256.w[1] > ten2mk128[ind - 1].w[1])
  632. || (P256.w[1] == ten2mk128[ind - 1].w[1]
  633. && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
  634. *pfpsf |= INEXACT_EXCEPTION;
  635. // if negative, the truncated value is already the correct result
  636. if (!x_sign) { // if positive
  637. if (++res.w[0] == 0) {
  638. res.w[1]++;
  639. }
  640. }
  641. }
  642. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  643. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  644. res.w[1] = (P256.w[3] >> shift);
  645. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  646. // redundant fstar.w[3] = 0;
  647. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  648. fstar.w[1] = P256.w[1];
  649. fstar.w[0] = P256.w[0];
  650. // fraction f* > 10^(-x) <=> inexact
  651. // f* is in the right position to be compared with
  652. // 10^(-x) from ten2mk128[]
  653. if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  654. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  655. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  656. *pfpsf |= INEXACT_EXCEPTION;
  657. // if negative, the truncated value is already the correct result
  658. if (!x_sign) { // if positive
  659. if (++res.w[0] == 0) {
  660. res.w[1]++;
  661. }
  662. }
  663. }
  664. } else { // 22 <= ind - 1 <= 33
  665. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  666. res.w[1] = 0;
  667. res.w[0] = P256.w[3] >> shift;
  668. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  669. fstar.w[2] = P256.w[2];
  670. fstar.w[1] = P256.w[1];
  671. fstar.w[0] = P256.w[0];
  672. // fraction f* > 10^(-x) <=> inexact
  673. // f* is in the right position to be compared with
  674. // 10^(-x) from ten2mk128[]
  675. if (fstar.w[3] || fstar.w[2]
  676. || fstar.w[1] > ten2mk128[ind - 1].w[1]
  677. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  678. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  679. *pfpsf |= INEXACT_EXCEPTION;
  680. // if negative, the truncated value is already the correct result
  681. if (!x_sign) { // if positive
  682. if (++res.w[0] == 0) {
  683. res.w[1]++;
  684. }
  685. }
  686. }
  687. }
  688. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  689. BID_RETURN (res);
  690. } else { // if exp < 0 and q + exp <= 0
  691. if (x_sign) { // negative rounds up to -0.0
  692. res.w[1] = 0xb040000000000000ull;
  693. res.w[0] = 0x0000000000000000ull;
  694. } else { // positive rpunds up to +1.0
  695. res.w[1] = 0x3040000000000000ull;
  696. res.w[0] = 0x0000000000000001ull;
  697. }
  698. *pfpsf |= INEXACT_EXCEPTION;
  699. BID_RETURN (res);
  700. }
  701. break;
  702. case ROUNDING_TO_ZERO:
  703. if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  704. // need to shift right -exp digits from the coefficient; exp will be 0
  705. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  706. // (number of digits to be chopped off)
  707. // chop off ind digits from the lower part of C1
  708. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  709. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  710. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  711. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  712. //tmp64 = C1.w[0];
  713. // if (ind <= 19) {
  714. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  715. // } else {
  716. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  717. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  718. // }
  719. // if (C1.w[0] < tmp64) C1.w[1]++;
  720. // if carry-out from C1.w[0], increment C1.w[1]
  721. // calculate C* and f*
  722. // C* is actually floor(C*) in this case
  723. // C* and f* need shifting and masking, as shown by
  724. // shiftright128[] and maskhigh128[]
  725. // 1 <= x <= 34
  726. // kx = 10^(-x) = ten2mk128[ind - 1]
  727. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  728. // the approximation of 10^(-x) was rounded up to 118 bits
  729. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  730. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  731. res.w[1] = P256.w[3];
  732. res.w[0] = P256.w[2];
  733. // redundant fstar.w[3] = 0;
  734. // redundant fstar.w[2] = 0;
  735. // redundant fstar.w[1] = P256.w[1];
  736. // redundant fstar.w[0] = P256.w[0];
  737. // fraction f* > 10^(-x) <=> inexact
  738. // f* is in the right position to be compared with
  739. // 10^(-x) from ten2mk128[]
  740. if ((P256.w[1] > ten2mk128[ind - 1].w[1])
  741. || (P256.w[1] == ten2mk128[ind - 1].w[1]
  742. && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
  743. *pfpsf |= INEXACT_EXCEPTION;
  744. }
  745. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  746. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  747. res.w[1] = (P256.w[3] >> shift);
  748. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  749. // redundant fstar.w[3] = 0;
  750. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  751. fstar.w[1] = P256.w[1];
  752. fstar.w[0] = P256.w[0];
  753. // fraction f* > 10^(-x) <=> inexact
  754. // f* is in the right position to be compared with
  755. // 10^(-x) from ten2mk128[]
  756. if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  757. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  758. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  759. *pfpsf |= INEXACT_EXCEPTION;
  760. }
  761. } else { // 22 <= ind - 1 <= 33
  762. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  763. res.w[1] = 0;
  764. res.w[0] = P256.w[3] >> shift;
  765. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  766. fstar.w[2] = P256.w[2];
  767. fstar.w[1] = P256.w[1];
  768. fstar.w[0] = P256.w[0];
  769. // fraction f* > 10^(-x) <=> inexact
  770. // f* is in the right position to be compared with
  771. // 10^(-x) from ten2mk128[]
  772. if (fstar.w[3] || fstar.w[2]
  773. || fstar.w[1] > ten2mk128[ind - 1].w[1]
  774. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  775. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  776. *pfpsf |= INEXACT_EXCEPTION;
  777. }
  778. }
  779. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  780. BID_RETURN (res);
  781. } else { // if exp < 0 and q + exp <= 0 the result is +0 or -0
  782. res.w[1] = x_sign | 0x3040000000000000ull;
  783. res.w[0] = 0x0000000000000000ull;
  784. *pfpsf |= INEXACT_EXCEPTION;
  785. BID_RETURN (res);
  786. }
  787. break;
  788. }
  789. BID_RETURN (res);
  790. }
  791. /*****************************************************************************
  792. * BID128_round_integral_nearest_even
  793. ****************************************************************************/
  794. BID128_FUNCTION_ARG1_NORND (bid128_round_integral_nearest_even, x)
  795. UINT128 res;
  796. UINT64 x_sign;
  797. UINT64 x_exp;
  798. int exp; // unbiased exponent
  799. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
  800. UINT64 tmp64;
  801. BID_UI64DOUBLE tmp1;
  802. unsigned int x_nr_bits;
  803. int q, ind, shift;
  804. UINT128 C1;
  805. // UINT128 res is C* at first - represents up to 34 decimal digits ~ 113 bits
  806. UINT256 fstar;
  807. UINT256 P256;
  808. // check for NaN or Infinity
  809. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  810. // x is special
  811. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  812. // if x = NaN, then res = Q (x)
  813. // check first for non-canonical NaN payload
  814. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  815. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  816. (x.w[0] > 0x38c15b09ffffffffull))) {
  817. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  818. x.w[0] = 0x0ull;
  819. }
  820. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  821. // set invalid flag
  822. *pfpsf |= INVALID_EXCEPTION;
  823. // return quiet (x)
  824. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  825. res.w[0] = x.w[0];
  826. } else { // x is QNaN
  827. // return x
  828. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  829. res.w[0] = x.w[0];
  830. }
  831. BID_RETURN (res)
  832. } else { // x is not a NaN, so it must be infinity
  833. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  834. // return +inf
  835. res.w[1] = 0x7800000000000000ull;
  836. res.w[0] = 0x0000000000000000ull;
  837. } else { // x is -inf
  838. // return -inf
  839. res.w[1] = 0xf800000000000000ull;
  840. res.w[0] = 0x0000000000000000ull;
  841. }
  842. BID_RETURN (res);
  843. }
  844. }
  845. // unpack x
  846. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  847. C1.w[1] = x.w[1] & MASK_COEFF;
  848. C1.w[0] = x.w[0];
  849. // check for non-canonical values (treated as zero)
  850. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  851. // non-canonical
  852. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  853. C1.w[1] = 0; // significand high
  854. C1.w[0] = 0; // significand low
  855. } else { // G0_G1 != 11
  856. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  857. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  858. (C1.w[1] == 0x0001ed09bead87c0ull
  859. && C1.w[0] > 0x378d8e63ffffffffull)) {
  860. // x is non-canonical if coefficient is larger than 10^34 -1
  861. C1.w[1] = 0;
  862. C1.w[0] = 0;
  863. } else { // canonical
  864. ;
  865. }
  866. }
  867. // test for input equal to zero
  868. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  869. // x is 0
  870. // return 0 preserving the sign bit and the preferred exponent
  871. // of MAX(Q(x), 0)
  872. if (x_exp <= (0x1820ull << 49)) {
  873. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  874. } else {
  875. res.w[1] = x_sign | x_exp;
  876. }
  877. res.w[0] = 0x0000000000000000ull;
  878. BID_RETURN (res);
  879. }
  880. // x is not special and is not zero
  881. // if (exp <= -(p+1)) return 0
  882. if (x_exp <= 0x2ffa000000000000ull) { // 0x2ffa000000000000ull == -35
  883. res.w[1] = x_sign | 0x3040000000000000ull;
  884. res.w[0] = 0x0000000000000000ull;
  885. BID_RETURN (res);
  886. }
  887. // q = nr. of decimal digits in x
  888. // determine first the nr. of bits in x
  889. if (C1.w[1] == 0) {
  890. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  891. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  892. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  893. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  894. x_nr_bits =
  895. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  896. } else { // x < 2^32
  897. tmp1.d = (double) (C1.w[0]); // exact conversion
  898. x_nr_bits =
  899. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  900. }
  901. } else { // if x < 2^53
  902. tmp1.d = (double) C1.w[0]; // exact conversion
  903. x_nr_bits =
  904. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  905. }
  906. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  907. tmp1.d = (double) C1.w[1]; // exact conversion
  908. x_nr_bits =
  909. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  910. }
  911. q = nr_digits[x_nr_bits - 1].digits;
  912. if (q == 0) {
  913. q = nr_digits[x_nr_bits - 1].digits1;
  914. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
  915. || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  916. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  917. q++;
  918. }
  919. exp = (x_exp >> 49) - 6176;
  920. if (exp >= 0) { // -exp <= 0
  921. // the argument is an integer already
  922. res.w[1] = x.w[1];
  923. res.w[0] = x.w[0];
  924. BID_RETURN (res);
  925. } else if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
  926. // need to shift right -exp digits from the coefficient; the exp will be 0
  927. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  928. // chop off ind digits from the lower part of C1
  929. // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
  930. tmp64 = C1.w[0];
  931. if (ind <= 19) {
  932. C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  933. } else {
  934. C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  935. C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  936. }
  937. if (C1.w[0] < tmp64)
  938. C1.w[1]++;
  939. // calculate C* and f*
  940. // C* is actually floor(C*) in this case
  941. // C* and f* need shifting and masking, as shown by
  942. // shiftright128[] and maskhigh128[]
  943. // 1 <= x <= 34
  944. // kx = 10^(-x) = ten2mk128[ind - 1]
  945. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  946. // the approximation of 10^(-x) was rounded up to 118 bits
  947. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  948. // determine the value of res and fstar
  949. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  950. // redundant shift = shiftright128[ind - 1]; // shift = 0
  951. res.w[1] = P256.w[3];
  952. res.w[0] = P256.w[2];
  953. // redundant fstar.w[3] = 0;
  954. // redundant fstar.w[2] = 0;
  955. // redundant fstar.w[1] = P256.w[1];
  956. // redundant fstar.w[0] = P256.w[0];
  957. // fraction f* < 10^(-x) <=> midpoint
  958. // f* is in the right position to be compared with
  959. // 10^(-x) from ten2mk128[]
  960. // if 0 < fstar < 10^(-x), subtract 1 if odd (for rounding to even)
  961. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  962. ((P256.w[1] < (ten2mk128[ind - 1].w[1]))
  963. || ((P256.w[1] == ten2mk128[ind - 1].w[1])
  964. && (P256.w[0] < ten2mk128[ind - 1].w[0])))) {
  965. // subract 1 to make even
  966. if (res.w[0]-- == 0) {
  967. res.w[1]--;
  968. }
  969. }
  970. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  971. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  972. res.w[1] = (P256.w[3] >> shift);
  973. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  974. // redundant fstar.w[3] = 0;
  975. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  976. fstar.w[1] = P256.w[1];
  977. fstar.w[0] = P256.w[0];
  978. // fraction f* < 10^(-x) <=> midpoint
  979. // f* is in the right position to be compared with
  980. // 10^(-x) from ten2mk128[]
  981. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  982. fstar.w[2] == 0 && (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
  983. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  984. fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
  985. // subract 1 to make even
  986. if (res.w[0]-- == 0) {
  987. res.w[1]--;
  988. }
  989. }
  990. } else { // 22 <= ind - 1 <= 33
  991. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  992. res.w[1] = 0;
  993. res.w[0] = P256.w[3] >> shift;
  994. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  995. fstar.w[2] = P256.w[2];
  996. fstar.w[1] = P256.w[1];
  997. fstar.w[0] = P256.w[0];
  998. // fraction f* < 10^(-x) <=> midpoint
  999. // f* is in the right position to be compared with
  1000. // 10^(-x) from ten2mk128[]
  1001. if ((res.w[0] & 0x0000000000000001ull) && // is result odd?
  1002. fstar.w[3] == 0 && fstar.w[2] == 0
  1003. && (fstar.w[1] < ten2mk128[ind - 1].w[1]
  1004. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  1005. && fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
  1006. // subract 1 to make even
  1007. if (res.w[0]-- == 0) {
  1008. res.w[1]--;
  1009. }
  1010. }
  1011. }
  1012. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  1013. BID_RETURN (res);
  1014. } else { // if ((q + exp) < 0) <=> q < -exp
  1015. // the result is +0 or -0
  1016. res.w[1] = x_sign | 0x3040000000000000ull;
  1017. res.w[0] = 0x0000000000000000ull;
  1018. BID_RETURN (res);
  1019. }
  1020. }
  1021. /*****************************************************************************
  1022. * BID128_round_integral_negative
  1023. ****************************************************************************/
  1024. BID128_FUNCTION_ARG1_NORND (bid128_round_integral_negative, x)
  1025. UINT128 res;
  1026. UINT64 x_sign;
  1027. UINT64 x_exp;
  1028. int exp; // unbiased exponent
  1029. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo
  1030. // (all are UINT64)
  1031. BID_UI64DOUBLE tmp1;
  1032. unsigned int x_nr_bits;
  1033. int q, ind, shift;
  1034. UINT128 C1;
  1035. // UINT128 res is C* at first - represents up to 34 decimal digits ~
  1036. // 113 bits
  1037. UINT256 fstar;
  1038. UINT256 P256;
  1039. // check for NaN or Infinity
  1040. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  1041. // x is special
  1042. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  1043. // if x = NaN, then res = Q (x)
  1044. // check first for non-canonical NaN payload
  1045. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  1046. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  1047. (x.w[0] > 0x38c15b09ffffffffull))) {
  1048. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  1049. x.w[0] = 0x0ull;
  1050. }
  1051. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  1052. // set invalid flag
  1053. *pfpsf |= INVALID_EXCEPTION;
  1054. // return quiet (x)
  1055. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  1056. res.w[0] = x.w[0];
  1057. } else { // x is QNaN
  1058. // return x
  1059. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  1060. res.w[0] = x.w[0];
  1061. }
  1062. BID_RETURN (res)
  1063. } else { // x is not a NaN, so it must be infinity
  1064. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  1065. // return +inf
  1066. res.w[1] = 0x7800000000000000ull;
  1067. res.w[0] = 0x0000000000000000ull;
  1068. } else { // x is -inf
  1069. // return -inf
  1070. res.w[1] = 0xf800000000000000ull;
  1071. res.w[0] = 0x0000000000000000ull;
  1072. }
  1073. BID_RETURN (res);
  1074. }
  1075. }
  1076. // unpack x
  1077. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1078. C1.w[1] = x.w[1] & MASK_COEFF;
  1079. C1.w[0] = x.w[0];
  1080. // check for non-canonical values (treated as zero)
  1081. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  1082. // non-canonical
  1083. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  1084. C1.w[1] = 0; // significand high
  1085. C1.w[0] = 0; // significand low
  1086. } else { // G0_G1 != 11
  1087. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  1088. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  1089. (C1.w[1] == 0x0001ed09bead87c0ull
  1090. && C1.w[0] > 0x378d8e63ffffffffull)) {
  1091. // x is non-canonical if coefficient is larger than 10^34 -1
  1092. C1.w[1] = 0;
  1093. C1.w[0] = 0;
  1094. } else { // canonical
  1095. ;
  1096. }
  1097. }
  1098. // test for input equal to zero
  1099. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  1100. // x is 0
  1101. // return 0 preserving the sign bit and the preferred exponent
  1102. // of MAX(Q(x), 0)
  1103. if (x_exp <= (0x1820ull << 49)) {
  1104. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  1105. } else {
  1106. res.w[1] = x_sign | x_exp;
  1107. }
  1108. res.w[0] = 0x0000000000000000ull;
  1109. BID_RETURN (res);
  1110. }
  1111. // x is not special and is not zero
  1112. // if (exp <= -p) return -1.0 or +0.0
  1113. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffc000000000000ull == -34
  1114. if (x_sign) {
  1115. // if negative, return negative 1, because we know the coefficient
  1116. // is non-zero (would have been caught above)
  1117. res.w[1] = 0xb040000000000000ull;
  1118. res.w[0] = 0x0000000000000001ull;
  1119. } else {
  1120. // if positive, return positive 0, because we know coefficient is
  1121. // non-zero (would have been caught above)
  1122. res.w[1] = 0x3040000000000000ull;
  1123. res.w[0] = 0x0000000000000000ull;
  1124. }
  1125. BID_RETURN (res);
  1126. }
  1127. // q = nr. of decimal digits in x
  1128. // determine first the nr. of bits in x
  1129. if (C1.w[1] == 0) {
  1130. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  1131. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1132. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  1133. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  1134. x_nr_bits =
  1135. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1136. } else { // x < 2^32
  1137. tmp1.d = (double) (C1.w[0]); // exact conversion
  1138. x_nr_bits =
  1139. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1140. }
  1141. } else { // if x < 2^53
  1142. tmp1.d = (double) C1.w[0]; // exact conversion
  1143. x_nr_bits =
  1144. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1145. }
  1146. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  1147. tmp1.d = (double) C1.w[1]; // exact conversion
  1148. x_nr_bits =
  1149. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1150. }
  1151. q = nr_digits[x_nr_bits - 1].digits;
  1152. if (q == 0) {
  1153. q = nr_digits[x_nr_bits - 1].digits1;
  1154. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
  1155. (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  1156. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  1157. q++;
  1158. }
  1159. exp = (x_exp >> 49) - 6176;
  1160. if (exp >= 0) { // -exp <= 0
  1161. // the argument is an integer already
  1162. res.w[1] = x.w[1];
  1163. res.w[0] = x.w[0];
  1164. BID_RETURN (res);
  1165. } else if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  1166. // need to shift right -exp digits from the coefficient; the exp will be 0
  1167. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  1168. // (number of digits to be chopped off)
  1169. // chop off ind digits from the lower part of C1
  1170. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  1171. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  1172. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  1173. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  1174. //tmp64 = C1.w[0];
  1175. // if (ind <= 19) {
  1176. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  1177. // } else {
  1178. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  1179. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  1180. // }
  1181. // if (C1.w[0] < tmp64) C1.w[1]++;
  1182. // if carry-out from C1.w[0], increment C1.w[1]
  1183. // calculate C* and f*
  1184. // C* is actually floor(C*) in this case
  1185. // C* and f* need shifting and masking, as shown by
  1186. // shiftright128[] and maskhigh128[]
  1187. // 1 <= x <= 34
  1188. // kx = 10^(-x) = ten2mk128[ind - 1]
  1189. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  1190. // the approximation of 10^(-x) was rounded up to 118 bits
  1191. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  1192. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  1193. res.w[1] = P256.w[3];
  1194. res.w[0] = P256.w[2];
  1195. // if positive, the truncated value is already the correct result
  1196. if (x_sign) { // if negative
  1197. // redundant fstar.w[3] = 0;
  1198. // redundant fstar.w[2] = 0;
  1199. // redundant fstar.w[1] = P256.w[1];
  1200. // redundant fstar.w[0] = P256.w[0];
  1201. // fraction f* > 10^(-x) <=> inexact
  1202. // f* is in the right position to be compared with
  1203. // 10^(-x) from ten2mk128[]
  1204. if ((P256.w[1] > ten2mk128[ind - 1].w[1])
  1205. || (P256.w[1] == ten2mk128[ind - 1].w[1]
  1206. && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
  1207. if (++res.w[0] == 0) {
  1208. res.w[1]++;
  1209. }
  1210. }
  1211. }
  1212. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  1213. shift = shiftright128[ind - 1]; // 0 <= shift <= 102
  1214. res.w[1] = (P256.w[3] >> shift);
  1215. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  1216. // if positive, the truncated value is already the correct result
  1217. if (x_sign) { // if negative
  1218. // redundant fstar.w[3] = 0;
  1219. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  1220. fstar.w[1] = P256.w[1];
  1221. fstar.w[0] = P256.w[0];
  1222. // fraction f* > 10^(-x) <=> inexact
  1223. // f* is in the right position to be compared with
  1224. // 10^(-x) from ten2mk128[]
  1225. if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  1226. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  1227. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  1228. if (++res.w[0] == 0) {
  1229. res.w[1]++;
  1230. }
  1231. }
  1232. }
  1233. } else { // 22 <= ind - 1 <= 33
  1234. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  1235. res.w[1] = 0;
  1236. res.w[0] = P256.w[3] >> shift;
  1237. // if positive, the truncated value is already the correct result
  1238. if (x_sign) { // if negative
  1239. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  1240. fstar.w[2] = P256.w[2];
  1241. fstar.w[1] = P256.w[1];
  1242. fstar.w[0] = P256.w[0];
  1243. // fraction f* > 10^(-x) <=> inexact
  1244. // f* is in the right position to be compared with
  1245. // 10^(-x) from ten2mk128[]
  1246. if (fstar.w[3] || fstar.w[2]
  1247. || fstar.w[1] > ten2mk128[ind - 1].w[1]
  1248. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  1249. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  1250. if (++res.w[0] == 0) {
  1251. res.w[1]++;
  1252. }
  1253. }
  1254. }
  1255. }
  1256. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  1257. BID_RETURN (res);
  1258. } else { // if exp < 0 and q + exp <= 0
  1259. if (x_sign) { // negative rounds down to -1.0
  1260. res.w[1] = 0xb040000000000000ull;
  1261. res.w[0] = 0x0000000000000001ull;
  1262. } else { // positive rpunds down to +0.0
  1263. res.w[1] = 0x3040000000000000ull;
  1264. res.w[0] = 0x0000000000000000ull;
  1265. }
  1266. BID_RETURN (res);
  1267. }
  1268. }
  1269. /*****************************************************************************
  1270. * BID128_round_integral_positive
  1271. ****************************************************************************/
  1272. BID128_FUNCTION_ARG1_NORND (bid128_round_integral_positive, x)
  1273. UINT128 res;
  1274. UINT64 x_sign;
  1275. UINT64 x_exp;
  1276. int exp; // unbiased exponent
  1277. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo
  1278. // (all are UINT64)
  1279. BID_UI64DOUBLE tmp1;
  1280. unsigned int x_nr_bits;
  1281. int q, ind, shift;
  1282. UINT128 C1;
  1283. // UINT128 res is C* at first - represents up to 34 decimal digits ~
  1284. // 113 bits
  1285. UINT256 fstar;
  1286. UINT256 P256;
  1287. // check for NaN or Infinity
  1288. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  1289. // x is special
  1290. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  1291. // if x = NaN, then res = Q (x)
  1292. // check first for non-canonical NaN payload
  1293. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  1294. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  1295. (x.w[0] > 0x38c15b09ffffffffull))) {
  1296. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  1297. x.w[0] = 0x0ull;
  1298. }
  1299. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  1300. // set invalid flag
  1301. *pfpsf |= INVALID_EXCEPTION;
  1302. // return quiet (x)
  1303. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  1304. res.w[0] = x.w[0];
  1305. } else { // x is QNaN
  1306. // return x
  1307. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  1308. res.w[0] = x.w[0];
  1309. }
  1310. BID_RETURN (res)
  1311. } else { // x is not a NaN, so it must be infinity
  1312. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  1313. // return +inf
  1314. res.w[1] = 0x7800000000000000ull;
  1315. res.w[0] = 0x0000000000000000ull;
  1316. } else { // x is -inf
  1317. // return -inf
  1318. res.w[1] = 0xf800000000000000ull;
  1319. res.w[0] = 0x0000000000000000ull;
  1320. }
  1321. BID_RETURN (res);
  1322. }
  1323. }
  1324. // unpack x
  1325. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1326. C1.w[1] = x.w[1] & MASK_COEFF;
  1327. C1.w[0] = x.w[0];
  1328. // check for non-canonical values (treated as zero)
  1329. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  1330. // non-canonical
  1331. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  1332. C1.w[1] = 0; // significand high
  1333. C1.w[0] = 0; // significand low
  1334. } else { // G0_G1 != 11
  1335. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  1336. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  1337. (C1.w[1] == 0x0001ed09bead87c0ull
  1338. && C1.w[0] > 0x378d8e63ffffffffull)) {
  1339. // x is non-canonical if coefficient is larger than 10^34 -1
  1340. C1.w[1] = 0;
  1341. C1.w[0] = 0;
  1342. } else { // canonical
  1343. ;
  1344. }
  1345. }
  1346. // test for input equal to zero
  1347. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  1348. // x is 0
  1349. // return 0 preserving the sign bit and the preferred exponent
  1350. // of MAX(Q(x), 0)
  1351. if (x_exp <= (0x1820ull << 49)) {
  1352. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  1353. } else {
  1354. res.w[1] = x_sign | x_exp;
  1355. }
  1356. res.w[0] = 0x0000000000000000ull;
  1357. BID_RETURN (res);
  1358. }
  1359. // x is not special and is not zero
  1360. // if (exp <= -p) return -0.0 or +1.0
  1361. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffc000000000000ull == -34
  1362. if (x_sign) {
  1363. // if negative, return negative 0, because we know the coefficient
  1364. // is non-zero (would have been caught above)
  1365. res.w[1] = 0xb040000000000000ull;
  1366. res.w[0] = 0x0000000000000000ull;
  1367. } else {
  1368. // if positive, return positive 1, because we know coefficient is
  1369. // non-zero (would have been caught above)
  1370. res.w[1] = 0x3040000000000000ull;
  1371. res.w[0] = 0x0000000000000001ull;
  1372. }
  1373. BID_RETURN (res);
  1374. }
  1375. // q = nr. of decimal digits in x
  1376. // determine first the nr. of bits in x
  1377. if (C1.w[1] == 0) {
  1378. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  1379. // split 64-bit value in two 32-bit halves to avoid rounding errors
  1380. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  1381. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  1382. x_nr_bits =
  1383. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1384. } else { // x < 2^32
  1385. tmp1.d = (double) (C1.w[0]); // exact conversion
  1386. x_nr_bits =
  1387. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1388. }
  1389. } else { // if x < 2^53
  1390. tmp1.d = (double) C1.w[0]; // exact conversion
  1391. x_nr_bits =
  1392. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1393. }
  1394. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  1395. tmp1.d = (double) C1.w[1]; // exact conversion
  1396. x_nr_bits =
  1397. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1398. }
  1399. q = nr_digits[x_nr_bits - 1].digits;
  1400. if (q == 0) {
  1401. q = nr_digits[x_nr_bits - 1].digits1;
  1402. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
  1403. (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  1404. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  1405. q++;
  1406. }
  1407. exp = (x_exp >> 49) - 6176;
  1408. if (exp >= 0) { // -exp <= 0
  1409. // the argument is an integer already
  1410. res.w[1] = x.w[1];
  1411. res.w[0] = x.w[0];
  1412. BID_RETURN (res);
  1413. } else if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  1414. // need to shift right -exp digits from the coefficient; exp will be 0
  1415. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  1416. // (number of digits to be chopped off)
  1417. // chop off ind digits from the lower part of C1
  1418. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  1419. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  1420. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  1421. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  1422. // tmp64 = C1.w[0];
  1423. // if (ind <= 19) {
  1424. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  1425. // } else {
  1426. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  1427. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  1428. // }
  1429. // if (C1.w[0] < tmp64) C1.w[1]++;
  1430. // if carry-out from C1.w[0], increment C1.w[1]
  1431. // calculate C* and f*
  1432. // C* is actually floor(C*) in this case
  1433. // C* and f* need shifting and masking, as shown by
  1434. // shiftright128[] and maskhigh128[]
  1435. // 1 <= x <= 34
  1436. // kx = 10^(-x) = ten2mk128[ind - 1]
  1437. // C* = C1 * 10^(-x)
  1438. // the approximation of 10^(-x) was rounded up to 118 bits
  1439. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  1440. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  1441. res.w[1] = P256.w[3];
  1442. res.w[0] = P256.w[2];
  1443. // if negative, the truncated value is already the correct result
  1444. if (!x_sign) { // if positive
  1445. // redundant fstar.w[3] = 0;
  1446. // redundant fstar.w[2] = 0;
  1447. // redundant fstar.w[1] = P256.w[1];
  1448. // redundant fstar.w[0] = P256.w[0];
  1449. // fraction f* > 10^(-x) <=> inexact
  1450. // f* is in the right position to be compared with
  1451. // 10^(-x) from ten2mk128[]
  1452. if ((P256.w[1] > ten2mk128[ind - 1].w[1])
  1453. || (P256.w[1] == ten2mk128[ind - 1].w[1]
  1454. && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
  1455. if (++res.w[0] == 0) {
  1456. res.w[1]++;
  1457. }
  1458. }
  1459. }
  1460. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  1461. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  1462. res.w[1] = (P256.w[3] >> shift);
  1463. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  1464. // if negative, the truncated value is already the correct result
  1465. if (!x_sign) { // if positive
  1466. // redundant fstar.w[3] = 0;
  1467. fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
  1468. fstar.w[1] = P256.w[1];
  1469. fstar.w[0] = P256.w[0];
  1470. // fraction f* > 10^(-x) <=> inexact
  1471. // f* is in the right position to be compared with
  1472. // 10^(-x) from ten2mk128[]
  1473. if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
  1474. (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
  1475. fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  1476. if (++res.w[0] == 0) {
  1477. res.w[1]++;
  1478. }
  1479. }
  1480. }
  1481. } else { // 22 <= ind - 1 <= 33
  1482. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  1483. res.w[1] = 0;
  1484. res.w[0] = P256.w[3] >> shift;
  1485. // if negative, the truncated value is already the correct result
  1486. if (!x_sign) { // if positive
  1487. fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
  1488. fstar.w[2] = P256.w[2];
  1489. fstar.w[1] = P256.w[1];
  1490. fstar.w[0] = P256.w[0];
  1491. // fraction f* > 10^(-x) <=> inexact
  1492. // f* is in the right position to be compared with
  1493. // 10^(-x) from ten2mk128[]
  1494. if (fstar.w[3] || fstar.w[2]
  1495. || fstar.w[1] > ten2mk128[ind - 1].w[1]
  1496. || (fstar.w[1] == ten2mk128[ind - 1].w[1]
  1497. && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
  1498. if (++res.w[0] == 0) {
  1499. res.w[1]++;
  1500. }
  1501. }
  1502. }
  1503. }
  1504. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  1505. BID_RETURN (res);
  1506. } else { // if exp < 0 and q + exp <= 0
  1507. if (x_sign) { // negative rounds up to -0.0
  1508. res.w[1] = 0xb040000000000000ull;
  1509. res.w[0] = 0x0000000000000000ull;
  1510. } else { // positive rpunds up to +1.0
  1511. res.w[1] = 0x3040000000000000ull;
  1512. res.w[0] = 0x0000000000000001ull;
  1513. }
  1514. BID_RETURN (res);
  1515. }
  1516. }
  1517. /*****************************************************************************
  1518. * BID128_round_integral_zero
  1519. ****************************************************************************/
  1520. BID128_FUNCTION_ARG1_NORND (bid128_round_integral_zero, x)
  1521. UINT128 res;
  1522. UINT64 x_sign;
  1523. UINT64 x_exp;
  1524. int exp; // unbiased exponent
  1525. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo
  1526. // (all are UINT64)
  1527. BID_UI64DOUBLE tmp1;
  1528. unsigned int x_nr_bits;
  1529. int q, ind, shift;
  1530. UINT128 C1;
  1531. // UINT128 res is C* at first - represents up to 34 decimal digits ~
  1532. // 113 bits
  1533. UINT256 P256;
  1534. // check for NaN or Infinity
  1535. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  1536. // x is special
  1537. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  1538. // if x = NaN, then res = Q (x)
  1539. // check first for non-canonical NaN payload
  1540. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  1541. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  1542. (x.w[0] > 0x38c15b09ffffffffull))) {
  1543. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  1544. x.w[0] = 0x0ull;
  1545. }
  1546. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  1547. // set invalid flag
  1548. *pfpsf |= INVALID_EXCEPTION;
  1549. // return quiet (x)
  1550. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  1551. res.w[0] = x.w[0];
  1552. } else { // x is QNaN
  1553. // return x
  1554. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  1555. res.w[0] = x.w[0];
  1556. }
  1557. BID_RETURN (res)
  1558. } else { // x is not a NaN, so it must be infinity
  1559. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  1560. // return +inf
  1561. res.w[1] = 0x7800000000000000ull;
  1562. res.w[0] = 0x0000000000000000ull;
  1563. } else { // x is -inf
  1564. // return -inf
  1565. res.w[1] = 0xf800000000000000ull;
  1566. res.w[0] = 0x0000000000000000ull;
  1567. }
  1568. BID_RETURN (res);
  1569. }
  1570. }
  1571. // unpack x
  1572. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1573. C1.w[1] = x.w[1] & MASK_COEFF;
  1574. C1.w[0] = x.w[0];
  1575. // check for non-canonical values (treated as zero)
  1576. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  1577. // non-canonical
  1578. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  1579. C1.w[1] = 0; // significand high
  1580. C1.w[0] = 0; // significand low
  1581. } else { // G0_G1 != 11
  1582. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  1583. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  1584. (C1.w[1] == 0x0001ed09bead87c0ull
  1585. && C1.w[0] > 0x378d8e63ffffffffull)) {
  1586. // x is non-canonical if coefficient is larger than 10^34 -1
  1587. C1.w[1] = 0;
  1588. C1.w[0] = 0;
  1589. } else { // canonical
  1590. ;
  1591. }
  1592. }
  1593. // test for input equal to zero
  1594. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  1595. // x is 0
  1596. // return 0 preserving the sign bit and the preferred exponent
  1597. // of MAX(Q(x), 0)
  1598. if (x_exp <= (0x1820ull << 49)) {
  1599. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  1600. } else {
  1601. res.w[1] = x_sign | x_exp;
  1602. }
  1603. res.w[0] = 0x0000000000000000ull;
  1604. BID_RETURN (res);
  1605. }
  1606. // x is not special and is not zero
  1607. // if (exp <= -p) return -0.0 or +0.0
  1608. if (x_exp <= 0x2ffc000000000000ull) { // 0x2ffc000000000000ull == -34
  1609. res.w[1] = x_sign | 0x3040000000000000ull;
  1610. res.w[0] = 0x0000000000000000ull;
  1611. BID_RETURN (res);
  1612. }
  1613. // q = nr. of decimal digits in x
  1614. // determine first the nr. of bits in x
  1615. if (C1.w[1] == 0) {
  1616. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  1617. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1618. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  1619. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  1620. x_nr_bits =
  1621. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1622. } else { // x < 2^32
  1623. tmp1.d = (double) (C1.w[0]); // exact conversion
  1624. x_nr_bits =
  1625. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1626. }
  1627. } else { // if x < 2^53
  1628. tmp1.d = (double) C1.w[0]; // exact conversion
  1629. x_nr_bits =
  1630. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1631. }
  1632. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  1633. tmp1.d = (double) C1.w[1]; // exact conversion
  1634. x_nr_bits =
  1635. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1636. }
  1637. q = nr_digits[x_nr_bits - 1].digits;
  1638. if (q == 0) {
  1639. q = nr_digits[x_nr_bits - 1].digits1;
  1640. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
  1641. (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  1642. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  1643. q++;
  1644. }
  1645. exp = (x_exp >> 49) - 6176;
  1646. if (exp >= 0) { // -exp <= 0
  1647. // the argument is an integer already
  1648. res.w[1] = x.w[1];
  1649. res.w[0] = x.w[0];
  1650. BID_RETURN (res);
  1651. } else if ((q + exp) > 0) { // exp < 0 and 1 <= -exp < q
  1652. // need to shift right -exp digits from the coefficient; the exp will be 0
  1653. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  1654. // (number of digits to be chopped off)
  1655. // chop off ind digits from the lower part of C1
  1656. // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
  1657. // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
  1658. // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
  1659. // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
  1660. //tmp64 = C1.w[0];
  1661. // if (ind <= 19) {
  1662. // C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  1663. // } else {
  1664. // C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  1665. // C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  1666. // }
  1667. // if (C1.w[0] < tmp64) C1.w[1]++;
  1668. // if carry-out from C1.w[0], increment C1.w[1]
  1669. // calculate C* and f*
  1670. // C* is actually floor(C*) in this case
  1671. // C* and f* need shifting and masking, as shown by
  1672. // shiftright128[] and maskhigh128[]
  1673. // 1 <= x <= 34
  1674. // kx = 10^(-x) = ten2mk128[ind - 1]
  1675. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  1676. // the approximation of 10^(-x) was rounded up to 118 bits
  1677. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  1678. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  1679. res.w[1] = P256.w[3];
  1680. res.w[0] = P256.w[2];
  1681. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  1682. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  1683. res.w[1] = (P256.w[3] >> shift);
  1684. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  1685. } else { // 22 <= ind - 1 <= 33
  1686. shift = shiftright128[ind - 1] - 64; // 2 <= shift <= 38
  1687. res.w[1] = 0;
  1688. res.w[0] = P256.w[3] >> shift;
  1689. }
  1690. res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
  1691. BID_RETURN (res);
  1692. } else { // if exp < 0 and q + exp <= 0 the result is +0 or -0
  1693. res.w[1] = x_sign | 0x3040000000000000ull;
  1694. res.w[0] = 0x0000000000000000ull;
  1695. BID_RETURN (res);
  1696. }
  1697. }
  1698. /*****************************************************************************
  1699. * BID128_round_integral_nearest_away
  1700. ****************************************************************************/
  1701. BID128_FUNCTION_ARG1_NORND (bid128_round_integral_nearest_away, x)
  1702. UINT128 res;
  1703. UINT64 x_sign;
  1704. UINT64 x_exp;
  1705. int exp; // unbiased exponent
  1706. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo
  1707. // (all are UINT64)
  1708. UINT64 tmp64;
  1709. BID_UI64DOUBLE tmp1;
  1710. unsigned int x_nr_bits;
  1711. int q, ind, shift;
  1712. UINT128 C1;
  1713. // UINT128 res is C* at first - represents up to 34 decimal digits ~
  1714. // 113 bits
  1715. // UINT256 fstar;
  1716. UINT256 P256;
  1717. // check for NaN or Infinity
  1718. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  1719. // x is special
  1720. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  1721. // if x = NaN, then res = Q (x)
  1722. // check first for non-canonical NaN payload
  1723. if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
  1724. (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
  1725. (x.w[0] > 0x38c15b09ffffffffull))) {
  1726. x.w[1] = x.w[1] & 0xffffc00000000000ull;
  1727. x.w[0] = 0x0ull;
  1728. }
  1729. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  1730. // set invalid flag
  1731. *pfpsf |= INVALID_EXCEPTION;
  1732. // return quiet (x)
  1733. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
  1734. res.w[0] = x.w[0];
  1735. } else { // x is QNaN
  1736. // return x
  1737. res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
  1738. res.w[0] = x.w[0];
  1739. }
  1740. BID_RETURN (res)
  1741. } else { // x is not a NaN, so it must be infinity
  1742. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  1743. // return +inf
  1744. res.w[1] = 0x7800000000000000ull;
  1745. res.w[0] = 0x0000000000000000ull;
  1746. } else { // x is -inf
  1747. // return -inf
  1748. res.w[1] = 0xf800000000000000ull;
  1749. res.w[0] = 0x0000000000000000ull;
  1750. }
  1751. BID_RETURN (res);
  1752. }
  1753. }
  1754. // unpack x
  1755. x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1756. C1.w[1] = x.w[1] & MASK_COEFF;
  1757. C1.w[0] = x.w[0];
  1758. // check for non-canonical values (treated as zero)
  1759. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
  1760. // non-canonical
  1761. x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  1762. C1.w[1] = 0; // significand high
  1763. C1.w[0] = 0; // significand low
  1764. } else { // G0_G1 != 11
  1765. x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
  1766. if (C1.w[1] > 0x0001ed09bead87c0ull ||
  1767. (C1.w[1] == 0x0001ed09bead87c0ull
  1768. && C1.w[0] > 0x378d8e63ffffffffull)) {
  1769. // x is non-canonical if coefficient is larger than 10^34 -1
  1770. C1.w[1] = 0;
  1771. C1.w[0] = 0;
  1772. } else { // canonical
  1773. ;
  1774. }
  1775. }
  1776. // test for input equal to zero
  1777. if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
  1778. // x is 0
  1779. // return 0 preserving the sign bit and the preferred exponent
  1780. // of MAX(Q(x), 0)
  1781. if (x_exp <= (0x1820ull << 49)) {
  1782. res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
  1783. } else {
  1784. res.w[1] = x_sign | x_exp;
  1785. }
  1786. res.w[0] = 0x0000000000000000ull;
  1787. BID_RETURN (res);
  1788. }
  1789. // x is not special and is not zero
  1790. // if (exp <= -(p+1)) return 0.0
  1791. if (x_exp <= 0x2ffa000000000000ull) { // 0x2ffa000000000000ull == -35
  1792. res.w[1] = x_sign | 0x3040000000000000ull;
  1793. res.w[0] = 0x0000000000000000ull;
  1794. BID_RETURN (res);
  1795. }
  1796. // q = nr. of decimal digits in x
  1797. // determine first the nr. of bits in x
  1798. if (C1.w[1] == 0) {
  1799. if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
  1800. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1801. if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
  1802. tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
  1803. x_nr_bits =
  1804. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1805. } else { // x < 2^32
  1806. tmp1.d = (double) (C1.w[0]); // exact conversion
  1807. x_nr_bits =
  1808. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1809. }
  1810. } else { // if x < 2^53
  1811. tmp1.d = (double) C1.w[0]; // exact conversion
  1812. x_nr_bits =
  1813. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1814. }
  1815. } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
  1816. tmp1.d = (double) C1.w[1]; // exact conversion
  1817. x_nr_bits =
  1818. 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1819. }
  1820. q = nr_digits[x_nr_bits - 1].digits;
  1821. if (q == 0) {
  1822. q = nr_digits[x_nr_bits - 1].digits1;
  1823. if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
  1824. (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
  1825. C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
  1826. q++;
  1827. }
  1828. exp = (x_exp >> 49) - 6176;
  1829. if (exp >= 0) { // -exp <= 0
  1830. // the argument is an integer already
  1831. res.w[1] = x.w[1];
  1832. res.w[0] = x.w[0];
  1833. BID_RETURN (res);
  1834. } else if ((q + exp) >= 0) { // exp < 0 and 1 <= -exp <= q
  1835. // need to shift right -exp digits from the coefficient; the exp will be 0
  1836. ind = -exp; // 1 <= ind <= 34; ind is a synonym for 'x'
  1837. // chop off ind digits from the lower part of C1
  1838. // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
  1839. tmp64 = C1.w[0];
  1840. if (ind <= 19) {
  1841. C1.w[0] = C1.w[0] + midpoint64[ind - 1];
  1842. } else {
  1843. C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
  1844. C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
  1845. }
  1846. if (C1.w[0] < tmp64)
  1847. C1.w[1]++;
  1848. // calculate C* and f*
  1849. // C* is actually floor(C*) in this case
  1850. // C* and f* need shifting and masking, as shown by
  1851. // shiftright128[] and maskhigh128[]
  1852. // 1 <= x <= 34
  1853. // kx = 10^(-x) = ten2mk128[ind - 1]
  1854. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  1855. // the approximation of 10^(-x) was rounded up to 118 bits
  1856. __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
  1857. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
  1858. // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
  1859. // if (0 < f* < 10^(-x)) then the result is a midpoint
  1860. // if floor(C*) is even then C* = floor(C*) - logical right
  1861. // shift; C* has p decimal digits, correct by Prop. 1)
  1862. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  1863. // shift; C* has p decimal digits, correct by Pr. 1)
  1864. // else
  1865. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1866. // correct by Property 1)
  1867. // n = C* * 10^(e+x)
  1868. // shift right C* by Ex-128 = shiftright128[ind]
  1869. if (ind - 1 <= 2) { // 0 <= ind - 1 <= 2 => shift = 0
  1870. res.w[1] = P256.w[3];
  1871. res.w[0] = P256.w[2];
  1872. } else if (ind - 1 <= 21) { // 3 <= ind - 1 <= 21 => 3 <= shift <= 63
  1873. shift = shiftright128[ind - 1]; // 3 <= shift <= 63
  1874. res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
  1875. res.w[1] = (P256.w[3] >> shift);
  1876. } else { // 22 <= ind - 1 <= 33
  1877. shift = shiftright128[ind - 1]; // 2 <= shift <= 38
  1878. res.w[1] = 0;
  1879. res.w[0] = (P256.w[3] >> (shift - 64)); // 2 <= shift - 64 <= 38
  1880. }
  1881. // if the result was a midpoint, it was already rounded away from zero
  1882. res.w[1] |= x_sign | 0x3040000000000000ull;
  1883. BID_RETURN (res);
  1884. } else { // if ((q + exp) < 0) <=> q < -exp
  1885. // the result is +0 or -0
  1886. res.w[1] = x_sign | 0x3040000000000000ull;
  1887. res.w[0] = 0x0000000000000000ull;
  1888. BID_RETURN (res);
  1889. }
  1890. }