bid128_string.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  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. * BID128_to_string
  20. ****************************************************************************/
  21. #define BID_128RES
  22. #include <stdio.h>
  23. #include "bid_internal.h"
  24. #include "bid128_2_str.h"
  25. #include "bid128_2_str_macros.h"
  26. extern int bid128_coeff_2_string (UINT64 X_hi, UINT64 X_lo,
  27. char *char_ptr);
  28. #if DECIMAL_CALL_BY_REFERENCE
  29. void
  30. bid128_to_string (char *str,
  31. UINT128 *
  32. px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  33. _EXC_INFO_PARAM) {
  34. UINT128 x;
  35. #else
  36. void
  37. bid128_to_string (char *str, UINT128 x
  38. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  39. #endif
  40. UINT64 x_sign;
  41. UINT64 x_exp;
  42. int exp; // unbiased exponent
  43. // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
  44. int ind;
  45. UINT128 C1;
  46. unsigned int k = 0; // pointer in the string
  47. unsigned int d0, d123;
  48. UINT64 HI_18Dig, LO_18Dig, Tmp;
  49. UINT32 MiDi[12], *ptr;
  50. char *c_ptr_start, *c_ptr;
  51. int midi_ind, k_lcv, len;
  52. #if DECIMAL_CALL_BY_REFERENCE
  53. x = *px;
  54. #endif
  55. BID_SWAP128(x);
  56. // check for NaN or Infinity
  57. if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
  58. // x is special
  59. if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
  60. if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  61. // set invalid flag
  62. str[0] = ((SINT64)x.w[1]<0)? '-':'+';
  63. str[1] = 'S';
  64. str[2] = 'N';
  65. str[3] = 'a';
  66. str[4] = 'N';
  67. str[5] = '\0';
  68. } else { // x is QNaN
  69. str[0] = ((SINT64)x.w[1]<0)? '-':'+';
  70. str[1] = 'Q';
  71. str[2] = 'N';
  72. str[3] = 'a';
  73. str[4] = 'N';
  74. str[5] = '\0';
  75. }
  76. } else { // x is not a NaN, so it must be infinity
  77. if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
  78. str[0] = '+';
  79. str[1] = 'I';
  80. str[2] = 'n';
  81. str[3] = 'f';
  82. str[4] = '\0';
  83. } else { // x is -inf
  84. str[0] = '-';
  85. str[1] = 'I';
  86. str[2] = 'n';
  87. str[3] = 'f';
  88. str[4] = '\0';
  89. }
  90. }
  91. return;
  92. } else if (((x.w[1] & MASK_COEFF) == 0x0ull) && (x.w[0] == 0x0ull)) {
  93. // x is 0
  94. len = 0;
  95. //determine if +/-
  96. if (x.w[1] & MASK_SIGN)
  97. str[len++] = '-';
  98. else
  99. str[len++] = '+';
  100. str[len++] = '0';
  101. str[len++] = 'E';
  102. // extract the exponent and print
  103. exp = (int) (((x.w[1] & MASK_EXP) >> 49) - 6176);
  104. if(exp > (((0x5ffe)>>1) - (6176))) {
  105. exp = (int) ((((x.w[1]<<2) & MASK_EXP) >> 49) - 6176);
  106. }
  107. if (exp >= 0) {
  108. str[len++] = '+';
  109. len += sprintf (str + len, "%u", exp);// should not use sprintf (should
  110. // use sophisticated algorithm, since we know range of exp is limited)
  111. str[len++] = '\0';
  112. } else {
  113. len += sprintf (str + len, "%d", exp);// should not use sprintf (should
  114. // use sophisticated algorithm, since we know range of exp is limited)
  115. str[len++] = '\0';
  116. }
  117. return;
  118. } else { // x is not special and is not zero
  119. // unpack x
  120. x_sign = x.w[1] & MASK_SIGN;// 0 for positive, MASK_SIGN for negative
  121. x_exp = x.w[1] & MASK_EXP;// biased and shifted left 49 bit positions
  122. if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)
  123. x_exp = (x.w[1]<<2) & MASK_EXP;// biased and shifted left 49 bit positions
  124. C1.w[1] = x.w[1] & MASK_COEFF;
  125. C1.w[0] = x.w[0];
  126. exp = (x_exp >> 49) - 6176;
  127. // determine sign's representation as a char
  128. if (x_sign)
  129. str[k++] = '-';// negative number
  130. else
  131. str[k++] = '+';// positive number
  132. // determine coefficient's representation as a decimal string
  133. // if zero or non-canonical, set coefficient to '0'
  134. if ((C1.w[1] > 0x0001ed09bead87c0ull) ||
  135. (C1.w[1] == 0x0001ed09bead87c0ull &&
  136. (C1.w[0] > 0x378d8e63ffffffffull)) ||
  137. ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
  138. ((C1.w[1] == 0) && (C1.w[0] == 0))) {
  139. str[k++] = '0';
  140. } else {
  141. /* ****************************************************
  142. This takes a bid coefficient in C1.w[1],C1.w[0]
  143. and put the converted character sequence at location
  144. starting at &(str[k]). The function returns the number
  145. of MiDi returned. Note that the character sequence
  146. does not have leading zeros EXCEPT when the input is of
  147. zero value. It will then output 1 character '0'
  148. The algorithm essentailly tries first to get a sequence of
  149. Millenial Digits "MiDi" and then uses table lookup to get the
  150. character strings of these MiDis.
  151. **************************************************** */
  152. /* Algorithm first decompose possibly 34 digits in hi and lo
  153. 18 digits. (The high can have at most 16 digits). It then
  154. uses macro that handle 18 digit portions.
  155. The first step is to get hi and lo such that
  156. 2^(64) C1.w[1] + C1.w[0] = hi * 10^18 + lo, 0 <= lo < 10^18.
  157. We use a table lookup method to obtain the hi and lo 18 digits.
  158. [C1.w[1],C1.w[0]] = c_8 2^(107) + c_7 2^(101) + ... + c_0 2^(59) + d
  159. where 0 <= d < 2^59 and each c_j has 6 bits. Because d fits in
  160. 18 digits, we set hi = 0, and lo = d to begin with.
  161. We then retrieve from a table, for j = 0, 1, ..., 8
  162. that gives us A and B where c_j 2^(59+6j) = A * 10^18 + B.
  163. hi += A ; lo += B; After each accumulation into lo, we normalize
  164. immediately. So at the end, we have the decomposition as we need. */
  165. Tmp = C1.w[0] >> 59;
  166. LO_18Dig = (C1.w[0] << 5) >> 5;
  167. Tmp += (C1.w[1] << 5);
  168. HI_18Dig = 0;
  169. k_lcv = 0;
  170. // Tmp = {C1.w[1]{49:0}, C1.w[0]{63:59}}
  171. // Lo_18Dig = {C1.w[0]{58:0}}
  172. while (Tmp) {
  173. midi_ind = (int) (Tmp & 0x000000000000003FLL);
  174. midi_ind <<= 1;
  175. Tmp >>= 6;
  176. HI_18Dig += mod10_18_tbl[k_lcv][midi_ind++];
  177. LO_18Dig += mod10_18_tbl[k_lcv++][midi_ind];
  178. __L0_Normalize_10to18 (HI_18Dig, LO_18Dig);
  179. }
  180. ptr = MiDi;
  181. if (HI_18Dig == 0LL) {
  182. __L1_Split_MiDi_6_Lead (LO_18Dig, ptr);
  183. } else {
  184. __L1_Split_MiDi_6_Lead (HI_18Dig, ptr);
  185. __L1_Split_MiDi_6 (LO_18Dig, ptr);
  186. }
  187. len = ptr - MiDi;
  188. c_ptr_start = &(str[k]);
  189. c_ptr = c_ptr_start;
  190. /* now convert the MiDi into character strings */
  191. __L0_MiDi2Str_Lead (MiDi[0], c_ptr);
  192. for (k_lcv = 1; k_lcv < len; k_lcv++) {
  193. __L0_MiDi2Str (MiDi[k_lcv], c_ptr);
  194. }
  195. k = k + (c_ptr - c_ptr_start);
  196. }
  197. // print E and sign of exponent
  198. str[k++] = 'E';
  199. if (exp < 0) {
  200. exp = -exp;
  201. str[k++] = '-';
  202. } else {
  203. str[k++] = '+';
  204. }
  205. // determine exponent's representation as a decimal string
  206. // d0 = exp / 1000;
  207. // Use Property 1
  208. d0 = (exp * 0x418a) >> 24;// 0x418a * 2^-24 = (10^(-3))RP,15
  209. d123 = exp - 1000 * d0;
  210. if (d0) { // 1000 <= exp <= 6144 => 4 digits to return
  211. str[k++] = d0 + 0x30;// ASCII for decimal digit d0
  212. ind = 3 * d123;
  213. str[k++] = char_table3[ind];
  214. str[k++] = char_table3[ind + 1];
  215. str[k++] = char_table3[ind + 2];
  216. } else { // 0 <= exp <= 999 => d0 = 0
  217. if (d123 < 10) { // 0 <= exp <= 9 => 1 digit to return
  218. str[k++] = d123 + 0x30;// ASCII
  219. } else if (d123 < 100) { // 10 <= exp <= 99 => 2 digits to return
  220. ind = 2 * (d123 - 10);
  221. str[k++] = char_table2[ind];
  222. str[k++] = char_table2[ind + 1];
  223. } else { // 100 <= exp <= 999 => 3 digits to return
  224. ind = 3 * d123;
  225. str[k++] = char_table3[ind];
  226. str[k++] = char_table3[ind + 1];
  227. str[k++] = char_table3[ind + 2];
  228. }
  229. }
  230. str[k] = '\0';
  231. }
  232. return;
  233. }
  234. #define MAX_FORMAT_DIGITS_128 34
  235. #define MAX_STRING_DIGITS_128 100
  236. #define MAX_SEARCH MAX_STRING_DIGITS_128-MAX_FORMAT_DIGITS_128-1
  237. #if DECIMAL_CALL_BY_REFERENCE
  238. void
  239. bid128_from_string (UINT128 * pres,
  240. char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM
  241. _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  242. #else
  243. UINT128
  244. bid128_from_string (char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM
  245. _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  246. #endif
  247. UINT128 CX, res;
  248. UINT64 sign_x, coeff_high, coeff_low, coeff2, coeff_l2, carry = 0x0ull,
  249. scale_high, right_radix_leading_zeros;
  250. int ndigits_before, ndigits_after, ndigits_total, dec_expon, sgn_exp,
  251. i, d2, rdx_pt_enc;
  252. char c, buffer[MAX_STRING_DIGITS_128];
  253. int save_rnd_mode;
  254. int save_fpsf;
  255. #if DECIMAL_CALL_BY_REFERENCE
  256. #if !DECIMAL_GLOBAL_ROUNDING
  257. _IDEC_round rnd_mode = *prnd_mode;
  258. #endif
  259. #endif
  260. save_rnd_mode = rnd_mode; // dummy
  261. save_fpsf = *pfpsf; // dummy
  262. right_radix_leading_zeros = rdx_pt_enc = 0;
  263. // if null string, return NaN
  264. if (!ps) {
  265. res.w[1] = 0x7c00000000000000ull;
  266. res.w[0] = 0;
  267. BID_RETURN (res);
  268. }
  269. // eliminate leading white space
  270. while ((*ps == ' ') || (*ps == '\t'))
  271. ps++;
  272. // c gets first character
  273. c = *ps;
  274. // if c is null or not equal to a (radix point, negative sign,
  275. // positive sign, or number) it might be SNaN, sNaN, Infinity
  276. if (!c
  277. || (c != '.' && c != '-' && c != '+'
  278. && ((unsigned) (c - '0') > 9))) {
  279. res.w[0] = 0;
  280. // Infinity?
  281. if ((tolower_macro (ps[0]) == 'i' && tolower_macro (ps[1]) == 'n'
  282. && tolower_macro (ps[2]) == 'f')
  283. && (!ps[3]
  284. || (tolower_macro (ps[3]) == 'i'
  285. && tolower_macro (ps[4]) == 'n'
  286. && tolower_macro (ps[5]) == 'i'
  287. && tolower_macro (ps[6]) == 't'
  288. && tolower_macro (ps[7]) == 'y' && !ps[8])
  289. )) {
  290. res.w[1] = 0x7800000000000000ull;
  291. BID_RETURN (res);
  292. }
  293. // return sNaN
  294. if (tolower_macro (ps[0]) == 's' && tolower_macro (ps[1]) == 'n' &&
  295. tolower_macro (ps[2]) == 'a' && tolower_macro (ps[3]) == 'n') {
  296. // case insensitive check for snan
  297. res.w[1] = 0x7e00000000000000ull;
  298. BID_RETURN (res);
  299. } else {
  300. // return qNaN
  301. res.w[1] = 0x7c00000000000000ull;
  302. BID_RETURN (res);
  303. }
  304. }
  305. // if +Inf, -Inf, +Infinity, or -Infinity (case insensitive check for inf)
  306. if ((tolower_macro (ps[1]) == 'i' && tolower_macro (ps[2]) == 'n' &&
  307. tolower_macro (ps[3]) == 'f') && (!ps[4] ||
  308. (tolower_macro (ps[4]) == 'i' && tolower_macro (ps[5]) == 'n' &&
  309. tolower_macro (ps[6]) == 'i' && tolower_macro (ps[7]) == 't' &&
  310. tolower_macro (ps[8]) == 'y' && !ps[9]))) { // ci check for infinity
  311. res.w[0] = 0;
  312. if (c == '+')
  313. res.w[1] = 0x7800000000000000ull;
  314. else if (c == '-')
  315. res.w[1] = 0xf800000000000000ull;
  316. else
  317. res.w[1] = 0x7c00000000000000ull;
  318. BID_RETURN (res);
  319. }
  320. // if +sNaN, +SNaN, -sNaN, or -SNaN
  321. if (tolower_macro (ps[1]) == 's' && tolower_macro (ps[2]) == 'n'
  322. && tolower_macro (ps[3]) == 'a' && tolower_macro (ps[4]) == 'n') {
  323. res.w[0] = 0;
  324. if (c == '-')
  325. res.w[1] = 0xfe00000000000000ull;
  326. else
  327. res.w[1] = 0x7e00000000000000ull;
  328. BID_RETURN (res);
  329. }
  330. // set up sign_x to be OR'ed with the upper word later
  331. if (c == '-')
  332. sign_x = 0x8000000000000000ull;
  333. else
  334. sign_x = 0;
  335. // go to next character if leading sign
  336. if (c == '-' || c == '+')
  337. ps++;
  338. c = *ps;
  339. // if c isn't a decimal point or a decimal digit, return NaN
  340. if (c != '.' && ((unsigned) (c - '0') > 9)) {
  341. res.w[1] = 0x7c00000000000000ull | sign_x;
  342. res.w[0] = 0;
  343. BID_RETURN (res);
  344. }
  345. // detect zero (and eliminate/ignore leading zeros)
  346. if (*(ps) == '0') {
  347. // if all numbers are zeros (with possibly 1 radix point, the number is zero
  348. // should catch cases such as: 000.0
  349. while (*ps == '0') {
  350. ps++;
  351. // for numbers such as 0.0000000000000000000000000000000000001001,
  352. // we want to count the leading zeros
  353. if (rdx_pt_enc) {
  354. right_radix_leading_zeros++;
  355. }
  356. // if this character is a radix point, make sure we haven't already
  357. // encountered one
  358. if (*(ps) == '.') {
  359. if (rdx_pt_enc == 0) {
  360. rdx_pt_enc = 1;
  361. // if this is the first radix point, and the next character is NULL,
  362. // we have a zero
  363. if (!*(ps + 1)) {
  364. res.w[1] =
  365. (0x3040000000000000ull -
  366. (right_radix_leading_zeros << 49)) | sign_x;
  367. res.w[0] = 0;
  368. BID_RETURN (res);
  369. }
  370. ps = ps + 1;
  371. } else {
  372. // if 2 radix points, return NaN
  373. res.w[1] = 0x7c00000000000000ull | sign_x;
  374. res.w[0] = 0;
  375. BID_RETURN (res);
  376. }
  377. } else if (!*(ps)) {
  378. //res.w[1] = 0x3040000000000000ull | sign_x;
  379. res.w[1] =
  380. (0x3040000000000000ull -
  381. (right_radix_leading_zeros << 49)) | sign_x;
  382. res.w[0] = 0;
  383. BID_RETURN (res);
  384. }
  385. }
  386. }
  387. c = *ps;
  388. // initialize local variables
  389. ndigits_before = ndigits_after = ndigits_total = 0;
  390. sgn_exp = 0;
  391. // pstart_coefficient = ps;
  392. if (!rdx_pt_enc) {
  393. // investigate string (before radix point)
  394. while ((unsigned) (c - '0') <= 9
  395. && ndigits_before < MAX_STRING_DIGITS_128) {
  396. buffer[ndigits_before] = c;
  397. ps++;
  398. c = *ps;
  399. ndigits_before++;
  400. }
  401. ndigits_total = ndigits_before;
  402. if (c == '.') {
  403. ps++;
  404. if ((c = *ps)) {
  405. // investigate string (after radix point)
  406. while ((unsigned) (c - '0') <= 9
  407. && ndigits_total < MAX_STRING_DIGITS_128) {
  408. buffer[ndigits_total] = c;
  409. ps++;
  410. c = *ps;
  411. ndigits_total++;
  412. }
  413. ndigits_after = ndigits_total - ndigits_before;
  414. }
  415. }
  416. } else {
  417. // we encountered a radix point while detecting zeros
  418. //if (c = *ps){
  419. c = *ps;
  420. ndigits_total = 0;
  421. // investigate string (after radix point)
  422. while ((unsigned) (c - '0') <= 9
  423. && ndigits_total < MAX_STRING_DIGITS_128) {
  424. buffer[ndigits_total] = c;
  425. ps++;
  426. c = *ps;
  427. ndigits_total++;
  428. }
  429. ndigits_after = ndigits_total - ndigits_before;
  430. }
  431. // get exponent
  432. dec_expon = 0;
  433. if (ndigits_total < MAX_STRING_DIGITS_128) {
  434. if (c) {
  435. if (c != 'e' && c != 'E') {
  436. // return NaN
  437. res.w[1] = 0x7c00000000000000ull;
  438. res.w[0] = 0;
  439. BID_RETURN (res);
  440. }
  441. ps++;
  442. c = *ps;
  443. if (((unsigned) (c - '0') > 9)
  444. && ((c != '+' && c != '-') || (unsigned) (ps[1] - '0') > 9)) {
  445. // return NaN
  446. res.w[1] = 0x7c00000000000000ull;
  447. res.w[0] = 0;
  448. BID_RETURN (res);
  449. }
  450. if (c == '-') {
  451. sgn_exp = -1;
  452. ps++;
  453. c = *ps;
  454. } else if (c == '+') {
  455. ps++;
  456. c = *ps;
  457. }
  458. dec_expon = c - '0';
  459. i = 1;
  460. ps++;
  461. c = *ps - '0';
  462. while (((unsigned) c) <= 9 && i < 7) {
  463. d2 = dec_expon + dec_expon;
  464. dec_expon = (d2 << 2) + d2 + c;
  465. ps++;
  466. c = *ps - '0';
  467. i++;
  468. }
  469. }
  470. dec_expon = (dec_expon + sgn_exp) ^ sgn_exp;
  471. }
  472. if (ndigits_total <= MAX_FORMAT_DIGITS_128) {
  473. dec_expon +=
  474. DECIMAL_EXPONENT_BIAS_128 - ndigits_after -
  475. right_radix_leading_zeros;
  476. if (dec_expon < 0) {
  477. res.w[1] = 0 | sign_x;
  478. res.w[0] = 0;
  479. }
  480. if (ndigits_total == 0) {
  481. CX.w[0] = 0;
  482. CX.w[1] = 0;
  483. } else if (ndigits_total <= 19) {
  484. coeff_high = buffer[0] - '0';
  485. for (i = 1; i < ndigits_total; i++) {
  486. coeff2 = coeff_high + coeff_high;
  487. coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
  488. }
  489. CX.w[0] = coeff_high;
  490. CX.w[1] = 0;
  491. } else {
  492. coeff_high = buffer[0] - '0';
  493. for (i = 1; i < ndigits_total - 17; i++) {
  494. coeff2 = coeff_high + coeff_high;
  495. coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
  496. }
  497. coeff_low = buffer[i] - '0';
  498. i++;
  499. for (; i < ndigits_total; i++) {
  500. coeff_l2 = coeff_low + coeff_low;
  501. coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0';
  502. }
  503. // now form the coefficient as coeff_high*10^19+coeff_low+carry
  504. scale_high = 100000000000000000ull;
  505. __mul_64x64_to_128_fast (CX, coeff_high, scale_high);
  506. CX.w[0] += coeff_low;
  507. if (CX.w[0] < coeff_low)
  508. CX.w[1]++;
  509. }
  510. get_BID128 (&res, sign_x, dec_expon, CX,&rnd_mode,pfpsf);
  511. BID_RETURN (res);
  512. } else {
  513. // simply round using the digits that were read
  514. dec_expon +=
  515. ndigits_before + DECIMAL_EXPONENT_BIAS_128 -
  516. MAX_FORMAT_DIGITS_128 - right_radix_leading_zeros;
  517. if (dec_expon < 0) {
  518. res.w[1] = 0 | sign_x;
  519. res.w[0] = 0;
  520. }
  521. coeff_high = buffer[0] - '0';
  522. for (i = 1; i < MAX_FORMAT_DIGITS_128 - 17; i++) {
  523. coeff2 = coeff_high + coeff_high;
  524. coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
  525. }
  526. coeff_low = buffer[i] - '0';
  527. i++;
  528. for (; i < MAX_FORMAT_DIGITS_128; i++) {
  529. coeff_l2 = coeff_low + coeff_low;
  530. coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0';
  531. }
  532. switch(rnd_mode) {
  533. case ROUNDING_TO_NEAREST:
  534. carry = ((unsigned) ('4' - buffer[i])) >> 31;
  535. if ((buffer[i] == '5' && !(coeff_low & 1)) || dec_expon < 0) {
  536. if (dec_expon >= 0) {
  537. carry = 0;
  538. i++;
  539. }
  540. for (; i < ndigits_total; i++) {
  541. if (buffer[i] > '0') {
  542. carry = 1;
  543. break;
  544. }
  545. }
  546. }
  547. break;
  548. case ROUNDING_DOWN:
  549. if(sign_x)
  550. for (; i < ndigits_total; i++) {
  551. if (buffer[i] > '0') {
  552. carry = 1;
  553. break;
  554. }
  555. }
  556. break;
  557. case ROUNDING_UP:
  558. if(!sign_x)
  559. for (; i < ndigits_total; i++) {
  560. if (buffer[i] > '0') {
  561. carry = 1;
  562. break;
  563. }
  564. }
  565. break;
  566. case ROUNDING_TO_ZERO:
  567. carry=0;
  568. break;
  569. case ROUNDING_TIES_AWAY:
  570. carry = ((unsigned) ('4' - buffer[i])) >> 31;
  571. if (dec_expon < 0) {
  572. for (; i < ndigits_total; i++) {
  573. if (buffer[i] > '0') {
  574. carry = 1;
  575. break;
  576. }
  577. }
  578. }
  579. break;
  580. }
  581. // now form the coefficient as coeff_high*10^17+coeff_low+carry
  582. scale_high = 100000000000000000ull;
  583. if (dec_expon < 0) {
  584. if (dec_expon > -MAX_FORMAT_DIGITS_128) {
  585. scale_high = 1000000000000000000ull;
  586. coeff_low = (coeff_low << 3) + (coeff_low << 1);
  587. dec_expon--;
  588. }
  589. if (dec_expon == -MAX_FORMAT_DIGITS_128
  590. && coeff_high > 50000000000000000ull)
  591. carry = 0;
  592. }
  593. __mul_64x64_to_128_fast (CX, coeff_high, scale_high);
  594. coeff_low += carry;
  595. CX.w[0] += coeff_low;
  596. if (CX.w[0] < coeff_low)
  597. CX.w[1]++;
  598. get_BID128(&res, sign_x, dec_expon, CX, &rnd_mode, pfpsf);
  599. BID_RETURN (res);
  600. }
  601. }