bid64_to_int64.c 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329
  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. #include "bid_internal.h"
  19. /*****************************************************************************
  20. * BID64_to_int64_rnint
  21. ****************************************************************************/
  22. #if DECIMAL_CALL_BY_REFERENCE
  23. void
  24. bid64_to_int64_rnint (SINT64 * pres, UINT64 * px
  25. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  26. _EXC_INFO_PARAM) {
  27. UINT64 x = *px;
  28. #else
  29. SINT64
  30. bid64_to_int64_rnint (UINT64 x
  31. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  32. _EXC_INFO_PARAM) {
  33. #endif
  34. SINT64 res;
  35. UINT64 x_sign;
  36. UINT64 x_exp;
  37. int exp; // unbiased exponent
  38. // Note: C1 represents x_significand (UINT64)
  39. BID_UI64DOUBLE tmp1;
  40. unsigned int x_nr_bits;
  41. int q, ind, shift;
  42. UINT64 C1;
  43. UINT128 C;
  44. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  45. UINT128 fstar;
  46. UINT128 P128;
  47. // check for NaN or Infinity
  48. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  49. // set invalid flag
  50. *pfpsf |= INVALID_EXCEPTION;
  51. // return Integer Indefinite
  52. res = 0x8000000000000000ull;
  53. BID_RETURN (res);
  54. }
  55. // unpack x
  56. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  57. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  58. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  59. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  60. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  61. if (C1 > 9999999999999999ull) { // non-canonical
  62. x_exp = 0;
  63. C1 = 0;
  64. }
  65. } else {
  66. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  67. C1 = x & MASK_BINARY_SIG1;
  68. }
  69. // check for zeros (possibly from non-canonical values)
  70. if (C1 == 0x0ull) {
  71. // x is 0
  72. res = 0x00000000;
  73. BID_RETURN (res);
  74. }
  75. // x is not special and is not zero
  76. // q = nr. of decimal digits in x (1 <= q <= 54)
  77. // determine first the nr. of bits in x
  78. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  79. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  80. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  81. tmp1.d = (double) (C1 >> 32); // exact conversion
  82. x_nr_bits =
  83. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  84. } else { // x < 2^32
  85. tmp1.d = (double) C1; // exact conversion
  86. x_nr_bits =
  87. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  88. }
  89. } else { // if x < 2^53
  90. tmp1.d = (double) C1; // exact conversion
  91. x_nr_bits =
  92. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  93. }
  94. q = nr_digits[x_nr_bits - 1].digits;
  95. if (q == 0) {
  96. q = nr_digits[x_nr_bits - 1].digits1;
  97. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  98. q++;
  99. }
  100. exp = x_exp - 398; // unbiased exponent
  101. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  102. // set invalid flag
  103. *pfpsf |= INVALID_EXCEPTION;
  104. // return Integer Indefinite
  105. res = 0x8000000000000000ull;
  106. BID_RETURN (res);
  107. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  108. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  109. // so x rounded to an integer may or may not fit in a signed 64-bit int
  110. // the cases that do not fit are identified here; the ones that fit
  111. // fall through and will be handled with other cases further,
  112. // under '1 <= q + exp <= 19'
  113. if (x_sign) { // if n < 0 and q + exp = 19
  114. // if n < -2^63 - 1/2 then n is too large
  115. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
  116. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
  117. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
  118. // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
  119. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  120. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  121. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
  122. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
  123. // set invalid flag
  124. *pfpsf |= INVALID_EXCEPTION;
  125. // return Integer Indefinite
  126. res = 0x8000000000000000ull;
  127. BID_RETURN (res);
  128. }
  129. // else cases that can be rounded to a 64-bit int fall through
  130. // to '1 <= q + exp <= 19'
  131. } else { // if n > 0 and q + exp = 19
  132. // if n >= 2^63 - 1/2 then n is too large
  133. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
  134. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
  135. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
  136. // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
  137. C.w[1] = 0x0000000000000004ull;
  138. C.w[0] = 0xfffffffffffffffbull;
  139. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  140. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  141. if (C.w[1] > 0x04ull ||
  142. (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
  143. // set invalid flag
  144. *pfpsf |= INVALID_EXCEPTION;
  145. // return Integer Indefinite
  146. res = 0x8000000000000000ull;
  147. BID_RETURN (res);
  148. }
  149. // else cases that can be rounded to a 64-bit int fall through
  150. // to '1 <= q + exp <= 19'
  151. } // end else if n > 0 and q + exp = 19
  152. } // end else if ((q + exp) == 19)
  153. // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
  154. // Note: some of the cases tested for above fall through to this point
  155. if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  156. // return 0
  157. res = 0x0000000000000000ull;
  158. BID_RETURN (res);
  159. } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
  160. // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
  161. // res = 0
  162. // else
  163. // res = +/-1
  164. ind = q - 1; // 0 <= ind <= 15
  165. if (C1 <= midpoint64[ind]) {
  166. res = 0x0000000000000000ull; // return 0
  167. } else if (x_sign) { // n < 0
  168. res = 0xffffffffffffffffull; // return -1
  169. } else { // n > 0
  170. res = 0x0000000000000001ull; // return +1
  171. }
  172. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  173. // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
  174. // to nearest to a 64-bit signed integer
  175. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  176. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  177. // chop off ind digits from the lower part of C1
  178. // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
  179. C1 = C1 + midpoint64[ind - 1];
  180. // calculate C* and f*
  181. // C* is actually floor(C*) in this case
  182. // C* and f* need shifting and masking, as shown by
  183. // shiftright128[] and maskhigh128[]
  184. // 1 <= x <= 15
  185. // kx = 10^(-x) = ten2mk64[ind - 1]
  186. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  187. // the approximation of 10^(-x) was rounded up to 54 bits
  188. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  189. Cstar = P128.w[1];
  190. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  191. fstar.w[0] = P128.w[0];
  192. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  193. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  194. // if (0 < f* < 10^(-x)) then the result is a midpoint
  195. // if floor(C*) is even then C* = floor(C*) - logical right
  196. // shift; C* has p decimal digits, correct by Prop. 1)
  197. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  198. // shift; C* has p decimal digits, correct by Pr. 1)
  199. // else
  200. // C* = floor(C*) (logical right shift; C has p decimal digits,
  201. // correct by Property 1)
  202. // n = C* * 10^(e+x)
  203. // shift right C* by Ex-64 = shiftright128[ind]
  204. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  205. Cstar = Cstar >> shift;
  206. // if the result was a midpoint it was rounded away from zero, so
  207. // it will need a correction
  208. // check for midpoints
  209. if ((fstar.w[1] == 0) && fstar.w[0] &&
  210. (fstar.w[0] <= ten2mk128trunc[ind - 1].w[1])) {
  211. // ten2mk128trunc[ind -1].w[1] is identical to
  212. // ten2mk128[ind -1].w[1]
  213. // the result is a midpoint; round to nearest
  214. if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
  215. // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
  216. Cstar--; // Cstar is now even
  217. } // else MP in [ODD, EVEN]
  218. }
  219. if (x_sign)
  220. res = -Cstar;
  221. else
  222. res = Cstar;
  223. } else if (exp == 0) {
  224. // 1 <= q <= 16
  225. // res = +/-C (exact)
  226. if (x_sign)
  227. res = -C1;
  228. else
  229. res = C1;
  230. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  231. // (the upper limit of 20 on q + exp is due to the fact that
  232. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  233. // res = +/-C * 10^exp (exact)
  234. if (x_sign)
  235. res = -C1 * ten2k64[exp];
  236. else
  237. res = C1 * ten2k64[exp];
  238. }
  239. }
  240. BID_RETURN (res);
  241. }
  242. /*****************************************************************************
  243. * BID64_to_int64_xrnint
  244. ****************************************************************************/
  245. #if DECIMAL_CALL_BY_REFERENCE
  246. void
  247. bid64_to_int64_xrnint (SINT64 * pres, UINT64 * px
  248. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  249. _EXC_INFO_PARAM) {
  250. UINT64 x = *px;
  251. #else
  252. SINT64
  253. bid64_to_int64_xrnint (UINT64 x
  254. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  255. _EXC_INFO_PARAM) {
  256. #endif
  257. SINT64 res;
  258. UINT64 x_sign;
  259. UINT64 x_exp;
  260. int exp; // unbiased exponent
  261. // Note: C1 represents x_significand (UINT64)
  262. UINT64 tmp64;
  263. BID_UI64DOUBLE tmp1;
  264. unsigned int x_nr_bits;
  265. int q, ind, shift;
  266. UINT64 C1;
  267. UINT128 C;
  268. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  269. UINT128 fstar;
  270. UINT128 P128;
  271. // check for NaN or Infinity
  272. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  273. // set invalid flag
  274. *pfpsf |= INVALID_EXCEPTION;
  275. // return Integer Indefinite
  276. res = 0x8000000000000000ull;
  277. BID_RETURN (res);
  278. }
  279. // unpack x
  280. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  281. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  282. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  283. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  284. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  285. if (C1 > 9999999999999999ull) { // non-canonical
  286. x_exp = 0;
  287. C1 = 0;
  288. }
  289. } else {
  290. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  291. C1 = x & MASK_BINARY_SIG1;
  292. }
  293. // check for zeros (possibly from non-canonical values)
  294. if (C1 == 0x0ull) {
  295. // x is 0
  296. res = 0x00000000;
  297. BID_RETURN (res);
  298. }
  299. // x is not special and is not zero
  300. // q = nr. of decimal digits in x (1 <= q <= 54)
  301. // determine first the nr. of bits in x
  302. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  303. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  304. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  305. tmp1.d = (double) (C1 >> 32); // exact conversion
  306. x_nr_bits =
  307. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  308. } else { // x < 2^32
  309. tmp1.d = (double) C1; // exact conversion
  310. x_nr_bits =
  311. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  312. }
  313. } else { // if x < 2^53
  314. tmp1.d = (double) C1; // exact conversion
  315. x_nr_bits =
  316. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  317. }
  318. q = nr_digits[x_nr_bits - 1].digits;
  319. if (q == 0) {
  320. q = nr_digits[x_nr_bits - 1].digits1;
  321. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  322. q++;
  323. }
  324. exp = x_exp - 398; // unbiased exponent
  325. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  326. // set invalid flag
  327. *pfpsf |= INVALID_EXCEPTION;
  328. // return Integer Indefinite
  329. res = 0x8000000000000000ull;
  330. BID_RETURN (res);
  331. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  332. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  333. // so x rounded to an integer may or may not fit in a signed 64-bit int
  334. // the cases that do not fit are identified here; the ones that fit
  335. // fall through and will be handled with other cases further,
  336. // under '1 <= q + exp <= 19'
  337. if (x_sign) { // if n < 0 and q + exp = 19
  338. // if n < -2^63 - 1/2 then n is too large
  339. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63+1/2
  340. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64+1), 1<=q<=16
  341. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000005, 1<=q<=16
  342. // <=> C * 10^(20-q) > 0x50000000000000005, 1<=q<=16
  343. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  344. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  345. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
  346. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] > 0x05ull)) {
  347. // set invalid flag
  348. *pfpsf |= INVALID_EXCEPTION;
  349. // return Integer Indefinite
  350. res = 0x8000000000000000ull;
  351. BID_RETURN (res);
  352. }
  353. // else cases that can be rounded to a 64-bit int fall through
  354. // to '1 <= q + exp <= 19'
  355. } else { // if n > 0 and q + exp = 19
  356. // if n >= 2^63 - 1/2 then n is too large
  357. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
  358. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
  359. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
  360. // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
  361. C.w[1] = 0x0000000000000004ull;
  362. C.w[0] = 0xfffffffffffffffbull;
  363. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  364. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  365. if (C.w[1] > 0x04ull ||
  366. (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
  367. // set invalid flag
  368. *pfpsf |= INVALID_EXCEPTION;
  369. // return Integer Indefinite
  370. res = 0x8000000000000000ull;
  371. BID_RETURN (res);
  372. }
  373. // else cases that can be rounded to a 64-bit int fall through
  374. // to '1 <= q + exp <= 19'
  375. } // end else if n > 0 and q + exp = 19
  376. } // end else if ((q + exp) == 19)
  377. // n is not too large to be converted to int64: -2^63-1/2 <= n < 2^63-1/2
  378. // Note: some of the cases tested for above fall through to this point
  379. if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  380. // set inexact flag
  381. *pfpsf |= INEXACT_EXCEPTION;
  382. // return 0
  383. res = 0x0000000000000000ull;
  384. BID_RETURN (res);
  385. } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
  386. // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
  387. // res = 0
  388. // else
  389. // res = +/-1
  390. ind = q - 1; // 0 <= ind <= 15
  391. if (C1 <= midpoint64[ind]) {
  392. res = 0x0000000000000000ull; // return 0
  393. } else if (x_sign) { // n < 0
  394. res = 0xffffffffffffffffull; // return -1
  395. } else { // n > 0
  396. res = 0x0000000000000001ull; // return +1
  397. }
  398. // set inexact flag
  399. *pfpsf |= INEXACT_EXCEPTION;
  400. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  401. // -2^63-1/2 <= x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
  402. // to nearest to a 64-bit signed integer
  403. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  404. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  405. // chop off ind digits from the lower part of C1
  406. // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
  407. C1 = C1 + midpoint64[ind - 1];
  408. // calculate C* and f*
  409. // C* is actually floor(C*) in this case
  410. // C* and f* need shifting and masking, as shown by
  411. // shiftright128[] and maskhigh128[]
  412. // 1 <= x <= 15
  413. // kx = 10^(-x) = ten2mk64[ind - 1]
  414. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  415. // the approximation of 10^(-x) was rounded up to 54 bits
  416. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  417. Cstar = P128.w[1];
  418. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  419. fstar.w[0] = P128.w[0];
  420. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  421. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  422. // if (0 < f* < 10^(-x)) then the result is a midpoint
  423. // if floor(C*) is even then C* = floor(C*) - logical right
  424. // shift; C* has p decimal digits, correct by Prop. 1)
  425. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  426. // shift; C* has p decimal digits, correct by Pr. 1)
  427. // else
  428. // C* = floor(C*) (logical right shift; C has p decimal digits,
  429. // correct by Property 1)
  430. // n = C* * 10^(e+x)
  431. // shift right C* by Ex-64 = shiftright128[ind]
  432. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  433. Cstar = Cstar >> shift;
  434. // determine inexactness of the rounding of C*
  435. // if (0 < f* - 1/2 < 10^(-x)) then
  436. // the result is exact
  437. // else // if (f* - 1/2 > T*) then
  438. // the result is inexact
  439. if (ind - 1 <= 2) {
  440. if (fstar.w[0] > 0x8000000000000000ull) {
  441. // f* > 1/2 and the result may be exact
  442. tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
  443. if ((tmp64 > ten2mk128trunc[ind - 1].w[1])) {
  444. // ten2mk128trunc[ind -1].w[1] is identical to
  445. // ten2mk128[ind -1].w[1]
  446. // set the inexact flag
  447. *pfpsf |= INEXACT_EXCEPTION;
  448. } // else the result is exact
  449. } else { // the result is inexact; f2* <= 1/2
  450. // set the inexact flag
  451. *pfpsf |= INEXACT_EXCEPTION;
  452. }
  453. } else { // if 3 <= ind - 1 <= 14
  454. if (fstar.w[1] > onehalf128[ind - 1] ||
  455. (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
  456. // f2* > 1/2 and the result may be exact
  457. // Calculate f2* - 1/2
  458. tmp64 = fstar.w[1] - onehalf128[ind - 1];
  459. if (tmp64 || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  460. // ten2mk128trunc[ind -1].w[1] is identical to
  461. // ten2mk128[ind -1].w[1]
  462. // set the inexact flag
  463. *pfpsf |= INEXACT_EXCEPTION;
  464. } // else the result is exact
  465. } else { // the result is inexact; f2* <= 1/2
  466. // set the inexact flag
  467. *pfpsf |= INEXACT_EXCEPTION;
  468. }
  469. }
  470. // if the result was a midpoint it was rounded away from zero, so
  471. // it will need a correction
  472. // check for midpoints
  473. if ((fstar.w[1] == 0) && fstar.w[0] &&
  474. (fstar.w[0] <= ten2mk128trunc[ind - 1].w[1])) {
  475. // ten2mk128trunc[ind -1].w[1] is identical to
  476. // ten2mk128[ind -1].w[1]
  477. // the result is a midpoint; round to nearest
  478. if (Cstar & 0x01) { // Cstar is odd; MP in [EVEN, ODD]
  479. // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
  480. Cstar--; // Cstar is now even
  481. } // else MP in [ODD, EVEN]
  482. }
  483. if (x_sign)
  484. res = -Cstar;
  485. else
  486. res = Cstar;
  487. } else if (exp == 0) {
  488. // 1 <= q <= 16
  489. // res = +/-C (exact)
  490. if (x_sign)
  491. res = -C1;
  492. else
  493. res = C1;
  494. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  495. // (the upper limit of 20 on q + exp is due to the fact that
  496. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  497. // res = +/-C * 10^exp (exact)
  498. if (x_sign)
  499. res = -C1 * ten2k64[exp];
  500. else
  501. res = C1 * ten2k64[exp];
  502. }
  503. }
  504. BID_RETURN (res);
  505. }
  506. /*****************************************************************************
  507. * BID64_to_int64_floor
  508. ****************************************************************************/
  509. #if DECIMAL_CALL_BY_REFERENCE
  510. void
  511. bid64_to_int64_floor (SINT64 * pres, UINT64 * px
  512. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  513. _EXC_INFO_PARAM) {
  514. UINT64 x = *px;
  515. #else
  516. SINT64
  517. bid64_to_int64_floor (UINT64 x
  518. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  519. _EXC_INFO_PARAM) {
  520. #endif
  521. SINT64 res;
  522. UINT64 x_sign;
  523. UINT64 x_exp;
  524. int exp; // unbiased exponent
  525. // Note: C1 represents x_significand (UINT64)
  526. BID_UI64DOUBLE tmp1;
  527. unsigned int x_nr_bits;
  528. int q, ind, shift;
  529. UINT64 C1;
  530. UINT128 C;
  531. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  532. UINT128 fstar;
  533. UINT128 P128;
  534. // check for NaN or Infinity
  535. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  536. // set invalid flag
  537. *pfpsf |= INVALID_EXCEPTION;
  538. // return Integer Indefinite
  539. res = 0x8000000000000000ull;
  540. BID_RETURN (res);
  541. }
  542. // unpack x
  543. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  544. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  545. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  546. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  547. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  548. if (C1 > 9999999999999999ull) { // non-canonical
  549. x_exp = 0;
  550. C1 = 0;
  551. }
  552. } else {
  553. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  554. C1 = x & MASK_BINARY_SIG1;
  555. }
  556. // check for zeros (possibly from non-canonical values)
  557. if (C1 == 0x0ull) {
  558. // x is 0
  559. res = 0x0000000000000000ull;
  560. BID_RETURN (res);
  561. }
  562. // x is not special and is not zero
  563. // q = nr. of decimal digits in x (1 <= q <= 54)
  564. // determine first the nr. of bits in x
  565. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  566. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  567. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  568. tmp1.d = (double) (C1 >> 32); // exact conversion
  569. x_nr_bits =
  570. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  571. } else { // x < 2^32
  572. tmp1.d = (double) C1; // exact conversion
  573. x_nr_bits =
  574. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  575. }
  576. } else { // if x < 2^53
  577. tmp1.d = (double) C1; // exact conversion
  578. x_nr_bits =
  579. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  580. }
  581. q = nr_digits[x_nr_bits - 1].digits;
  582. if (q == 0) {
  583. q = nr_digits[x_nr_bits - 1].digits1;
  584. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  585. q++;
  586. }
  587. exp = x_exp - 398; // unbiased exponent
  588. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  589. // set invalid flag
  590. *pfpsf |= INVALID_EXCEPTION;
  591. // return Integer Indefinite
  592. res = 0x8000000000000000ull;
  593. BID_RETURN (res);
  594. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  595. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  596. // so x rounded to an integer may or may not fit in a signed 64-bit int
  597. // the cases that do not fit are identified here; the ones that fit
  598. // fall through and will be handled with other cases further,
  599. // under '1 <= q + exp <= 19'
  600. if (x_sign) { // if n < 0 and q + exp = 19
  601. // if n < -2^63 then n is too large
  602. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
  603. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  604. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
  605. // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
  606. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  607. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  608. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  609. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
  610. // set invalid flag
  611. *pfpsf |= INVALID_EXCEPTION;
  612. // return Integer Indefinite
  613. res = 0x8000000000000000ull;
  614. BID_RETURN (res);
  615. }
  616. // else cases that can be rounded to a 64-bit int fall through
  617. // to '1 <= q + exp <= 19'
  618. } else { // if n > 0 and q + exp = 19
  619. // if n >= 2^63 then n is too large
  620. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
  621. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  622. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
  623. // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
  624. C.w[1] = 0x0000000000000005ull;
  625. C.w[0] = 0x0000000000000000ull;
  626. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  627. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  628. if (C.w[1] >= 0x05ull) {
  629. // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
  630. // set invalid flag
  631. *pfpsf |= INVALID_EXCEPTION;
  632. // return Integer Indefinite
  633. res = 0x8000000000000000ull;
  634. BID_RETURN (res);
  635. }
  636. // else cases that can be rounded to a 64-bit int fall through
  637. // to '1 <= q + exp <= 19'
  638. } // end else if n > 0 and q + exp = 19
  639. } // end else if ((q + exp) == 19)
  640. // n is not too large to be converted to int64: -2^63 <= n < 2^63
  641. // Note: some of the cases tested for above fall through to this point
  642. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  643. // return -1 or 0
  644. if (x_sign)
  645. res = 0xffffffffffffffffull;
  646. else
  647. res = 0x0000000000000000ull;
  648. BID_RETURN (res);
  649. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  650. // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
  651. // to nearest to a 64-bit signed integer
  652. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  653. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  654. // chop off ind digits from the lower part of C1
  655. // C1 fits in 64 bits
  656. // calculate C* and f*
  657. // C* is actually floor(C*) in this case
  658. // C* and f* need shifting and masking, as shown by
  659. // shiftright128[] and maskhigh128[]
  660. // 1 <= x <= 15
  661. // kx = 10^(-x) = ten2mk64[ind - 1]
  662. // C* = C1 * 10^(-x)
  663. // the approximation of 10^(-x) was rounded up to 54 bits
  664. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  665. Cstar = P128.w[1];
  666. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  667. fstar.w[0] = P128.w[0];
  668. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  669. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  670. // C* = floor(C*) (logical right shift; C has p decimal digits,
  671. // correct by Property 1)
  672. // n = C* * 10^(e+x)
  673. // shift right C* by Ex-64 = shiftright128[ind]
  674. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  675. Cstar = Cstar >> shift;
  676. // determine inexactness of the rounding of C*
  677. // if (0 < f* < 10^(-x)) then
  678. // the result is exact
  679. // else // if (f* > T*) then
  680. // the result is inexact
  681. if (ind - 1 <= 2) { // fstar.w[1] is 0
  682. if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  683. // ten2mk128trunc[ind -1].w[1] is identical to
  684. // ten2mk128[ind -1].w[1]
  685. if (x_sign) { // negative and inexact
  686. Cstar++;
  687. }
  688. } // else the result is exact
  689. } else { // if 3 <= ind - 1 <= 14
  690. if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  691. // ten2mk128trunc[ind -1].w[1] is identical to
  692. // ten2mk128[ind -1].w[1]
  693. if (x_sign) { // negative and inexact
  694. Cstar++;
  695. }
  696. } // else the result is exact
  697. }
  698. if (x_sign)
  699. res = -Cstar;
  700. else
  701. res = Cstar;
  702. } else if (exp == 0) {
  703. // 1 <= q <= 16
  704. // res = +/-C (exact)
  705. if (x_sign)
  706. res = -C1;
  707. else
  708. res = C1;
  709. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  710. // (the upper limit of 20 on q + exp is due to the fact that
  711. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  712. // res = +/-C * 10^exp (exact)
  713. if (x_sign)
  714. res = -C1 * ten2k64[exp];
  715. else
  716. res = C1 * ten2k64[exp];
  717. }
  718. }
  719. BID_RETURN (res);
  720. }
  721. /*****************************************************************************
  722. * BID64_to_int64_xfloor
  723. ****************************************************************************/
  724. #if DECIMAL_CALL_BY_REFERENCE
  725. void
  726. bid64_to_int64_xfloor (SINT64 * pres, UINT64 * px
  727. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  728. _EXC_INFO_PARAM) {
  729. UINT64 x = *px;
  730. #else
  731. SINT64
  732. bid64_to_int64_xfloor (UINT64 x
  733. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  734. _EXC_INFO_PARAM) {
  735. #endif
  736. SINT64 res;
  737. UINT64 x_sign;
  738. UINT64 x_exp;
  739. int exp; // unbiased exponent
  740. // Note: C1 represents x_significand (UINT64)
  741. BID_UI64DOUBLE tmp1;
  742. unsigned int x_nr_bits;
  743. int q, ind, shift;
  744. UINT64 C1;
  745. UINT128 C;
  746. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  747. UINT128 fstar;
  748. UINT128 P128;
  749. // check for NaN or Infinity
  750. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  751. // set invalid flag
  752. *pfpsf |= INVALID_EXCEPTION;
  753. // return Integer Indefinite
  754. res = 0x8000000000000000ull;
  755. BID_RETURN (res);
  756. }
  757. // unpack x
  758. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  759. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  760. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  761. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  762. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  763. if (C1 > 9999999999999999ull) { // non-canonical
  764. x_exp = 0;
  765. C1 = 0;
  766. }
  767. } else {
  768. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  769. C1 = x & MASK_BINARY_SIG1;
  770. }
  771. // check for zeros (possibly from non-canonical values)
  772. if (C1 == 0x0ull) {
  773. // x is 0
  774. res = 0x0000000000000000ull;
  775. BID_RETURN (res);
  776. }
  777. // x is not special and is not zero
  778. // q = nr. of decimal digits in x (1 <= q <= 54)
  779. // determine first the nr. of bits in x
  780. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  781. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  782. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  783. tmp1.d = (double) (C1 >> 32); // exact conversion
  784. x_nr_bits =
  785. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  786. } else { // x < 2^32
  787. tmp1.d = (double) C1; // exact conversion
  788. x_nr_bits =
  789. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  790. }
  791. } else { // if x < 2^53
  792. tmp1.d = (double) C1; // exact conversion
  793. x_nr_bits =
  794. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  795. }
  796. q = nr_digits[x_nr_bits - 1].digits;
  797. if (q == 0) {
  798. q = nr_digits[x_nr_bits - 1].digits1;
  799. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  800. q++;
  801. }
  802. exp = x_exp - 398; // unbiased exponent
  803. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  804. // set invalid flag
  805. *pfpsf |= INVALID_EXCEPTION;
  806. // return Integer Indefinite
  807. res = 0x8000000000000000ull;
  808. BID_RETURN (res);
  809. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  810. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  811. // so x rounded to an integer may or may not fit in a signed 64-bit int
  812. // the cases that do not fit are identified here; the ones that fit
  813. // fall through and will be handled with other cases further,
  814. // under '1 <= q + exp <= 19'
  815. if (x_sign) { // if n < 0 and q + exp = 19
  816. // if n < -2^63 then n is too large
  817. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63
  818. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  819. // <=> 0.c(0)c(1)...c(q-1) * 10^20 > 0x50000000000000000, 1<=q<=16
  820. // <=> C * 10^(20-q) > 0x50000000000000000, 1<=q<=16
  821. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  822. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  823. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  824. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] != 0)) {
  825. // set invalid flag
  826. *pfpsf |= INVALID_EXCEPTION;
  827. // return Integer Indefinite
  828. res = 0x8000000000000000ull;
  829. BID_RETURN (res);
  830. }
  831. // else cases that can be rounded to a 64-bit int fall through
  832. // to '1 <= q + exp <= 19'
  833. } else { // if n > 0 and q + exp = 19
  834. // if n >= 2^63 then n is too large
  835. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
  836. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  837. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
  838. // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
  839. C.w[1] = 0x0000000000000005ull;
  840. C.w[0] = 0x0000000000000000ull;
  841. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  842. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  843. if (C.w[1] >= 0x05ull) {
  844. // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
  845. // set invalid flag
  846. *pfpsf |= INVALID_EXCEPTION;
  847. // return Integer Indefinite
  848. res = 0x8000000000000000ull;
  849. BID_RETURN (res);
  850. }
  851. // else cases that can be rounded to a 64-bit int fall through
  852. // to '1 <= q + exp <= 19'
  853. } // end else if n > 0 and q + exp = 19
  854. } // end else if ((q + exp) == 19)
  855. // n is not too large to be converted to int64: -2^63 <= n < 2^63
  856. // Note: some of the cases tested for above fall through to this point
  857. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  858. // set inexact flag
  859. *pfpsf |= INEXACT_EXCEPTION;
  860. // return -1 or 0
  861. if (x_sign)
  862. res = 0xffffffffffffffffull;
  863. else
  864. res = 0x0000000000000000ull;
  865. BID_RETURN (res);
  866. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  867. // -2^63 <= x <= -1 or 1 <= x < 2^63 so x can be rounded
  868. // to nearest to a 64-bit signed integer
  869. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  870. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  871. // chop off ind digits from the lower part of C1
  872. // C1 fits in 64 bits
  873. // calculate C* and f*
  874. // C* is actually floor(C*) in this case
  875. // C* and f* need shifting and masking, as shown by
  876. // shiftright128[] and maskhigh128[]
  877. // 1 <= x <= 15
  878. // kx = 10^(-x) = ten2mk64[ind - 1]
  879. // C* = C1 * 10^(-x)
  880. // the approximation of 10^(-x) was rounded up to 54 bits
  881. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  882. Cstar = P128.w[1];
  883. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  884. fstar.w[0] = P128.w[0];
  885. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  886. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  887. // C* = floor(C*) (logical right shift; C has p decimal digits,
  888. // correct by Property 1)
  889. // n = C* * 10^(e+x)
  890. // shift right C* by Ex-64 = shiftright128[ind]
  891. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  892. Cstar = Cstar >> shift;
  893. // determine inexactness of the rounding of C*
  894. // if (0 < f* < 10^(-x)) then
  895. // the result is exact
  896. // else // if (f* > T*) then
  897. // the result is inexact
  898. if (ind - 1 <= 2) { // fstar.w[1] is 0
  899. if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  900. // ten2mk128trunc[ind -1].w[1] is identical to
  901. // ten2mk128[ind -1].w[1]
  902. if (x_sign) { // negative and inexact
  903. Cstar++;
  904. }
  905. // set the inexact flag
  906. *pfpsf |= INEXACT_EXCEPTION;
  907. } // else the result is exact
  908. } else { // if 3 <= ind - 1 <= 14
  909. if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  910. // ten2mk128trunc[ind -1].w[1] is identical to
  911. // ten2mk128[ind -1].w[1]
  912. if (x_sign) { // negative and inexact
  913. Cstar++;
  914. }
  915. // set the inexact flag
  916. *pfpsf |= INEXACT_EXCEPTION;
  917. } // else the result is exact
  918. }
  919. if (x_sign)
  920. res = -Cstar;
  921. else
  922. res = Cstar;
  923. } else if (exp == 0) {
  924. // 1 <= q <= 16
  925. // res = +/-C (exact)
  926. if (x_sign)
  927. res = -C1;
  928. else
  929. res = C1;
  930. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  931. // (the upper limit of 20 on q + exp is due to the fact that
  932. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  933. // res = +/-C * 10^exp (exact)
  934. if (x_sign)
  935. res = -C1 * ten2k64[exp];
  936. else
  937. res = C1 * ten2k64[exp];
  938. }
  939. }
  940. BID_RETURN (res);
  941. }
  942. /*****************************************************************************
  943. * BID64_to_int64_ceil
  944. ****************************************************************************/
  945. #if DECIMAL_CALL_BY_REFERENCE
  946. void
  947. bid64_to_int64_ceil (SINT64 * pres, UINT64 * px
  948. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
  949. {
  950. UINT64 x = *px;
  951. #else
  952. SINT64
  953. bid64_to_int64_ceil (UINT64 x
  954. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
  955. {
  956. #endif
  957. SINT64 res;
  958. UINT64 x_sign;
  959. UINT64 x_exp;
  960. int exp; // unbiased exponent
  961. // Note: C1 represents x_significand (UINT64)
  962. BID_UI64DOUBLE tmp1;
  963. unsigned int x_nr_bits;
  964. int q, ind, shift;
  965. UINT64 C1;
  966. UINT128 C;
  967. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  968. UINT128 fstar;
  969. UINT128 P128;
  970. // check for NaN or Infinity
  971. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  972. // set invalid flag
  973. *pfpsf |= INVALID_EXCEPTION;
  974. // return Integer Indefinite
  975. res = 0x8000000000000000ull;
  976. BID_RETURN (res);
  977. }
  978. // unpack x
  979. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  980. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  981. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  982. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  983. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  984. if (C1 > 9999999999999999ull) { // non-canonical
  985. x_exp = 0;
  986. C1 = 0;
  987. }
  988. } else {
  989. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  990. C1 = x & MASK_BINARY_SIG1;
  991. }
  992. // check for zeros (possibly from non-canonical values)
  993. if (C1 == 0x0ull) {
  994. // x is 0
  995. res = 0x00000000;
  996. BID_RETURN (res);
  997. }
  998. // x is not special and is not zero
  999. // q = nr. of decimal digits in x (1 <= q <= 54)
  1000. // determine first the nr. of bits in x
  1001. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  1002. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1003. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  1004. tmp1.d = (double) (C1 >> 32); // exact conversion
  1005. x_nr_bits =
  1006. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1007. } else { // x < 2^32
  1008. tmp1.d = (double) C1; // exact conversion
  1009. x_nr_bits =
  1010. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1011. }
  1012. } else { // if x < 2^53
  1013. tmp1.d = (double) C1; // exact conversion
  1014. x_nr_bits =
  1015. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1016. }
  1017. q = nr_digits[x_nr_bits - 1].digits;
  1018. if (q == 0) {
  1019. q = nr_digits[x_nr_bits - 1].digits1;
  1020. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  1021. q++;
  1022. }
  1023. exp = x_exp - 398; // unbiased exponent
  1024. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  1025. // set invalid flag
  1026. *pfpsf |= INVALID_EXCEPTION;
  1027. // return Integer Indefinite
  1028. res = 0x8000000000000000ull;
  1029. BID_RETURN (res);
  1030. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  1031. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  1032. // so x rounded to an integer may or may not fit in a signed 64-bit int
  1033. // the cases that do not fit are identified here; the ones that fit
  1034. // fall through and will be handled with other cases further,
  1035. // under '1 <= q + exp <= 19'
  1036. if (x_sign) { // if n < 0 and q + exp = 19
  1037. // if n <= -2^63 - 1 then n is too large
  1038. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
  1039. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
  1040. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
  1041. // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
  1042. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1043. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1044. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  1045. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
  1046. // set invalid flag
  1047. *pfpsf |= INVALID_EXCEPTION;
  1048. // return Integer Indefinite
  1049. res = 0x8000000000000000ull;
  1050. BID_RETURN (res);
  1051. }
  1052. // else cases that can be rounded to a 64-bit int fall through
  1053. // to '1 <= q + exp <= 19'
  1054. } else { // if n > 0 and q + exp = 19
  1055. // if n > 2^63 - 1 then n is too large
  1056. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
  1057. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
  1058. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
  1059. // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
  1060. C.w[1] = 0x0000000000000004ull;
  1061. C.w[0] = 0xfffffffffffffff6ull;
  1062. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1063. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1064. if (C.w[1] > 0x04ull ||
  1065. (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
  1066. // set invalid flag
  1067. *pfpsf |= INVALID_EXCEPTION;
  1068. // return Integer Indefinite
  1069. res = 0x8000000000000000ull;
  1070. BID_RETURN (res);
  1071. }
  1072. // else cases that can be rounded to a 64-bit int fall through
  1073. // to '1 <= q + exp <= 19'
  1074. } // end else if n > 0 and q + exp = 19
  1075. } // end else if ((q + exp) == 19)
  1076. // n is not too large to be converted to int64: -2^63-1 < n < 2^63
  1077. // Note: some of the cases tested for above fall through to this point
  1078. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  1079. // return 0 or 1
  1080. if (x_sign)
  1081. res = 0x00000000;
  1082. else
  1083. res = 0x00000001;
  1084. BID_RETURN (res);
  1085. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  1086. // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
  1087. // to nearest to a 64-bit signed integer
  1088. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  1089. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  1090. // chop off ind digits from the lower part of C1
  1091. // C1 fits in 64 bits
  1092. // calculate C* and f*
  1093. // C* is actually floor(C*) in this case
  1094. // C* and f* need shifting and masking, as shown by
  1095. // shiftright128[] and maskhigh128[]
  1096. // 1 <= x <= 15
  1097. // kx = 10^(-x) = ten2mk64[ind - 1]
  1098. // C* = C1 * 10^(-x)
  1099. // the approximation of 10^(-x) was rounded up to 54 bits
  1100. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  1101. Cstar = P128.w[1];
  1102. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  1103. fstar.w[0] = P128.w[0];
  1104. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  1105. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  1106. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1107. // correct by Property 1)
  1108. // n = C* * 10^(e+x)
  1109. // shift right C* by Ex-64 = shiftright128[ind]
  1110. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  1111. Cstar = Cstar >> shift;
  1112. // determine inexactness of the rounding of C*
  1113. // if (0 < f* < 10^(-x)) then
  1114. // the result is exact
  1115. // else // if (f* > T*) then
  1116. // the result is inexact
  1117. if (ind - 1 <= 2) { // fstar.w[1] is 0
  1118. if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1119. // ten2mk128trunc[ind -1].w[1] is identical to
  1120. // ten2mk128[ind -1].w[1]
  1121. if (!x_sign) { // positive and inexact
  1122. Cstar++;
  1123. }
  1124. } // else the result is exact
  1125. } else { // if 3 <= ind - 1 <= 14
  1126. if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1127. // ten2mk128trunc[ind -1].w[1] is identical to
  1128. // ten2mk128[ind -1].w[1]
  1129. if (!x_sign) { // positive and inexact
  1130. Cstar++;
  1131. }
  1132. } // else the result is exact
  1133. }
  1134. if (x_sign)
  1135. res = -Cstar;
  1136. else
  1137. res = Cstar;
  1138. } else if (exp == 0) {
  1139. // 1 <= q <= 16
  1140. // res = +/-C (exact)
  1141. if (x_sign)
  1142. res = -C1;
  1143. else
  1144. res = C1;
  1145. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  1146. // (the upper limit of 20 on q + exp is due to the fact that
  1147. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  1148. // res = +/-C * 10^exp (exact)
  1149. if (x_sign)
  1150. res = -C1 * ten2k64[exp];
  1151. else
  1152. res = C1 * ten2k64[exp];
  1153. }
  1154. }
  1155. BID_RETURN (res);
  1156. }
  1157. /*****************************************************************************
  1158. * BID64_to_int64_xceil
  1159. ****************************************************************************/
  1160. #if DECIMAL_CALL_BY_REFERENCE
  1161. void
  1162. bid64_to_int64_xceil (SINT64 * pres, UINT64 * px
  1163. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1164. _EXC_INFO_PARAM) {
  1165. UINT64 x = *px;
  1166. #else
  1167. SINT64
  1168. bid64_to_int64_xceil (UINT64 x
  1169. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1170. _EXC_INFO_PARAM) {
  1171. #endif
  1172. SINT64 res;
  1173. UINT64 x_sign;
  1174. UINT64 x_exp;
  1175. int exp; // unbiased exponent
  1176. // Note: C1 represents x_significand (UINT64)
  1177. BID_UI64DOUBLE tmp1;
  1178. unsigned int x_nr_bits;
  1179. int q, ind, shift;
  1180. UINT64 C1;
  1181. UINT128 C;
  1182. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  1183. UINT128 fstar;
  1184. UINT128 P128;
  1185. // check for NaN or Infinity
  1186. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  1187. // set invalid flag
  1188. *pfpsf |= INVALID_EXCEPTION;
  1189. // return Integer Indefinite
  1190. res = 0x8000000000000000ull;
  1191. BID_RETURN (res);
  1192. }
  1193. // unpack x
  1194. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1195. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  1196. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  1197. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  1198. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  1199. if (C1 > 9999999999999999ull) { // non-canonical
  1200. x_exp = 0;
  1201. C1 = 0;
  1202. }
  1203. } else {
  1204. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  1205. C1 = x & MASK_BINARY_SIG1;
  1206. }
  1207. // check for zeros (possibly from non-canonical values)
  1208. if (C1 == 0x0ull) {
  1209. // x is 0
  1210. res = 0x00000000;
  1211. BID_RETURN (res);
  1212. }
  1213. // x is not special and is not zero
  1214. // q = nr. of decimal digits in x (1 <= q <= 54)
  1215. // determine first the nr. of bits in x
  1216. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  1217. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1218. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  1219. tmp1.d = (double) (C1 >> 32); // exact conversion
  1220. x_nr_bits =
  1221. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1222. } else { // x < 2^32
  1223. tmp1.d = (double) C1; // exact conversion
  1224. x_nr_bits =
  1225. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1226. }
  1227. } else { // if x < 2^53
  1228. tmp1.d = (double) C1; // exact conversion
  1229. x_nr_bits =
  1230. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1231. }
  1232. q = nr_digits[x_nr_bits - 1].digits;
  1233. if (q == 0) {
  1234. q = nr_digits[x_nr_bits - 1].digits1;
  1235. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  1236. q++;
  1237. }
  1238. exp = x_exp - 398; // unbiased exponent
  1239. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  1240. // set invalid flag
  1241. *pfpsf |= INVALID_EXCEPTION;
  1242. // return Integer Indefinite
  1243. res = 0x8000000000000000ull;
  1244. BID_RETURN (res);
  1245. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  1246. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  1247. // so x rounded to an integer may or may not fit in a signed 64-bit int
  1248. // the cases that do not fit are identified here; the ones that fit
  1249. // fall through and will be handled with other cases further,
  1250. // under '1 <= q + exp <= 19'
  1251. if (x_sign) { // if n < 0 and q + exp = 19
  1252. // if n <= -2^63 - 1 then n is too large
  1253. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
  1254. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
  1255. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
  1256. // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
  1257. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1258. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1259. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  1260. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
  1261. // set invalid flag
  1262. *pfpsf |= INVALID_EXCEPTION;
  1263. // return Integer Indefinite
  1264. res = 0x8000000000000000ull;
  1265. BID_RETURN (res);
  1266. }
  1267. // else cases that can be rounded to a 64-bit int fall through
  1268. // to '1 <= q + exp <= 19'
  1269. } else { // if n > 0 and q + exp = 19
  1270. // if n > 2^63 - 1 then n is too large
  1271. // too large if c(0)c(1)...c(18).c(19)...c(q-1) > 2^63 - 1
  1272. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 5*(2^64-2), 1<=q<=16
  1273. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 > 0x4fffffffffffffff6, 1<=q<=16
  1274. // <=> if C * 10^(20-q) > 0x4fffffffffffffff6, 1<=q<=16
  1275. C.w[1] = 0x0000000000000004ull;
  1276. C.w[0] = 0xfffffffffffffff6ull;
  1277. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1278. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1279. if (C.w[1] > 0x04ull ||
  1280. (C.w[1] == 0x04ull && C.w[0] > 0xfffffffffffffff6ull)) {
  1281. // set invalid flag
  1282. *pfpsf |= INVALID_EXCEPTION;
  1283. // return Integer Indefinite
  1284. res = 0x8000000000000000ull;
  1285. BID_RETURN (res);
  1286. }
  1287. // else cases that can be rounded to a 64-bit int fall through
  1288. // to '1 <= q + exp <= 19'
  1289. } // end else if n > 0 and q + exp = 19
  1290. } // end else if ((q + exp) == 19)
  1291. // n is not too large to be converted to int64: -2^63-1 < n < 2^63
  1292. // Note: some of the cases tested for above fall through to this point
  1293. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  1294. // set inexact flag
  1295. *pfpsf |= INEXACT_EXCEPTION;
  1296. // return 0 or 1
  1297. if (x_sign)
  1298. res = 0x00000000;
  1299. else
  1300. res = 0x00000001;
  1301. BID_RETURN (res);
  1302. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  1303. // -2^63-1 < x <= -1 or 1 <= x <= 2^63 - 1 so x can be rounded
  1304. // to nearest to a 64-bit signed integer
  1305. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  1306. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  1307. // chop off ind digits from the lower part of C1
  1308. // C1 fits in 64 bits
  1309. // calculate C* and f*
  1310. // C* is actually floor(C*) in this case
  1311. // C* and f* need shifting and masking, as shown by
  1312. // shiftright128[] and maskhigh128[]
  1313. // 1 <= x <= 15
  1314. // kx = 10^(-x) = ten2mk64[ind - 1]
  1315. // C* = C1 * 10^(-x)
  1316. // the approximation of 10^(-x) was rounded up to 54 bits
  1317. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  1318. Cstar = P128.w[1];
  1319. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  1320. fstar.w[0] = P128.w[0];
  1321. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  1322. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  1323. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1324. // correct by Property 1)
  1325. // n = C* * 10^(e+x)
  1326. // shift right C* by Ex-64 = shiftright128[ind]
  1327. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  1328. Cstar = Cstar >> shift;
  1329. // determine inexactness of the rounding of C*
  1330. // if (0 < f* < 10^(-x)) then
  1331. // the result is exact
  1332. // else // if (f* > T*) then
  1333. // the result is inexact
  1334. if (ind - 1 <= 2) { // fstar.w[1] is 0
  1335. if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1336. // ten2mk128trunc[ind -1].w[1] is identical to
  1337. // ten2mk128[ind -1].w[1]
  1338. if (!x_sign) { // positive and inexact
  1339. Cstar++;
  1340. }
  1341. // set the inexact flag
  1342. *pfpsf |= INEXACT_EXCEPTION;
  1343. } // else the result is exact
  1344. } else { // if 3 <= ind - 1 <= 14
  1345. if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1346. // ten2mk128trunc[ind -1].w[1] is identical to
  1347. // ten2mk128[ind -1].w[1]
  1348. if (!x_sign) { // positive and inexact
  1349. Cstar++;
  1350. }
  1351. // set the inexact flag
  1352. *pfpsf |= INEXACT_EXCEPTION;
  1353. } // else the result is exact
  1354. }
  1355. if (x_sign)
  1356. res = -Cstar;
  1357. else
  1358. res = Cstar;
  1359. } else if (exp == 0) {
  1360. // 1 <= q <= 16
  1361. // res = +/-C (exact)
  1362. if (x_sign)
  1363. res = -C1;
  1364. else
  1365. res = C1;
  1366. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  1367. // (the upper limit of 20 on q + exp is due to the fact that
  1368. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  1369. // res = +/-C * 10^exp (exact)
  1370. if (x_sign)
  1371. res = -C1 * ten2k64[exp];
  1372. else
  1373. res = C1 * ten2k64[exp];
  1374. }
  1375. }
  1376. BID_RETURN (res);
  1377. }
  1378. /*****************************************************************************
  1379. * BID64_to_int64_int
  1380. ****************************************************************************/
  1381. #if DECIMAL_CALL_BY_REFERENCE
  1382. void
  1383. bid64_to_int64_int (SINT64 * pres, UINT64 * px
  1384. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  1385. UINT64 x = *px;
  1386. #else
  1387. SINT64
  1388. bid64_to_int64_int (UINT64 x
  1389. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  1390. #endif
  1391. SINT64 res;
  1392. UINT64 x_sign;
  1393. UINT64 x_exp;
  1394. int exp; // unbiased exponent
  1395. // Note: C1 represents x_significand (UINT64)
  1396. BID_UI64DOUBLE tmp1;
  1397. unsigned int x_nr_bits;
  1398. int q, ind, shift;
  1399. UINT64 C1;
  1400. UINT128 C;
  1401. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  1402. UINT128 P128;
  1403. // check for NaN or Infinity
  1404. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  1405. // set invalid flag
  1406. *pfpsf |= INVALID_EXCEPTION;
  1407. // return Integer Indefinite
  1408. res = 0x8000000000000000ull;
  1409. BID_RETURN (res);
  1410. }
  1411. // unpack x
  1412. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1413. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  1414. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  1415. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  1416. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  1417. if (C1 > 9999999999999999ull) { // non-canonical
  1418. x_exp = 0;
  1419. C1 = 0;
  1420. }
  1421. } else {
  1422. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  1423. C1 = x & MASK_BINARY_SIG1;
  1424. }
  1425. // check for zeros (possibly from non-canonical values)
  1426. if (C1 == 0x0ull) {
  1427. // x is 0
  1428. res = 0x00000000;
  1429. BID_RETURN (res);
  1430. }
  1431. // x is not special and is not zero
  1432. // q = nr. of decimal digits in x (1 <= q <= 54)
  1433. // determine first the nr. of bits in x
  1434. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  1435. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1436. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  1437. tmp1.d = (double) (C1 >> 32); // exact conversion
  1438. x_nr_bits =
  1439. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1440. } else { // x < 2^32
  1441. tmp1.d = (double) C1; // exact conversion
  1442. x_nr_bits =
  1443. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1444. }
  1445. } else { // if x < 2^53
  1446. tmp1.d = (double) C1; // exact conversion
  1447. x_nr_bits =
  1448. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1449. }
  1450. q = nr_digits[x_nr_bits - 1].digits;
  1451. if (q == 0) {
  1452. q = nr_digits[x_nr_bits - 1].digits1;
  1453. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  1454. q++;
  1455. }
  1456. exp = x_exp - 398; // unbiased exponent
  1457. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  1458. // set invalid flag
  1459. *pfpsf |= INVALID_EXCEPTION;
  1460. // return Integer Indefinite
  1461. res = 0x8000000000000000ull;
  1462. BID_RETURN (res);
  1463. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  1464. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  1465. // so x rounded to an integer may or may not fit in a signed 64-bit int
  1466. // the cases that do not fit are identified here; the ones that fit
  1467. // fall through and will be handled with other cases further,
  1468. // under '1 <= q + exp <= 19'
  1469. if (x_sign) { // if n < 0 and q + exp = 19
  1470. // if n <= -2^63 - 1 then n is too large
  1471. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
  1472. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
  1473. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
  1474. // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
  1475. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1476. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1477. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  1478. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
  1479. // set invalid flag
  1480. *pfpsf |= INVALID_EXCEPTION;
  1481. // return Integer Indefinite
  1482. res = 0x8000000000000000ull;
  1483. BID_RETURN (res);
  1484. }
  1485. // else cases that can be rounded to a 64-bit int fall through
  1486. // to '1 <= q + exp <= 19'
  1487. } else { // if n > 0 and q + exp = 19
  1488. // if n >= 2^63 then n is too large
  1489. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
  1490. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  1491. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
  1492. // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
  1493. C.w[1] = 0x0000000000000005ull;
  1494. C.w[0] = 0x0000000000000000ull;
  1495. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1496. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1497. if (C.w[1] >= 0x05ull) {
  1498. // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
  1499. // set invalid flag
  1500. *pfpsf |= INVALID_EXCEPTION;
  1501. // return Integer Indefinite
  1502. res = 0x8000000000000000ull;
  1503. BID_RETURN (res);
  1504. }
  1505. // else cases that can be rounded to a 64-bit int fall through
  1506. // to '1 <= q + exp <= 19'
  1507. } // end else if n > 0 and q + exp = 19
  1508. } // end else if ((q + exp) == 19)
  1509. // n is not too large to be converted to int64: -2^63-1 < n < 2^63
  1510. // Note: some of the cases tested for above fall through to this point
  1511. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  1512. // return 0
  1513. res = 0x0000000000000000ull;
  1514. BID_RETURN (res);
  1515. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  1516. // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
  1517. // to nearest to a 64-bit signed integer
  1518. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  1519. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  1520. // chop off ind digits from the lower part of C1
  1521. // C1 fits in 64 bits
  1522. // calculate C* and f*
  1523. // C* is actually floor(C*) in this case
  1524. // C* and f* need shifting and masking, as shown by
  1525. // shiftright128[] and maskhigh128[]
  1526. // 1 <= x <= 15
  1527. // kx = 10^(-x) = ten2mk64[ind - 1]
  1528. // C* = C1 * 10^(-x)
  1529. // the approximation of 10^(-x) was rounded up to 54 bits
  1530. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  1531. Cstar = P128.w[1];
  1532. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  1533. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  1534. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1535. // correct by Property 1)
  1536. // n = C* * 10^(e+x)
  1537. // shift right C* by Ex-64 = shiftright128[ind]
  1538. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  1539. Cstar = Cstar >> shift;
  1540. if (x_sign)
  1541. res = -Cstar;
  1542. else
  1543. res = Cstar;
  1544. } else if (exp == 0) {
  1545. // 1 <= q <= 16
  1546. // res = +/-C (exact)
  1547. if (x_sign)
  1548. res = -C1;
  1549. else
  1550. res = C1;
  1551. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  1552. // (the upper limit of 20 on q + exp is due to the fact that
  1553. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  1554. // res = +/-C * 10^exp (exact)
  1555. if (x_sign)
  1556. res = -C1 * ten2k64[exp];
  1557. else
  1558. res = C1 * ten2k64[exp];
  1559. }
  1560. }
  1561. BID_RETURN (res);
  1562. }
  1563. /*****************************************************************************
  1564. * BID64_to_int64_xint
  1565. ****************************************************************************/
  1566. #if DECIMAL_CALL_BY_REFERENCE
  1567. void
  1568. bid64_to_int64_xint (SINT64 * pres, UINT64 * px
  1569. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
  1570. {
  1571. UINT64 x = *px;
  1572. #else
  1573. SINT64
  1574. bid64_to_int64_xint (UINT64 x
  1575. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
  1576. {
  1577. #endif
  1578. SINT64 res;
  1579. UINT64 x_sign;
  1580. UINT64 x_exp;
  1581. int exp; // unbiased exponent
  1582. // Note: C1 represents x_significand (UINT64)
  1583. BID_UI64DOUBLE tmp1;
  1584. unsigned int x_nr_bits;
  1585. int q, ind, shift;
  1586. UINT64 C1;
  1587. UINT128 C;
  1588. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  1589. UINT128 fstar;
  1590. UINT128 P128;
  1591. // check for NaN or Infinity
  1592. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  1593. // set invalid flag
  1594. *pfpsf |= INVALID_EXCEPTION;
  1595. // return Integer Indefinite
  1596. res = 0x8000000000000000ull;
  1597. BID_RETURN (res);
  1598. }
  1599. // unpack x
  1600. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1601. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  1602. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  1603. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  1604. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  1605. if (C1 > 9999999999999999ull) { // non-canonical
  1606. x_exp = 0;
  1607. C1 = 0;
  1608. }
  1609. } else {
  1610. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  1611. C1 = x & MASK_BINARY_SIG1;
  1612. }
  1613. // check for zeros (possibly from non-canonical values)
  1614. if (C1 == 0x0ull) {
  1615. // x is 0
  1616. res = 0x00000000;
  1617. BID_RETURN (res);
  1618. }
  1619. // x is not special and is not zero
  1620. // q = nr. of decimal digits in x (1 <= q <= 54)
  1621. // determine first the nr. of bits in x
  1622. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  1623. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1624. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  1625. tmp1.d = (double) (C1 >> 32); // exact conversion
  1626. x_nr_bits =
  1627. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1628. } else { // x < 2^32
  1629. tmp1.d = (double) C1; // exact conversion
  1630. x_nr_bits =
  1631. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1632. }
  1633. } else { // if x < 2^53
  1634. tmp1.d = (double) C1; // exact conversion
  1635. x_nr_bits =
  1636. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1637. }
  1638. q = nr_digits[x_nr_bits - 1].digits;
  1639. if (q == 0) {
  1640. q = nr_digits[x_nr_bits - 1].digits1;
  1641. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  1642. q++;
  1643. }
  1644. exp = x_exp - 398; // unbiased exponent
  1645. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  1646. // set invalid flag
  1647. *pfpsf |= INVALID_EXCEPTION;
  1648. // return Integer Indefinite
  1649. res = 0x8000000000000000ull;
  1650. BID_RETURN (res);
  1651. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  1652. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  1653. // so x rounded to an integer may or may not fit in a signed 64-bit int
  1654. // the cases that do not fit are identified here; the ones that fit
  1655. // fall through and will be handled with other cases further,
  1656. // under '1 <= q + exp <= 19'
  1657. if (x_sign) { // if n < 0 and q + exp = 19
  1658. // if n <= -2^63 - 1 then n is too large
  1659. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1
  1660. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+2), 1<=q<=16
  1661. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x5000000000000000a, 1<=q<=16
  1662. // <=> C * 10^(20-q) >= 0x5000000000000000a, 1<=q<=16
  1663. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1664. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1665. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x5000000000000000a, has 20
  1666. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x0aull)) {
  1667. // set invalid flag
  1668. *pfpsf |= INVALID_EXCEPTION;
  1669. // return Integer Indefinite
  1670. res = 0x8000000000000000ull;
  1671. BID_RETURN (res);
  1672. }
  1673. // else cases that can be rounded to a 64-bit int fall through
  1674. // to '1 <= q + exp <= 19'
  1675. } else { // if n > 0 and q + exp = 19
  1676. // if n >= 2^63 then n is too large
  1677. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63
  1678. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*2^64, 1<=q<=16
  1679. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000000, 1<=q<=16
  1680. // <=> if C * 10^(20-q) >= 0x50000000000000000, 1<=q<=16
  1681. C.w[1] = 0x0000000000000005ull;
  1682. C.w[0] = 0x0000000000000000ull;
  1683. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1684. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1685. if (C.w[1] >= 0x05ull) {
  1686. // actually C.w[1] == 0x05ull && C.w[0] >= 0x0000000000000000ull) {
  1687. // set invalid flag
  1688. *pfpsf |= INVALID_EXCEPTION;
  1689. // return Integer Indefinite
  1690. res = 0x8000000000000000ull;
  1691. BID_RETURN (res);
  1692. }
  1693. // else cases that can be rounded to a 64-bit int fall through
  1694. // to '1 <= q + exp <= 19'
  1695. } // end else if n > 0 and q + exp = 19
  1696. } // end else if ((q + exp) == 19)
  1697. // n is not too large to be converted to int64: -2^63-1 < n < 2^63
  1698. // Note: some of the cases tested for above fall through to this point
  1699. if ((q + exp) <= 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  1700. // set inexact flag
  1701. *pfpsf |= INEXACT_EXCEPTION;
  1702. // return 0
  1703. res = 0x0000000000000000ull;
  1704. BID_RETURN (res);
  1705. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  1706. // -2^63-1 < x <= -1 or 1 <= x < 2^63 so x can be rounded
  1707. // to nearest to a 64-bit signed integer
  1708. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  1709. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  1710. // chop off ind digits from the lower part of C1
  1711. // C1 fits in 64 bits
  1712. // calculate C* and f*
  1713. // C* is actually floor(C*) in this case
  1714. // C* and f* need shifting and masking, as shown by
  1715. // shiftright128[] and maskhigh128[]
  1716. // 1 <= x <= 15
  1717. // kx = 10^(-x) = ten2mk64[ind - 1]
  1718. // C* = C1 * 10^(-x)
  1719. // the approximation of 10^(-x) was rounded up to 54 bits
  1720. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  1721. Cstar = P128.w[1];
  1722. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  1723. fstar.w[0] = P128.w[0];
  1724. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  1725. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  1726. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1727. // correct by Property 1)
  1728. // n = C* * 10^(e+x)
  1729. // shift right C* by Ex-64 = shiftright128[ind]
  1730. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  1731. Cstar = Cstar >> shift;
  1732. // determine inexactness of the rounding of C*
  1733. // if (0 < f* < 10^(-x)) then
  1734. // the result is exact
  1735. // else // if (f* > T*) then
  1736. // the result is inexact
  1737. if (ind - 1 <= 2) { // fstar.w[1] is 0
  1738. if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1739. // ten2mk128trunc[ind -1].w[1] is identical to
  1740. // ten2mk128[ind -1].w[1]
  1741. // set the inexact flag
  1742. *pfpsf |= INEXACT_EXCEPTION;
  1743. } // else the result is exact
  1744. } else { // if 3 <= ind - 1 <= 14
  1745. if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  1746. // ten2mk128trunc[ind -1].w[1] is identical to
  1747. // ten2mk128[ind -1].w[1]
  1748. // set the inexact flag
  1749. *pfpsf |= INEXACT_EXCEPTION;
  1750. } // else the result is exact
  1751. }
  1752. if (x_sign)
  1753. res = -Cstar;
  1754. else
  1755. res = Cstar;
  1756. } else if (exp == 0) {
  1757. // 1 <= q <= 16
  1758. // res = +/-C (exact)
  1759. if (x_sign)
  1760. res = -C1;
  1761. else
  1762. res = C1;
  1763. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  1764. // (the upper limit of 20 on q + exp is due to the fact that
  1765. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  1766. // res = +/-C * 10^exp (exact)
  1767. if (x_sign)
  1768. res = -C1 * ten2k64[exp];
  1769. else
  1770. res = C1 * ten2k64[exp];
  1771. }
  1772. }
  1773. BID_RETURN (res);
  1774. }
  1775. /*****************************************************************************
  1776. * BID64_to_int64_rninta
  1777. ****************************************************************************/
  1778. #if DECIMAL_CALL_BY_REFERENCE
  1779. void
  1780. bid64_to_int64_rninta (SINT64 * pres, UINT64 * px
  1781. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1782. _EXC_INFO_PARAM) {
  1783. UINT64 x = *px;
  1784. #else
  1785. SINT64
  1786. bid64_to_int64_rninta (UINT64 x
  1787. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1788. _EXC_INFO_PARAM) {
  1789. #endif
  1790. SINT64 res;
  1791. UINT64 x_sign;
  1792. UINT64 x_exp;
  1793. int exp; // unbiased exponent
  1794. // Note: C1 represents x_significand (UINT64)
  1795. BID_UI64DOUBLE tmp1;
  1796. unsigned int x_nr_bits;
  1797. int q, ind, shift;
  1798. UINT64 C1;
  1799. UINT128 C;
  1800. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  1801. UINT128 P128;
  1802. // check for NaN or Infinity
  1803. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  1804. // set invalid flag
  1805. *pfpsf |= INVALID_EXCEPTION;
  1806. // return Integer Indefinite
  1807. res = 0x8000000000000000ull;
  1808. BID_RETURN (res);
  1809. }
  1810. // unpack x
  1811. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  1812. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  1813. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  1814. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  1815. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  1816. if (C1 > 9999999999999999ull) { // non-canonical
  1817. x_exp = 0;
  1818. C1 = 0;
  1819. }
  1820. } else {
  1821. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  1822. C1 = x & MASK_BINARY_SIG1;
  1823. }
  1824. // check for zeros (possibly from non-canonical values)
  1825. if (C1 == 0x0ull) {
  1826. // x is 0
  1827. res = 0x00000000;
  1828. BID_RETURN (res);
  1829. }
  1830. // x is not special and is not zero
  1831. // q = nr. of decimal digits in x (1 <= q <= 54)
  1832. // determine first the nr. of bits in x
  1833. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  1834. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  1835. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  1836. tmp1.d = (double) (C1 >> 32); // exact conversion
  1837. x_nr_bits =
  1838. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1839. } else { // x < 2^32
  1840. tmp1.d = (double) C1; // exact conversion
  1841. x_nr_bits =
  1842. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1843. }
  1844. } else { // if x < 2^53
  1845. tmp1.d = (double) C1; // exact conversion
  1846. x_nr_bits =
  1847. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  1848. }
  1849. q = nr_digits[x_nr_bits - 1].digits;
  1850. if (q == 0) {
  1851. q = nr_digits[x_nr_bits - 1].digits1;
  1852. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  1853. q++;
  1854. }
  1855. exp = x_exp - 398; // unbiased exponent
  1856. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  1857. // set invalid flag
  1858. *pfpsf |= INVALID_EXCEPTION;
  1859. // return Integer Indefinite
  1860. res = 0x8000000000000000ull;
  1861. BID_RETURN (res);
  1862. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  1863. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  1864. // so x rounded to an integer may or may not fit in a signed 64-bit int
  1865. // the cases that do not fit are identified here; the ones that fit
  1866. // fall through and will be handled with other cases further,
  1867. // under '1 <= q + exp <= 19'
  1868. if (x_sign) { // if n < 0 and q + exp = 19
  1869. // if n <= -2^63 - 1/2 then n is too large
  1870. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
  1871. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
  1872. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
  1873. // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
  1874. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1875. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1876. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
  1877. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
  1878. // set invalid flag
  1879. *pfpsf |= INVALID_EXCEPTION;
  1880. // return Integer Indefinite
  1881. res = 0x8000000000000000ull;
  1882. BID_RETURN (res);
  1883. }
  1884. // else cases that can be rounded to a 64-bit int fall through
  1885. // to '1 <= q + exp <= 19'
  1886. } else { // if n > 0 and q + exp = 19
  1887. // if n >= 2^63 - 1/2 then n is too large
  1888. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
  1889. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
  1890. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
  1891. // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
  1892. C.w[1] = 0x0000000000000004ull;
  1893. C.w[0] = 0xfffffffffffffffbull;
  1894. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  1895. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  1896. if (C.w[1] > 0x04ull ||
  1897. (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
  1898. // set invalid flag
  1899. *pfpsf |= INVALID_EXCEPTION;
  1900. // return Integer Indefinite
  1901. res = 0x8000000000000000ull;
  1902. BID_RETURN (res);
  1903. }
  1904. // else cases that can be rounded to a 64-bit int fall through
  1905. // to '1 <= q + exp <= 19'
  1906. } // end else if n > 0 and q + exp = 19
  1907. } // end else if ((q + exp) == 19)
  1908. // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
  1909. // Note: some of the cases tested for above fall through to this point
  1910. if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  1911. // return 0
  1912. res = 0x0000000000000000ull;
  1913. BID_RETURN (res);
  1914. } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
  1915. // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
  1916. // res = 0
  1917. // else
  1918. // res = +/-1
  1919. ind = q - 1; // 0 <= ind <= 15
  1920. if (C1 < midpoint64[ind]) {
  1921. res = 0x0000000000000000ull; // return 0
  1922. } else if (x_sign) { // n < 0
  1923. res = 0xffffffffffffffffull; // return -1
  1924. } else { // n > 0
  1925. res = 0x0000000000000001ull; // return +1
  1926. }
  1927. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  1928. // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
  1929. // to nearest to a 64-bit signed integer
  1930. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  1931. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  1932. // chop off ind digits from the lower part of C1
  1933. // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
  1934. C1 = C1 + midpoint64[ind - 1];
  1935. // calculate C* and f*
  1936. // C* is actually floor(C*) in this case
  1937. // C* and f* need shifting and masking, as shown by
  1938. // shiftright128[] and maskhigh128[]
  1939. // 1 <= x <= 15
  1940. // kx = 10^(-x) = ten2mk64[ind - 1]
  1941. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  1942. // the approximation of 10^(-x) was rounded up to 54 bits
  1943. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  1944. Cstar = P128.w[1];
  1945. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  1946. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  1947. // if (0 < f* < 10^(-x)) then the result is a midpoint
  1948. // if floor(C*) is even then C* = floor(C*) - logical right
  1949. // shift; C* has p decimal digits, correct by Prop. 1)
  1950. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  1951. // shift; C* has p decimal digits, correct by Pr. 1)
  1952. // else
  1953. // C* = floor(C*) (logical right shift; C has p decimal digits,
  1954. // correct by Property 1)
  1955. // n = C* * 10^(e+x)
  1956. // shift right C* by Ex-64 = shiftright128[ind]
  1957. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  1958. Cstar = Cstar >> shift;
  1959. // if the result was a midpoint it was rounded away from zero
  1960. if (x_sign)
  1961. res = -Cstar;
  1962. else
  1963. res = Cstar;
  1964. } else if (exp == 0) {
  1965. // 1 <= q <= 16
  1966. // res = +/-C (exact)
  1967. if (x_sign)
  1968. res = -C1;
  1969. else
  1970. res = C1;
  1971. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  1972. // (the upper limit of 20 on q + exp is due to the fact that
  1973. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  1974. // res = +/-C * 10^exp (exact)
  1975. if (x_sign)
  1976. res = -C1 * ten2k64[exp];
  1977. else
  1978. res = C1 * ten2k64[exp];
  1979. }
  1980. }
  1981. BID_RETURN (res);
  1982. }
  1983. /*****************************************************************************
  1984. * BID64_to_int64_xrninta
  1985. ****************************************************************************/
  1986. #if DECIMAL_CALL_BY_REFERENCE
  1987. void
  1988. bid64_to_int64_xrninta (SINT64 * pres, UINT64 * px
  1989. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1990. _EXC_INFO_PARAM) {
  1991. UINT64 x = *px;
  1992. #else
  1993. SINT64
  1994. bid64_to_int64_xrninta (UINT64 x
  1995. _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  1996. _EXC_INFO_PARAM) {
  1997. #endif
  1998. SINT64 res;
  1999. UINT64 x_sign;
  2000. UINT64 x_exp;
  2001. int exp; // unbiased exponent
  2002. // Note: C1 represents x_significand (UINT64)
  2003. UINT64 tmp64;
  2004. BID_UI64DOUBLE tmp1;
  2005. unsigned int x_nr_bits;
  2006. int q, ind, shift;
  2007. UINT64 C1;
  2008. UINT128 C;
  2009. UINT64 Cstar; // C* represents up to 16 decimal digits ~ 54 bits
  2010. UINT128 fstar;
  2011. UINT128 P128;
  2012. // check for NaN or Infinity
  2013. if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
  2014. // set invalid flag
  2015. *pfpsf |= INVALID_EXCEPTION;
  2016. // return Integer Indefinite
  2017. res = 0x8000000000000000ull;
  2018. BID_RETURN (res);
  2019. }
  2020. // unpack x
  2021. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  2022. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  2023. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  2024. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  2025. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  2026. if (C1 > 9999999999999999ull) { // non-canonical
  2027. x_exp = 0;
  2028. C1 = 0;
  2029. }
  2030. } else {
  2031. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  2032. C1 = x & MASK_BINARY_SIG1;
  2033. }
  2034. // check for zeros (possibly from non-canonical values)
  2035. if (C1 == 0x0ull) {
  2036. // x is 0
  2037. res = 0x00000000;
  2038. BID_RETURN (res);
  2039. }
  2040. // x is not special and is not zero
  2041. // q = nr. of decimal digits in x (1 <= q <= 54)
  2042. // determine first the nr. of bits in x
  2043. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  2044. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  2045. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  2046. tmp1.d = (double) (C1 >> 32); // exact conversion
  2047. x_nr_bits =
  2048. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  2049. } else { // x < 2^32
  2050. tmp1.d = (double) C1; // exact conversion
  2051. x_nr_bits =
  2052. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  2053. }
  2054. } else { // if x < 2^53
  2055. tmp1.d = (double) C1; // exact conversion
  2056. x_nr_bits =
  2057. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  2058. }
  2059. q = nr_digits[x_nr_bits - 1].digits;
  2060. if (q == 0) {
  2061. q = nr_digits[x_nr_bits - 1].digits1;
  2062. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  2063. q++;
  2064. }
  2065. exp = x_exp - 398; // unbiased exponent
  2066. if ((q + exp) > 19) { // x >= 10^19 ~= 2^63.11... (cannot fit in SINT64)
  2067. // set invalid flag
  2068. *pfpsf |= INVALID_EXCEPTION;
  2069. // return Integer Indefinite
  2070. res = 0x8000000000000000ull;
  2071. BID_RETURN (res);
  2072. } else if ((q + exp) == 19) { // x = c(0)c(1)...c(18).c(19)...c(q-1)
  2073. // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
  2074. // so x rounded to an integer may or may not fit in a signed 64-bit int
  2075. // the cases that do not fit are identified here; the ones that fit
  2076. // fall through and will be handled with other cases further,
  2077. // under '1 <= q + exp <= 19'
  2078. if (x_sign) { // if n < 0 and q + exp = 19
  2079. // if n <= -2^63 - 1/2 then n is too large
  2080. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63+1/2
  2081. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64+1), 1<=q<=16
  2082. // <=> 0.c(0)c(1)...c(q-1) * 10^20 >= 0x50000000000000005, 1<=q<=16
  2083. // <=> C * 10^(20-q) >= 0x50000000000000005, 1<=q<=16
  2084. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  2085. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  2086. // Note: C1 * 10^(11-q) has 19 or 20 digits; 0x50000000000000005, has 20
  2087. if (C.w[1] > 0x05ull || (C.w[1] == 0x05ull && C.w[0] >= 0x05ull)) {
  2088. // set invalid flag
  2089. *pfpsf |= INVALID_EXCEPTION;
  2090. // return Integer Indefinite
  2091. res = 0x8000000000000000ull;
  2092. BID_RETURN (res);
  2093. }
  2094. // else cases that can be rounded to a 64-bit int fall through
  2095. // to '1 <= q + exp <= 19'
  2096. } else { // if n > 0 and q + exp = 19
  2097. // if n >= 2^63 - 1/2 then n is too large
  2098. // too large if c(0)c(1)...c(18).c(19)...c(q-1) >= 2^63-1/2
  2099. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 5*(2^64-1), 1<=q<=16
  2100. // <=> if 0.c(0)c(1)...c(q-1) * 10^20 >= 0x4fffffffffffffffb, 1<=q<=16
  2101. // <=> if C * 10^(20-q) >= 0x4fffffffffffffffb, 1<=q<=16
  2102. C.w[1] = 0x0000000000000004ull;
  2103. C.w[0] = 0xfffffffffffffffbull;
  2104. // 1 <= q <= 16 => 4 <= 20-q <= 19 => 10^(20-q) is 64-bit, and so is C1
  2105. __mul_64x64_to_128MACH (C, C1, ten2k64[20 - q]);
  2106. if (C.w[1] > 0x04ull ||
  2107. (C.w[1] == 0x04ull && C.w[0] >= 0xfffffffffffffffbull)) {
  2108. // set invalid flag
  2109. *pfpsf |= INVALID_EXCEPTION;
  2110. // return Integer Indefinite
  2111. res = 0x8000000000000000ull;
  2112. BID_RETURN (res);
  2113. }
  2114. // else cases that can be rounded to a 64-bit int fall through
  2115. // to '1 <= q + exp <= 19'
  2116. } // end else if n > 0 and q + exp = 19
  2117. } // end else if ((q + exp) == 19)
  2118. // n is not too large to be converted to int64: -2^63-1/2 < n < 2^63-1/2
  2119. // Note: some of the cases tested for above fall through to this point
  2120. if ((q + exp) < 0) { // n = +/-0.0...c(0)c(1)...c(q-1)
  2121. // set inexact flag
  2122. *pfpsf |= INEXACT_EXCEPTION;
  2123. // return 0
  2124. res = 0x0000000000000000ull;
  2125. BID_RETURN (res);
  2126. } else if ((q + exp) == 0) { // n = +/-0.c(0)c(1)...c(q-1)
  2127. // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
  2128. // res = 0
  2129. // else
  2130. // res = +/-1
  2131. ind = q - 1; // 0 <= ind <= 15
  2132. if (C1 < midpoint64[ind]) {
  2133. res = 0x0000000000000000ull; // return 0
  2134. } else if (x_sign) { // n < 0
  2135. res = 0xffffffffffffffffull; // return -1
  2136. } else { // n > 0
  2137. res = 0x0000000000000001ull; // return +1
  2138. }
  2139. // set inexact flag
  2140. *pfpsf |= INEXACT_EXCEPTION;
  2141. } else { // if (1 <= q + exp <= 19, 1 <= q <= 16, -15 <= exp <= 18)
  2142. // -2^63-1/2 < x <= -1 or 1 <= x < 2^63-1/2 so x can be rounded
  2143. // to nearest to a 64-bit signed integer
  2144. if (exp < 0) { // 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 19
  2145. ind = -exp; // 1 <= ind <= 15; ind is a synonym for 'x'
  2146. // chop off ind digits from the lower part of C1
  2147. // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
  2148. C1 = C1 + midpoint64[ind - 1];
  2149. // calculate C* and f*
  2150. // C* is actually floor(C*) in this case
  2151. // C* and f* need shifting and masking, as shown by
  2152. // shiftright128[] and maskhigh128[]
  2153. // 1 <= x <= 15
  2154. // kx = 10^(-x) = ten2mk64[ind - 1]
  2155. // C* = (C1 + 1/2 * 10^x) * 10^(-x)
  2156. // the approximation of 10^(-x) was rounded up to 54 bits
  2157. __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
  2158. Cstar = P128.w[1];
  2159. fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
  2160. fstar.w[0] = P128.w[0];
  2161. // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
  2162. // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
  2163. // if (0 < f* < 10^(-x)) then the result is a midpoint
  2164. // if floor(C*) is even then C* = floor(C*) - logical right
  2165. // shift; C* has p decimal digits, correct by Prop. 1)
  2166. // else if floor(C*) is odd C* = floor(C*)-1 (logical right
  2167. // shift; C* has p decimal digits, correct by Pr. 1)
  2168. // else
  2169. // C* = floor(C*) (logical right shift; C has p decimal digits,
  2170. // correct by Property 1)
  2171. // n = C* * 10^(e+x)
  2172. // shift right C* by Ex-64 = shiftright128[ind]
  2173. shift = shiftright128[ind - 1]; // 0 <= shift <= 39
  2174. Cstar = Cstar >> shift;
  2175. // determine inexactness of the rounding of C*
  2176. // if (0 < f* - 1/2 < 10^(-x)) then
  2177. // the result is exact
  2178. // else // if (f* - 1/2 > T*) then
  2179. // the result is inexact
  2180. if (ind - 1 <= 2) {
  2181. if (fstar.w[0] > 0x8000000000000000ull) {
  2182. // f* > 1/2 and the result may be exact
  2183. tmp64 = fstar.w[0] - 0x8000000000000000ull; // f* - 1/2
  2184. if ((tmp64 > ten2mk128trunc[ind - 1].w[1])) {
  2185. // ten2mk128trunc[ind -1].w[1] is identical to
  2186. // ten2mk128[ind -1].w[1]
  2187. // set the inexact flag
  2188. *pfpsf |= INEXACT_EXCEPTION;
  2189. } // else the result is exact
  2190. } else { // the result is inexact; f2* <= 1/2
  2191. // set the inexact flag
  2192. *pfpsf |= INEXACT_EXCEPTION;
  2193. }
  2194. } else { // if 3 <= ind - 1 <= 14
  2195. if (fstar.w[1] > onehalf128[ind - 1] ||
  2196. (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
  2197. // f2* > 1/2 and the result may be exact
  2198. // Calculate f2* - 1/2
  2199. tmp64 = fstar.w[1] - onehalf128[ind - 1];
  2200. if (tmp64 || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
  2201. // ten2mk128trunc[ind -1].w[1] is identical to
  2202. // ten2mk128[ind -1].w[1]
  2203. // set the inexact flag
  2204. *pfpsf |= INEXACT_EXCEPTION;
  2205. } // else the result is exact
  2206. } else { // the result is inexact; f2* <= 1/2
  2207. // set the inexact flag
  2208. *pfpsf |= INEXACT_EXCEPTION;
  2209. }
  2210. }
  2211. // if the result was a midpoint it was rounded away from zero
  2212. if (x_sign)
  2213. res = -Cstar;
  2214. else
  2215. res = Cstar;
  2216. } else if (exp == 0) {
  2217. // 1 <= q <= 16
  2218. // res = +/-C (exact)
  2219. if (x_sign)
  2220. res = -C1;
  2221. else
  2222. res = C1;
  2223. } else { // if (exp > 0) => 1 <= exp <= 18, 1 <= q <= 16, 2 <= q + exp <= 20
  2224. // (the upper limit of 20 on q + exp is due to the fact that
  2225. // +/-C * 10^exp is guaranteed to fit in 64 bits)
  2226. // res = +/-C * 10^exp (exact)
  2227. if (x_sign)
  2228. res = -C1 * ten2k64[exp];
  2229. else
  2230. res = C1 * ten2k64[exp];
  2231. }
  2232. }
  2233. BID_RETURN (res);
  2234. }