bid64_div.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795
  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. /*****************************************************************************
  19. * BID64 divide
  20. *****************************************************************************
  21. *
  22. * Algorithm description:
  23. *
  24. * if(coefficient_x<coefficient_y)
  25. * p = number_digits(coefficient_y) - number_digits(coefficient_x)
  26. * A = coefficient_x*10^p
  27. * B = coefficient_y
  28. * CA= A*10^(15+j), j=0 for A>=B, 1 otherwise
  29. * Q = 0
  30. * else
  31. * get Q=(int)(coefficient_x/coefficient_y)
  32. * (based on double precision divide)
  33. * check for exact divide case
  34. * Let R = coefficient_x - Q*coefficient_y
  35. * Let m=16-number_digits(Q)
  36. * CA=R*10^m, Q=Q*10^m
  37. * B = coefficient_y
  38. * endif
  39. * if (CA<2^64)
  40. * Q += CA/B (64-bit unsigned divide)
  41. * else
  42. * get final Q using double precision divide, followed by 3 integer
  43. * iterations
  44. * if exact result, eliminate trailing zeros
  45. * check for underflow
  46. * round coefficient to nearest
  47. *
  48. ****************************************************************************/
  49. #include "bid_internal.h"
  50. #include "bid_div_macros.h"
  51. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  52. #include <fenv.h>
  53. #define FE_ALL_FLAGS FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT
  54. #endif
  55. extern UINT32 convert_table[5][128][2];
  56. extern SINT8 factors[][2];
  57. extern UINT8 packed_10000_zeros[];
  58. #if DECIMAL_CALL_BY_REFERENCE
  59. void
  60. bid64_div (UINT64 * pres, UINT64 * px,
  61. UINT64 *
  62. py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  63. _EXC_INFO_PARAM) {
  64. UINT64 x, y;
  65. #else
  66. UINT64
  67. bid64_div (UINT64 x,
  68. UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
  69. _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  70. #endif
  71. UINT128 CA, CT;
  72. UINT64 sign_x, sign_y, coefficient_x, coefficient_y, A, B, QX, PD;
  73. UINT64 A2, Q, Q2, B2, B4, B5, R, T, DU, res;
  74. UINT64 valid_x, valid_y;
  75. SINT64 D;
  76. int_double t_scale, tempq, temp_b;
  77. int_float tempx, tempy;
  78. double da, db, dq, da_h, da_l;
  79. int exponent_x, exponent_y, bin_expon_cx;
  80. int diff_expon, ed1, ed2, bin_index;
  81. int rmode, amount;
  82. int nzeros, i, j, k, d5;
  83. UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
  84. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  85. fexcept_t binaryflags = 0;
  86. #endif
  87. #if DECIMAL_CALL_BY_REFERENCE
  88. #if !DECIMAL_GLOBAL_ROUNDING
  89. _IDEC_round rnd_mode = *prnd_mode;
  90. #endif
  91. x = *px;
  92. y = *py;
  93. #endif
  94. valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x);
  95. valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y);
  96. // unpack arguments, check for NaN or Infinity
  97. if (!valid_x) {
  98. // x is Inf. or NaN
  99. #ifdef SET_STATUS_FLAGS
  100. if ((y & SNAN_MASK64) == SNAN_MASK64) // y is sNaN
  101. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  102. #endif
  103. // test if x is NaN
  104. if ((x & NAN_MASK64) == NAN_MASK64) {
  105. #ifdef SET_STATUS_FLAGS
  106. if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN
  107. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  108. #endif
  109. BID_RETURN (coefficient_x & QUIET_MASK64);
  110. }
  111. // x is Infinity?
  112. if ((x & INFINITY_MASK64) == INFINITY_MASK64) {
  113. // check if y is Inf or NaN
  114. if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
  115. // y==Inf, return NaN
  116. if ((y & NAN_MASK64) == INFINITY_MASK64) { // Inf/Inf
  117. #ifdef SET_STATUS_FLAGS
  118. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  119. #endif
  120. BID_RETURN (NAN_MASK64);
  121. }
  122. } else {
  123. // otherwise return +/-Inf
  124. BID_RETURN (((x ^ y) & 0x8000000000000000ull) |
  125. INFINITY_MASK64);
  126. }
  127. }
  128. // x==0
  129. if (((y & INFINITY_MASK64) != INFINITY_MASK64)
  130. && !(coefficient_y)) {
  131. // y==0 , return NaN
  132. #ifdef SET_STATUS_FLAGS
  133. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  134. #endif
  135. BID_RETURN (NAN_MASK64);
  136. }
  137. if (((y & INFINITY_MASK64) != INFINITY_MASK64)) {
  138. if ((y & SPECIAL_ENCODING_MASK64) == SPECIAL_ENCODING_MASK64)
  139. exponent_y = ((UINT32) (y >> 51)) & 0x3ff;
  140. else
  141. exponent_y = ((UINT32) (y >> 53)) & 0x3ff;
  142. sign_y = y & 0x8000000000000000ull;
  143. exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
  144. if (exponent_x > DECIMAL_MAX_EXPON_64)
  145. exponent_x = DECIMAL_MAX_EXPON_64;
  146. else if (exponent_x < 0)
  147. exponent_x = 0;
  148. BID_RETURN ((sign_x ^ sign_y) | (((UINT64) exponent_x) << 53));
  149. }
  150. }
  151. if (!valid_y) {
  152. // y is Inf. or NaN
  153. // test if y is NaN
  154. if ((y & NAN_MASK64) == NAN_MASK64) {
  155. #ifdef SET_STATUS_FLAGS
  156. if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN
  157. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  158. #endif
  159. BID_RETURN (coefficient_y & QUIET_MASK64);
  160. }
  161. // y is Infinity?
  162. if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
  163. // return +/-0
  164. BID_RETURN (((x ^ y) & 0x8000000000000000ull));
  165. }
  166. // y is 0
  167. #ifdef SET_STATUS_FLAGS
  168. __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
  169. #endif
  170. BID_RETURN ((sign_x ^ sign_y) | INFINITY_MASK64);
  171. }
  172. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  173. (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
  174. #endif
  175. diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
  176. if (coefficient_x < coefficient_y) {
  177. // get number of decimal digits for c_x, c_y
  178. //--- get number of bits in the coefficients of x and y ---
  179. tempx.d = (float) coefficient_x;
  180. tempy.d = (float) coefficient_y;
  181. bin_index = (tempy.i - tempx.i) >> 23;
  182. A = coefficient_x * power10_index_binexp[bin_index];
  183. B = coefficient_y;
  184. temp_b.d = (double) B;
  185. // compare A, B
  186. DU = (A - B) >> 63;
  187. ed1 = 15 + (int) DU;
  188. ed2 = estimate_decimal_digits[bin_index] + ed1;
  189. T = power10_table_128[ed1].w[0];
  190. __mul_64x64_to_128 (CA, A, T);
  191. Q = 0;
  192. diff_expon = diff_expon - ed2;
  193. // adjust double precision db, to ensure that later A/B - (int)(da/db) > -1
  194. if (coefficient_y < 0x0020000000000000ull) {
  195. temp_b.i += 1;
  196. db = temp_b.d;
  197. } else
  198. db = (double) (B + 2 + (B & 1));
  199. } else {
  200. // get c_x/c_y
  201. // set last bit before conversion to DP
  202. A2 = coefficient_x | 1;
  203. da = (double) A2;
  204. db = (double) coefficient_y;
  205. tempq.d = da / db;
  206. Q = (UINT64) tempq.d;
  207. R = coefficient_x - coefficient_y * Q;
  208. // will use to get number of dec. digits of Q
  209. bin_expon_cx = (tempq.i >> 52) - 0x3ff;
  210. // R<0 ?
  211. D = ((SINT64) R) >> 63;
  212. Q += D;
  213. R += (coefficient_y & D);
  214. // exact result ?
  215. if (((SINT64) R) <= 0) {
  216. // can have R==-1 for coeff_y==1
  217. res =
  218. get_BID64 (sign_x ^ sign_y, diff_expon, (Q + R), rnd_mode,
  219. pfpsf);
  220. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  221. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  222. #endif
  223. BID_RETURN (res);
  224. }
  225. // get decimal digits of Q
  226. DU = power10_index_binexp[bin_expon_cx] - Q - 1;
  227. DU >>= 63;
  228. ed2 = 16 - estimate_decimal_digits[bin_expon_cx] - (int) DU;
  229. T = power10_table_128[ed2].w[0];
  230. __mul_64x64_to_128 (CA, R, T);
  231. B = coefficient_y;
  232. Q *= power10_table_128[ed2].w[0];
  233. diff_expon -= ed2;
  234. }
  235. if (!CA.w[1]) {
  236. Q2 = CA.w[0] / B;
  237. B2 = B + B;
  238. B4 = B2 + B2;
  239. R = CA.w[0] - Q2 * B;
  240. Q += Q2;
  241. } else {
  242. // 2^64
  243. t_scale.i = 0x43f0000000000000ull;
  244. // convert CA to DP
  245. da_h = CA.w[1];
  246. da_l = CA.w[0];
  247. da = da_h * t_scale.d + da_l;
  248. // quotient
  249. dq = da / db;
  250. Q2 = (UINT64) dq;
  251. // get w[0] remainder
  252. R = CA.w[0] - Q2 * B;
  253. // R<0 ?
  254. D = ((SINT64) R) >> 63;
  255. Q2 += D;
  256. R += (B & D);
  257. // now R<6*B
  258. // quick divide
  259. // 4*B
  260. B2 = B + B;
  261. B4 = B2 + B2;
  262. R = R - B4;
  263. // R<0 ?
  264. D = ((SINT64) R) >> 63;
  265. // restore R if negative
  266. R += (B4 & D);
  267. Q2 += ((~D) & 4);
  268. R = R - B2;
  269. // R<0 ?
  270. D = ((SINT64) R) >> 63;
  271. // restore R if negative
  272. R += (B2 & D);
  273. Q2 += ((~D) & 2);
  274. R = R - B;
  275. // R<0 ?
  276. D = ((SINT64) R) >> 63;
  277. // restore R if negative
  278. R += (B & D);
  279. Q2 += ((~D) & 1);
  280. Q += Q2;
  281. }
  282. #ifdef SET_STATUS_FLAGS
  283. if (R) {
  284. // set status flags
  285. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  286. }
  287. #ifndef LEAVE_TRAILING_ZEROS
  288. else
  289. #endif
  290. #else
  291. #ifndef LEAVE_TRAILING_ZEROS
  292. if (!R)
  293. #endif
  294. #endif
  295. #ifndef LEAVE_TRAILING_ZEROS
  296. {
  297. // eliminate trailing zeros
  298. // check whether CX, CY are short
  299. if ((coefficient_x <= 1024) && (coefficient_y <= 1024)) {
  300. i = (int) coefficient_y - 1;
  301. j = (int) coefficient_x - 1;
  302. // difference in powers of 2 factors for Y and X
  303. nzeros = ed2 - factors[i][0] + factors[j][0];
  304. // difference in powers of 5 factors
  305. d5 = ed2 - factors[i][1] + factors[j][1];
  306. if (d5 < nzeros)
  307. nzeros = d5;
  308. __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
  309. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  310. amount = short_recip_scale[nzeros];
  311. Q = CT.w[1] >> amount;
  312. diff_expon += nzeros;
  313. } else {
  314. tdigit[0] = Q & 0x3ffffff;
  315. tdigit[1] = 0;
  316. QX = Q >> 26;
  317. QX32 = QX;
  318. nzeros = 0;
  319. for (j = 0; QX32; j++, QX32 >>= 7) {
  320. k = (QX32 & 127);
  321. tdigit[0] += convert_table[j][k][0];
  322. tdigit[1] += convert_table[j][k][1];
  323. if (tdigit[0] >= 100000000) {
  324. tdigit[0] -= 100000000;
  325. tdigit[1]++;
  326. }
  327. }
  328. digit = tdigit[0];
  329. if (!digit && !tdigit[1])
  330. nzeros += 16;
  331. else {
  332. if (!digit) {
  333. nzeros += 8;
  334. digit = tdigit[1];
  335. }
  336. // decompose digit
  337. PD = (UINT64) digit *0x068DB8BBull;
  338. digit_h = (UINT32) (PD >> 40);
  339. digit_low = digit - digit_h * 10000;
  340. if (!digit_low)
  341. nzeros += 4;
  342. else
  343. digit_h = digit_low;
  344. if (!(digit_h & 1))
  345. nzeros +=
  346. 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
  347. (digit_h & 7));
  348. }
  349. if (nzeros) {
  350. __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
  351. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  352. amount = short_recip_scale[nzeros];
  353. Q = CT.w[1] >> amount;
  354. }
  355. diff_expon += nzeros;
  356. }
  357. if (diff_expon >= 0) {
  358. res =
  359. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q,
  360. rnd_mode, pfpsf);
  361. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  362. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  363. #endif
  364. BID_RETURN (res);
  365. }
  366. }
  367. #endif
  368. if (diff_expon >= 0) {
  369. #ifdef IEEE_ROUND_NEAREST
  370. // round to nearest code
  371. // R*10
  372. R += R;
  373. R = (R << 2) + R;
  374. B5 = B4 + B;
  375. // compare 10*R to 5*B
  376. R = B5 - R;
  377. // correction for (R==0 && (Q&1))
  378. R -= (Q & 1);
  379. // R<0 ?
  380. D = ((UINT64) R) >> 63;
  381. Q += D;
  382. #else
  383. #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
  384. // round to nearest code
  385. // R*10
  386. R += R;
  387. R = (R << 2) + R;
  388. B5 = B4 + B;
  389. // compare 10*R to 5*B
  390. R = B5 - R;
  391. // correction for (R==0 && (Q&1))
  392. R -= (Q & 1);
  393. // R<0 ?
  394. D = ((UINT64) R) >> 63;
  395. Q += D;
  396. #else
  397. rmode = rnd_mode;
  398. if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
  399. rmode = 3 - rmode;
  400. switch (rmode) {
  401. case 0: // round to nearest code
  402. case ROUNDING_TIES_AWAY:
  403. // R*10
  404. R += R;
  405. R = (R << 2) + R;
  406. B5 = B4 + B;
  407. // compare 10*R to 5*B
  408. R = B5 - R;
  409. // correction for (R==0 && (Q&1))
  410. R -= ((Q | (rmode >> 2)) & 1);
  411. // R<0 ?
  412. D = ((UINT64) R) >> 63;
  413. Q += D;
  414. break;
  415. case ROUNDING_DOWN:
  416. case ROUNDING_TO_ZERO:
  417. break;
  418. default: // rounding up
  419. Q++;
  420. break;
  421. }
  422. #endif
  423. #endif
  424. res =
  425. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q, rnd_mode,
  426. pfpsf);
  427. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  428. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  429. #endif
  430. BID_RETURN (res);
  431. } else {
  432. // UF occurs
  433. #ifdef SET_STATUS_FLAGS
  434. if ((diff_expon + 16 < 0)) {
  435. // set status flags
  436. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  437. }
  438. #endif
  439. rmode = rnd_mode;
  440. res =
  441. get_BID64_UF (sign_x ^ sign_y, diff_expon, Q, R, rmode, pfpsf);
  442. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  443. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  444. #endif
  445. BID_RETURN (res);
  446. }
  447. }
  448. TYPE0_FUNCTION_ARGTYPE1_ARG128 (UINT64, bid64dq_div, UINT64, x, y)
  449. UINT256 CA4 =
  450. { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
  451. UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
  452. UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
  453. int_float fx, fy, f64;
  454. UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
  455. int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
  456. digits_q, amount;
  457. int nzeros, i, j, k, d5, done = 0;
  458. unsigned rmode;
  459. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  460. fexcept_t binaryflags = 0;
  461. #endif
  462. valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
  463. // unpack arguments, check for NaN or Infinity
  464. CX.w[1] = 0;
  465. if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) {
  466. #ifdef SET_STATUS_FLAGS
  467. if (((y.w[1] & SNAN_MASK64) == SNAN_MASK64) || // y is sNaN
  468. ((x & SNAN_MASK64) == SNAN_MASK64))
  469. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  470. #endif
  471. // test if x is NaN
  472. if (((x) & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
  473. res = CX.w[0];
  474. BID_RETURN (res & QUIET_MASK64);
  475. }
  476. // x is Infinity?
  477. if (((x) & 0x7800000000000000ull) == 0x7800000000000000ull) {
  478. // check if y is Inf.
  479. if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
  480. // return NaN
  481. {
  482. #ifdef SET_STATUS_FLAGS
  483. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  484. #endif
  485. res = 0x7c00000000000000ull;
  486. BID_RETURN (res);
  487. }
  488. if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
  489. // otherwise return +/-Inf
  490. res =
  491. (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
  492. BID_RETURN (res);
  493. }
  494. }
  495. // x is 0
  496. if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) {
  497. if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
  498. #ifdef SET_STATUS_FLAGS
  499. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  500. #endif
  501. // x=y=0, return NaN
  502. res = 0x7c00000000000000ull;
  503. BID_RETURN (res);
  504. }
  505. // return 0
  506. res = ((x) ^ y.w[1]) & 0x8000000000000000ull;
  507. exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS_128;
  508. if (exponent_x > DECIMAL_MAX_EXPON_64)
  509. exponent_x = DECIMAL_MAX_EXPON_64;
  510. else if (exponent_x < 0)
  511. exponent_x = 0;
  512. res |= (((UINT64) exponent_x) << 53);
  513. BID_RETURN (res);
  514. }
  515. }
  516. exponent_x += (DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS);
  517. if (!valid_y) {
  518. // y is Inf. or NaN
  519. // test if y is NaN
  520. if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
  521. #ifdef SET_STATUS_FLAGS
  522. if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN
  523. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  524. #endif
  525. Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
  526. Tmp.w[0] = CY.w[0];
  527. TP128 = reciprocals10_128[18];
  528. __mul_128x128_high (Qh, Tmp, TP128);
  529. amount = recip_scale[18];
  530. __shr_128 (Tmp, Qh, amount);
  531. res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
  532. BID_RETURN (res);
  533. }
  534. // y is Infinity?
  535. if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
  536. // return +/-0
  537. res = sign_x ^ sign_y;
  538. BID_RETURN (res);
  539. }
  540. // y is 0, return +/-Inf
  541. res =
  542. (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
  543. #ifdef SET_STATUS_FLAGS
  544. __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
  545. #endif
  546. BID_RETURN (res);
  547. }
  548. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  549. (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
  550. #endif
  551. diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
  552. if (__unsigned_compare_gt_128 (CY, CX)) {
  553. // CX < CY
  554. // 2^64
  555. f64.i = 0x5f800000;
  556. // fx ~ CX, fy ~ CY
  557. fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
  558. fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
  559. // expon_cy - expon_cx
  560. bin_index = (fy.i - fx.i) >> 23;
  561. if (CX.w[1]) {
  562. T = power10_index_binexp_128[bin_index].w[0];
  563. __mul_64x128_short (CA, T, CX);
  564. } else {
  565. T128 = power10_index_binexp_128[bin_index];
  566. __mul_64x128_short (CA, CX.w[0], T128);
  567. }
  568. ed2 = 15;
  569. if (__unsigned_compare_gt_128 (CY, CA))
  570. ed2++;
  571. T128 = power10_table_128[ed2];
  572. __mul_128x128_to_256 (CA4, CA, T128);
  573. ed2 += estimate_decimal_digits[bin_index];
  574. CQ.w[0] = CQ.w[1] = 0;
  575. diff_expon = diff_expon - ed2;
  576. } else {
  577. // get CQ = CX/CY
  578. __div_128_by_128 (&CQ, &CR, CX, CY);
  579. // get number of decimal digits in CQ
  580. // 2^64
  581. f64.i = 0x5f800000;
  582. fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
  583. // binary expon. of CQ
  584. bin_expon = (fx.i - 0x3f800000) >> 23;
  585. digits_q = estimate_decimal_digits[bin_expon];
  586. TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
  587. TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
  588. if (__unsigned_compare_ge_128 (CQ, TP128))
  589. digits_q++;
  590. if (digits_q <= 16) {
  591. if (!CR.w[1] && !CR.w[0]) {
  592. res = get_BID64 (sign_x ^ sign_y, diff_expon,
  593. CQ.w[0], rnd_mode, pfpsf);
  594. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  595. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  596. #endif
  597. BID_RETURN (res);
  598. }
  599. ed2 = 16 - digits_q;
  600. T128.w[0] = power10_table_128[ed2].w[0];
  601. __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
  602. diff_expon = diff_expon - ed2;
  603. CQ.w[0] *= T128.w[0];
  604. } else {
  605. ed2 = digits_q - 16;
  606. diff_expon += ed2;
  607. T128 = reciprocals10_128[ed2];
  608. __mul_128x128_to_256 (P256, CQ, T128);
  609. amount = recip_scale[ed2];
  610. CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
  611. CQ.w[1] = 0;
  612. __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
  613. __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
  614. QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
  615. CA4.w[1] = CX.w[1] - QB256.w[1];
  616. CA4.w[0] = CX.w[0] - QB256.w[0];
  617. if (CX.w[0] < QB256.w[0])
  618. CA4.w[1]--;
  619. if (CR.w[0] || CR.w[1])
  620. CA4.w[0] |= 1;
  621. done = 1;
  622. }
  623. }
  624. if (!done) {
  625. __div_256_by_128 (&CQ, &CA4, CY);
  626. }
  627. #ifdef SET_STATUS_FLAGS
  628. if (CA4.w[0] || CA4.w[1]) {
  629. // set status flags
  630. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  631. }
  632. #ifndef LEAVE_TRAILING_ZEROS
  633. else
  634. #endif
  635. #else
  636. #ifndef LEAVE_TRAILING_ZEROS
  637. if (!CA4.w[0] && !CA4.w[1])
  638. #endif
  639. #endif
  640. #ifndef LEAVE_TRAILING_ZEROS
  641. // check whether result is exact
  642. {
  643. // check whether CX, CY are short
  644. if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
  645. i = (int) CY.w[0] - 1;
  646. j = (int) CX.w[0] - 1;
  647. // difference in powers of 2 factors for Y and X
  648. nzeros = ed2 - factors[i][0] + factors[j][0];
  649. // difference in powers of 5 factors
  650. d5 = ed2 - factors[i][1] + factors[j][1];
  651. if (d5 < nzeros)
  652. nzeros = d5;
  653. // get P*(2^M[extra_digits])/10^extra_digits
  654. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  655. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  656. amount = recip_scale[nzeros];
  657. __shr_128_long (CQ, Qh, amount);
  658. diff_expon += nzeros;
  659. } else {
  660. // decompose Q as Qh*10^17 + Ql
  661. Q_low = CQ.w[0];
  662. {
  663. tdigit[0] = Q_low & 0x3ffffff;
  664. tdigit[1] = 0;
  665. QX = Q_low >> 26;
  666. QX32 = QX;
  667. nzeros = 0;
  668. for (j = 0; QX32; j++, QX32 >>= 7) {
  669. k = (QX32 & 127);
  670. tdigit[0] += convert_table[j][k][0];
  671. tdigit[1] += convert_table[j][k][1];
  672. if (tdigit[0] >= 100000000) {
  673. tdigit[0] -= 100000000;
  674. tdigit[1]++;
  675. }
  676. }
  677. if (tdigit[1] >= 100000000) {
  678. tdigit[1] -= 100000000;
  679. if (tdigit[1] >= 100000000)
  680. tdigit[1] -= 100000000;
  681. }
  682. digit = tdigit[0];
  683. if (!digit && !tdigit[1])
  684. nzeros += 16;
  685. else {
  686. if (!digit) {
  687. nzeros += 8;
  688. digit = tdigit[1];
  689. }
  690. // decompose digit
  691. PD = (UINT64) digit *0x068DB8BBull;
  692. digit_h = (UINT32) (PD >> 40);
  693. digit_low = digit - digit_h * 10000;
  694. if (!digit_low)
  695. nzeros += 4;
  696. else
  697. digit_h = digit_low;
  698. if (!(digit_h & 1))
  699. nzeros +=
  700. 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
  701. (digit_h & 7));
  702. }
  703. if (nzeros) {
  704. // get P*(2^M[extra_digits])/10^extra_digits
  705. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  706. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  707. amount = recip_scale[nzeros];
  708. __shr_128 (CQ, Qh, amount);
  709. }
  710. diff_expon += nzeros;
  711. }
  712. }
  713. if(diff_expon>=0){
  714. res =
  715. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
  716. rnd_mode, pfpsf);
  717. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  718. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  719. #endif
  720. BID_RETURN (res);
  721. }
  722. }
  723. #endif
  724. if (diff_expon >= 0) {
  725. #ifdef IEEE_ROUND_NEAREST
  726. // rounding
  727. // 2*CA4 - CY
  728. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  729. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  730. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  731. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  732. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  733. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  734. CQ.w[0] += carry64;
  735. #else
  736. #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
  737. // rounding
  738. // 2*CA4 - CY
  739. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  740. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  741. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  742. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  743. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  744. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  745. CQ.w[0] += carry64;
  746. if (CQ.w[0] < carry64)
  747. CQ.w[1]++;
  748. #else
  749. rmode = rnd_mode;
  750. if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
  751. rmode = 3 - rmode;
  752. switch (rmode) {
  753. case ROUNDING_TO_NEAREST: // round to nearest code
  754. // rounding
  755. // 2*CA4 - CY
  756. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  757. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  758. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  759. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  760. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  761. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  762. CQ.w[0] += carry64;
  763. if (CQ.w[0] < carry64)
  764. CQ.w[1]++;
  765. break;
  766. case ROUNDING_TIES_AWAY:
  767. // rounding
  768. // 2*CA4 - CY
  769. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  770. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  771. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  772. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  773. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  774. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  775. CQ.w[0] += carry64;
  776. if (CQ.w[0] < carry64)
  777. CQ.w[1]++;
  778. break;
  779. case ROUNDING_DOWN:
  780. case ROUNDING_TO_ZERO:
  781. break;
  782. default: // rounding up
  783. CQ.w[0]++;
  784. if (!CQ.w[0])
  785. CQ.w[1]++;
  786. break;
  787. }
  788. #endif
  789. #endif
  790. res =
  791. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
  792. pfpsf);
  793. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  794. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  795. #endif
  796. BID_RETURN (res);
  797. } else {
  798. // UF occurs
  799. #ifdef SET_STATUS_FLAGS
  800. if ((diff_expon + 16 < 0)) {
  801. // set status flags
  802. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  803. }
  804. #endif
  805. rmode = rnd_mode;
  806. res =
  807. get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
  808. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  809. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  810. #endif
  811. BID_RETURN (res);
  812. }
  813. }
  814. //#define LEAVE_TRAILING_ZEROS
  815. TYPE0_FUNCTION_ARG128_ARGTYPE2 (UINT64, bid64qd_div, x, UINT64, y)
  816. UINT256 CA4 =
  817. { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
  818. UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
  819. UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, PD, res, valid_y;
  820. int_float fx, fy, f64;
  821. UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
  822. int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
  823. digits_q, amount;
  824. int nzeros, i, j, k, d5, done = 0;
  825. unsigned rmode;
  826. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  827. fexcept_t binaryflags = 0;
  828. #endif
  829. valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], (y));
  830. // unpack arguments, check for NaN or Infinity
  831. if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
  832. // test if x is NaN
  833. if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
  834. #ifdef SET_STATUS_FLAGS
  835. if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN
  836. (y & 0x7e00000000000000ull) == 0x7e00000000000000ull)
  837. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  838. #endif
  839. Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
  840. Tmp.w[0] = CX.w[0];
  841. TP128 = reciprocals10_128[18];
  842. __mul_128x128_high (Qh, Tmp, TP128);
  843. amount = recip_scale[18];
  844. __shr_128 (Tmp, Qh, amount);
  845. res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
  846. BID_RETURN (res);
  847. }
  848. // x is Infinity?
  849. if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
  850. // check if y is Inf.
  851. if (((y & 0x7c00000000000000ull) == 0x7800000000000000ull))
  852. // return NaN
  853. {
  854. #ifdef SET_STATUS_FLAGS
  855. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  856. #endif
  857. res = 0x7c00000000000000ull;
  858. BID_RETURN (res);
  859. }
  860. if (((y & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
  861. // otherwise return +/-Inf
  862. res =
  863. ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
  864. BID_RETURN (res);
  865. }
  866. }
  867. // x is 0
  868. if (((y & INFINITY_MASK64) != INFINITY_MASK64) &&
  869. !(CY.w[0])) {
  870. #ifdef SET_STATUS_FLAGS
  871. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  872. #endif
  873. // x=y=0, return NaN
  874. res = 0x7c00000000000000ull;
  875. BID_RETURN (res);
  876. }
  877. // return 0
  878. if (((y & 0x7800000000000000ull) != 0x7800000000000000ull)) {
  879. if (!CY.w[0]) {
  880. #ifdef SET_STATUS_FLAGS
  881. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  882. #endif
  883. res = 0x7c00000000000000ull;
  884. BID_RETURN (res);
  885. }
  886. exponent_x =
  887. exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
  888. (DECIMAL_EXPONENT_BIAS << 1);
  889. if (exponent_x > DECIMAL_MAX_EXPON_64)
  890. exponent_x = DECIMAL_MAX_EXPON_64;
  891. else if (exponent_x < 0)
  892. exponent_x = 0;
  893. res = (sign_x ^ sign_y) | (((UINT64) exponent_x) << 53);
  894. BID_RETURN (res);
  895. }
  896. }
  897. CY.w[1] = 0;
  898. if (!valid_y) {
  899. // y is Inf. or NaN
  900. // test if y is NaN
  901. if ((y & NAN_MASK64) == NAN_MASK64) {
  902. #ifdef SET_STATUS_FLAGS
  903. if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN
  904. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  905. #endif
  906. BID_RETURN (CY.w[0] & QUIET_MASK64);
  907. }
  908. // y is Infinity?
  909. if (((y) & 0x7800000000000000ull) == 0x7800000000000000ull) {
  910. // return +/-0
  911. res = sign_x ^ sign_y;
  912. BID_RETURN (res);
  913. }
  914. // y is 0, return +/-Inf
  915. res =
  916. ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
  917. #ifdef SET_STATUS_FLAGS
  918. __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
  919. #endif
  920. BID_RETURN (res);
  921. }
  922. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  923. (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
  924. #endif
  925. diff_expon =
  926. exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
  927. (DECIMAL_EXPONENT_BIAS << 1);
  928. if (__unsigned_compare_gt_128 (CY, CX)) {
  929. // CX < CY
  930. // 2^64
  931. f64.i = 0x5f800000;
  932. // fx ~ CX, fy ~ CY
  933. fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
  934. fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
  935. // expon_cy - expon_cx
  936. bin_index = (fy.i - fx.i) >> 23;
  937. if (CX.w[1]) {
  938. T = power10_index_binexp_128[bin_index].w[0];
  939. __mul_64x128_short (CA, T, CX);
  940. } else {
  941. T128 = power10_index_binexp_128[bin_index];
  942. __mul_64x128_short (CA, CX.w[0], T128);
  943. }
  944. ed2 = 15;
  945. if (__unsigned_compare_gt_128 (CY, CA))
  946. ed2++;
  947. T128 = power10_table_128[ed2];
  948. __mul_128x128_to_256 (CA4, CA, T128);
  949. ed2 += estimate_decimal_digits[bin_index];
  950. CQ.w[0] = CQ.w[1] = 0;
  951. diff_expon = diff_expon - ed2;
  952. } else {
  953. // get CQ = CX/CY
  954. __div_128_by_128 (&CQ, &CR, CX, CY);
  955. // get number of decimal digits in CQ
  956. // 2^64
  957. f64.i = 0x5f800000;
  958. fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
  959. // binary expon. of CQ
  960. bin_expon = (fx.i - 0x3f800000) >> 23;
  961. digits_q = estimate_decimal_digits[bin_expon];
  962. TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
  963. TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
  964. if (__unsigned_compare_ge_128 (CQ, TP128))
  965. digits_q++;
  966. if (digits_q <= 16) {
  967. if (!CR.w[1] && !CR.w[0]) {
  968. res = get_BID64 (sign_x ^ sign_y, diff_expon,
  969. CQ.w[0], rnd_mode, pfpsf);
  970. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  971. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  972. #endif
  973. BID_RETURN (res);
  974. }
  975. ed2 = 16 - digits_q;
  976. T128.w[0] = power10_table_128[ed2].w[0];
  977. __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
  978. diff_expon = diff_expon - ed2;
  979. CQ.w[0] *= T128.w[0];
  980. } else {
  981. ed2 = digits_q - 16;
  982. diff_expon += ed2;
  983. T128 = reciprocals10_128[ed2];
  984. __mul_128x128_to_256 (P256, CQ, T128);
  985. amount = recip_scale[ed2];
  986. CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
  987. CQ.w[1] = 0;
  988. __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
  989. __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
  990. QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
  991. CA4.w[1] = CX.w[1] - QB256.w[1];
  992. CA4.w[0] = CX.w[0] - QB256.w[0];
  993. if (CX.w[0] < QB256.w[0])
  994. CA4.w[1]--;
  995. if (CR.w[0] || CR.w[1])
  996. CA4.w[0] |= 1;
  997. done = 1;
  998. if(CA4.w[1]|CA4.w[0]) {
  999. __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
  1000. }
  1001. }
  1002. }
  1003. if (!done) {
  1004. __div_256_by_128 (&CQ, &CA4, CY);
  1005. }
  1006. #ifdef SET_STATUS_FLAGS
  1007. if (CA4.w[0] || CA4.w[1]) {
  1008. // set status flags
  1009. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  1010. }
  1011. #ifndef LEAVE_TRAILING_ZEROS
  1012. else
  1013. #endif
  1014. #else
  1015. #ifndef LEAVE_TRAILING_ZEROS
  1016. if (!CA4.w[0] && !CA4.w[1])
  1017. #endif
  1018. #endif
  1019. #ifndef LEAVE_TRAILING_ZEROS
  1020. // check whether result is exact
  1021. {
  1022. if(!done) {
  1023. // check whether CX, CY are short
  1024. if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
  1025. i = (int) CY.w[0] - 1;
  1026. j = (int) CX.w[0] - 1;
  1027. // difference in powers of 2 factors for Y and X
  1028. nzeros = ed2 - factors[i][0] + factors[j][0];
  1029. // difference in powers of 5 factors
  1030. d5 = ed2 - factors[i][1] + factors[j][1];
  1031. if (d5 < nzeros)
  1032. nzeros = d5;
  1033. // get P*(2^M[extra_digits])/10^extra_digits
  1034. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  1035. //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
  1036. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  1037. amount = recip_scale[nzeros];
  1038. __shr_128_long (CQ, Qh, amount);
  1039. diff_expon += nzeros;
  1040. } else {
  1041. // decompose Q as Qh*10^17 + Ql
  1042. //T128 = reciprocals10_128[17];
  1043. Q_low = CQ.w[0];
  1044. {
  1045. tdigit[0] = Q_low & 0x3ffffff;
  1046. tdigit[1] = 0;
  1047. QX = Q_low >> 26;
  1048. QX32 = QX;
  1049. nzeros = 0;
  1050. for (j = 0; QX32; j++, QX32 >>= 7) {
  1051. k = (QX32 & 127);
  1052. tdigit[0] += convert_table[j][k][0];
  1053. tdigit[1] += convert_table[j][k][1];
  1054. if (tdigit[0] >= 100000000) {
  1055. tdigit[0] -= 100000000;
  1056. tdigit[1]++;
  1057. }
  1058. }
  1059. if (tdigit[1] >= 100000000) {
  1060. tdigit[1] -= 100000000;
  1061. if (tdigit[1] >= 100000000)
  1062. tdigit[1] -= 100000000;
  1063. }
  1064. digit = tdigit[0];
  1065. if (!digit && !tdigit[1])
  1066. nzeros += 16;
  1067. else {
  1068. if (!digit) {
  1069. nzeros += 8;
  1070. digit = tdigit[1];
  1071. }
  1072. // decompose digit
  1073. PD = (UINT64) digit *0x068DB8BBull;
  1074. digit_h = (UINT32) (PD >> 40);
  1075. digit_low = digit - digit_h * 10000;
  1076. if (!digit_low)
  1077. nzeros += 4;
  1078. else
  1079. digit_h = digit_low;
  1080. if (!(digit_h & 1))
  1081. nzeros +=
  1082. 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
  1083. (digit_h & 7));
  1084. }
  1085. if (nzeros) {
  1086. // get P*(2^M[extra_digits])/10^extra_digits
  1087. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  1088. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  1089. amount = recip_scale[nzeros];
  1090. __shr_128 (CQ, Qh, amount);
  1091. }
  1092. diff_expon += nzeros;
  1093. }
  1094. }
  1095. }
  1096. if(diff_expon>=0){
  1097. res =
  1098. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
  1099. rnd_mode, pfpsf);
  1100. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1101. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1102. #endif
  1103. BID_RETURN (res);
  1104. }
  1105. }
  1106. #endif
  1107. if (diff_expon >= 0) {
  1108. #ifdef IEEE_ROUND_NEAREST
  1109. // rounding
  1110. // 2*CA4 - CY
  1111. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1112. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1113. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1114. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1115. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  1116. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  1117. CQ.w[0] += carry64;
  1118. //if(CQ.w[0]<carry64)
  1119. //CQ.w[1] ++;
  1120. #else
  1121. #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
  1122. // rounding
  1123. // 2*CA4 - CY
  1124. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1125. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1126. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1127. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1128. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  1129. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  1130. CQ.w[0] += carry64;
  1131. if (CQ.w[0] < carry64)
  1132. CQ.w[1]++;
  1133. #else
  1134. rmode = rnd_mode;
  1135. if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
  1136. rmode = 3 - rmode;
  1137. switch (rmode) {
  1138. case ROUNDING_TO_NEAREST: // round to nearest code
  1139. // rounding
  1140. // 2*CA4 - CY
  1141. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1142. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1143. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1144. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1145. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  1146. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  1147. CQ.w[0] += carry64;
  1148. if (CQ.w[0] < carry64)
  1149. CQ.w[1]++;
  1150. break;
  1151. case ROUNDING_TIES_AWAY:
  1152. // rounding
  1153. // 2*CA4 - CY
  1154. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1155. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1156. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1157. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1158. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  1159. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  1160. CQ.w[0] += carry64;
  1161. if (CQ.w[0] < carry64)
  1162. CQ.w[1]++;
  1163. break;
  1164. case ROUNDING_DOWN:
  1165. case ROUNDING_TO_ZERO:
  1166. break;
  1167. default: // rounding up
  1168. CQ.w[0]++;
  1169. if (!CQ.w[0])
  1170. CQ.w[1]++;
  1171. break;
  1172. }
  1173. #endif
  1174. #endif
  1175. res =
  1176. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
  1177. pfpsf);
  1178. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1179. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1180. #endif
  1181. BID_RETURN (res);
  1182. } else {
  1183. // UF occurs
  1184. #ifdef SET_STATUS_FLAGS
  1185. if ((diff_expon + 16 < 0)) {
  1186. // set status flags
  1187. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  1188. }
  1189. #endif
  1190. rmode = rnd_mode;
  1191. res =
  1192. get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
  1193. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1194. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1195. #endif
  1196. BID_RETURN (res);
  1197. }
  1198. }
  1199. //#define LEAVE_TRAILING_ZEROS
  1200. extern UINT32 convert_table[5][128][2];
  1201. extern SINT8 factors[][2];
  1202. extern UINT8 packed_10000_zeros[];
  1203. //UINT64* bid64_div128x128(UINT64 res, UINT128 *px, UINT128 *py, unsigned rnd_mode, unsigned *pfpsf)
  1204. TYPE0_FUNCTION_ARG128_ARG128 (UINT64, bid64qq_div, x, y)
  1205. UINT256 CA4 =
  1206. { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
  1207. UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
  1208. UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
  1209. int_float fx, fy, f64;
  1210. UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
  1211. int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
  1212. digits_q, amount;
  1213. int nzeros, i, j, k, d5, done = 0;
  1214. unsigned rmode;
  1215. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1216. fexcept_t binaryflags = 0;
  1217. #endif
  1218. valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
  1219. // unpack arguments, check for NaN or Infinity
  1220. if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
  1221. // test if x is NaN
  1222. if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
  1223. #ifdef SET_STATUS_FLAGS
  1224. if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN
  1225. (y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)
  1226. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  1227. #endif
  1228. Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
  1229. Tmp.w[0] = CX.w[0];
  1230. TP128 = reciprocals10_128[18];
  1231. __mul_128x128_high (Qh, Tmp, TP128);
  1232. amount = recip_scale[18];
  1233. __shr_128 (Tmp, Qh, amount);
  1234. res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
  1235. BID_RETURN (res);
  1236. }
  1237. // x is Infinity?
  1238. if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
  1239. // check if y is Inf.
  1240. if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
  1241. // return NaN
  1242. {
  1243. #ifdef SET_STATUS_FLAGS
  1244. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  1245. #endif
  1246. res = 0x7c00000000000000ull;
  1247. BID_RETURN (res);
  1248. }
  1249. if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
  1250. // otherwise return +/-Inf
  1251. res =
  1252. ((x.w[1] ^ y.
  1253. w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
  1254. BID_RETURN (res);
  1255. }
  1256. }
  1257. // x is 0
  1258. if (((y.w[1] & 0x7800000000000000ull) != 0x7800000000000000ull)) {
  1259. if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
  1260. #ifdef SET_STATUS_FLAGS
  1261. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  1262. #endif
  1263. // x=y=0, return NaN
  1264. res = 0x7c00000000000000ull;
  1265. BID_RETURN (res);
  1266. }
  1267. // return 0
  1268. res = (x.w[1] ^ y.w[1]) & 0x8000000000000000ull;
  1269. exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
  1270. if (exponent_x > DECIMAL_MAX_EXPON_64)
  1271. exponent_x = DECIMAL_MAX_EXPON_64;
  1272. else if (exponent_x < 0)
  1273. exponent_x = 0;
  1274. res |= (((UINT64) exponent_x) << 53);
  1275. BID_RETURN (res);
  1276. }
  1277. }
  1278. if (!valid_y) {
  1279. // y is Inf. or NaN
  1280. // test if y is NaN
  1281. if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
  1282. #ifdef SET_STATUS_FLAGS
  1283. if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN
  1284. __set_status_flags (pfpsf, INVALID_EXCEPTION);
  1285. #endif
  1286. Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
  1287. Tmp.w[0] = CY.w[0];
  1288. TP128 = reciprocals10_128[18];
  1289. __mul_128x128_high (Qh, Tmp, TP128);
  1290. amount = recip_scale[18];
  1291. __shr_128 (Tmp, Qh, amount);
  1292. res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
  1293. BID_RETURN (res);
  1294. }
  1295. // y is Infinity?
  1296. if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
  1297. // return +/-0
  1298. res = sign_x ^ sign_y;
  1299. BID_RETURN (res);
  1300. }
  1301. // y is 0, return +/-Inf
  1302. res =
  1303. ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
  1304. #ifdef SET_STATUS_FLAGS
  1305. __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
  1306. #endif
  1307. BID_RETURN (res);
  1308. }
  1309. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1310. (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1311. #endif
  1312. diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
  1313. if (__unsigned_compare_gt_128 (CY, CX)) {
  1314. // CX < CY
  1315. // 2^64
  1316. f64.i = 0x5f800000;
  1317. // fx ~ CX, fy ~ CY
  1318. fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
  1319. fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
  1320. // expon_cy - expon_cx
  1321. bin_index = (fy.i - fx.i) >> 23;
  1322. if (CX.w[1]) {
  1323. T = power10_index_binexp_128[bin_index].w[0];
  1324. __mul_64x128_short (CA, T, CX);
  1325. } else {
  1326. T128 = power10_index_binexp_128[bin_index];
  1327. __mul_64x128_short (CA, CX.w[0], T128);
  1328. }
  1329. ed2 = 15;
  1330. if (__unsigned_compare_gt_128 (CY, CA))
  1331. ed2++;
  1332. T128 = power10_table_128[ed2];
  1333. __mul_128x128_to_256 (CA4, CA, T128);
  1334. ed2 += estimate_decimal_digits[bin_index];
  1335. CQ.w[0] = CQ.w[1] = 0;
  1336. diff_expon = diff_expon - ed2;
  1337. } else {
  1338. // get CQ = CX/CY
  1339. __div_128_by_128 (&CQ, &CR, CX, CY);
  1340. // get number of decimal digits in CQ
  1341. // 2^64
  1342. f64.i = 0x5f800000;
  1343. fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
  1344. // binary expon. of CQ
  1345. bin_expon = (fx.i - 0x3f800000) >> 23;
  1346. digits_q = estimate_decimal_digits[bin_expon];
  1347. TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
  1348. TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
  1349. if (__unsigned_compare_ge_128 (CQ, TP128))
  1350. digits_q++;
  1351. if (digits_q <= 16) {
  1352. if (!CR.w[1] && !CR.w[0]) {
  1353. res = get_BID64 (sign_x ^ sign_y, diff_expon,
  1354. CQ.w[0], rnd_mode, pfpsf);
  1355. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1356. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1357. #endif
  1358. BID_RETURN (res);
  1359. }
  1360. ed2 = 16 - digits_q;
  1361. T128.w[0] = power10_table_128[ed2].w[0];
  1362. __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
  1363. diff_expon = diff_expon - ed2;
  1364. CQ.w[0] *= T128.w[0];
  1365. } else {
  1366. ed2 = digits_q - 16;
  1367. diff_expon += ed2;
  1368. T128 = reciprocals10_128[ed2];
  1369. __mul_128x128_to_256 (P256, CQ, T128);
  1370. amount = recip_scale[ed2];
  1371. CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
  1372. CQ.w[1] = 0;
  1373. __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
  1374. __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
  1375. QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
  1376. CA4.w[1] = CX.w[1] - QB256.w[1];
  1377. CA4.w[0] = CX.w[0] - QB256.w[0];
  1378. if (CX.w[0] < QB256.w[0])
  1379. CA4.w[1]--;
  1380. if (CR.w[0] || CR.w[1])
  1381. CA4.w[0] |= 1;
  1382. done = 1;
  1383. if(CA4.w[1]|CA4.w[0]) {
  1384. __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
  1385. }
  1386. }
  1387. }
  1388. if (!done) {
  1389. __div_256_by_128 (&CQ, &CA4, CY);
  1390. }
  1391. #ifdef SET_STATUS_FLAGS
  1392. if (CA4.w[0] || CA4.w[1]) {
  1393. // set status flags
  1394. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  1395. }
  1396. #ifndef LEAVE_TRAILING_ZEROS
  1397. else
  1398. #endif
  1399. #else
  1400. #ifndef LEAVE_TRAILING_ZEROS
  1401. if (!CA4.w[0] && !CA4.w[1])
  1402. #endif
  1403. #endif
  1404. #ifndef LEAVE_TRAILING_ZEROS
  1405. // check whether result is exact
  1406. {
  1407. if(!done) {
  1408. // check whether CX, CY are short
  1409. if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
  1410. i = (int) CY.w[0] - 1;
  1411. j = (int) CX.w[0] - 1;
  1412. // difference in powers of 2 factors for Y and X
  1413. nzeros = ed2 - factors[i][0] + factors[j][0];
  1414. // difference in powers of 5 factors
  1415. d5 = ed2 - factors[i][1] + factors[j][1];
  1416. if (d5 < nzeros)
  1417. nzeros = d5;
  1418. // get P*(2^M[extra_digits])/10^extra_digits
  1419. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  1420. //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
  1421. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  1422. amount = recip_scale[nzeros];
  1423. __shr_128_long (CQ, Qh, amount);
  1424. diff_expon += nzeros;
  1425. } else {
  1426. // decompose Q as Qh*10^17 + Ql
  1427. //T128 = reciprocals10_128[17];
  1428. Q_low = CQ.w[0];
  1429. {
  1430. tdigit[0] = Q_low & 0x3ffffff;
  1431. tdigit[1] = 0;
  1432. QX = Q_low >> 26;
  1433. QX32 = QX;
  1434. nzeros = 0;
  1435. for (j = 0; QX32; j++, QX32 >>= 7) {
  1436. k = (QX32 & 127);
  1437. tdigit[0] += convert_table[j][k][0];
  1438. tdigit[1] += convert_table[j][k][1];
  1439. if (tdigit[0] >= 100000000) {
  1440. tdigit[0] -= 100000000;
  1441. tdigit[1]++;
  1442. }
  1443. }
  1444. if (tdigit[1] >= 100000000) {
  1445. tdigit[1] -= 100000000;
  1446. if (tdigit[1] >= 100000000)
  1447. tdigit[1] -= 100000000;
  1448. }
  1449. digit = tdigit[0];
  1450. if (!digit && !tdigit[1])
  1451. nzeros += 16;
  1452. else {
  1453. if (!digit) {
  1454. nzeros += 8;
  1455. digit = tdigit[1];
  1456. }
  1457. // decompose digit
  1458. PD = (UINT64) digit *0x068DB8BBull;
  1459. digit_h = (UINT32) (PD >> 40);
  1460. digit_low = digit - digit_h * 10000;
  1461. if (!digit_low)
  1462. nzeros += 4;
  1463. else
  1464. digit_h = digit_low;
  1465. if (!(digit_h & 1))
  1466. nzeros +=
  1467. 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
  1468. (digit_h & 7));
  1469. }
  1470. if (nzeros) {
  1471. // get P*(2^M[extra_digits])/10^extra_digits
  1472. __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
  1473. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  1474. amount = recip_scale[nzeros];
  1475. __shr_128 (CQ, Qh, amount);
  1476. }
  1477. diff_expon += nzeros;
  1478. }
  1479. }
  1480. }
  1481. if(diff_expon>=0){
  1482. res =
  1483. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
  1484. rnd_mode, pfpsf);
  1485. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1486. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1487. #endif
  1488. BID_RETURN (res);
  1489. }
  1490. }
  1491. #endif
  1492. if(diff_expon>=0) {
  1493. #ifdef IEEE_ROUND_NEAREST
  1494. // rounding
  1495. // 2*CA4 - CY
  1496. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1497. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1498. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1499. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1500. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  1501. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  1502. CQ.w[0] += carry64;
  1503. //if(CQ.w[0]<carry64)
  1504. //CQ.w[1] ++;
  1505. #else
  1506. #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
  1507. // rounding
  1508. // 2*CA4 - CY
  1509. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1510. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1511. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1512. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1513. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  1514. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  1515. CQ.w[0] += carry64;
  1516. if (CQ.w[0] < carry64)
  1517. CQ.w[1]++;
  1518. #else
  1519. rmode = rnd_mode;
  1520. if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
  1521. rmode = 3 - rmode;
  1522. switch (rmode) {
  1523. case ROUNDING_TO_NEAREST: // round to nearest code
  1524. // rounding
  1525. // 2*CA4 - CY
  1526. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1527. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1528. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1529. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1530. D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
  1531. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
  1532. CQ.w[0] += carry64;
  1533. if (CQ.w[0] < carry64)
  1534. CQ.w[1]++;
  1535. break;
  1536. case ROUNDING_TIES_AWAY:
  1537. // rounding
  1538. // 2*CA4 - CY
  1539. CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
  1540. CA4r.w[0] = CA4.w[0] + CA4.w[0];
  1541. __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
  1542. CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
  1543. D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
  1544. carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
  1545. CQ.w[0] += carry64;
  1546. if (CQ.w[0] < carry64)
  1547. CQ.w[1]++;
  1548. break;
  1549. case ROUNDING_DOWN:
  1550. case ROUNDING_TO_ZERO:
  1551. break;
  1552. default: // rounding up
  1553. CQ.w[0]++;
  1554. if (!CQ.w[0])
  1555. CQ.w[1]++;
  1556. break;
  1557. }
  1558. #endif
  1559. #endif
  1560. res =
  1561. fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
  1562. pfpsf);
  1563. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1564. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1565. #endif
  1566. BID_RETURN (res);
  1567. } else {
  1568. // UF occurs
  1569. #ifdef SET_STATUS_FLAGS
  1570. if ((diff_expon + 16 < 0)) {
  1571. // set status flags
  1572. __set_status_flags (pfpsf, INEXACT_EXCEPTION);
  1573. }
  1574. #endif
  1575. rmode = rnd_mode;
  1576. res =
  1577. get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
  1578. #ifdef UNCHANGED_BINARY_STATUS_FLAGS
  1579. (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
  1580. #endif
  1581. BID_RETURN (res);
  1582. }
  1583. }