1 1.1 christos /* Common base code for the decNumber C Library. 2 1.6 christos Copyright (C) 2007-2018 Free Software Foundation, Inc. 3 1.1 christos Contributed by IBM Corporation. Author Mike Cowlishaw. 4 1.1 christos 5 1.1 christos This file is part of GCC. 6 1.1 christos 7 1.1 christos GCC is free software; you can redistribute it and/or modify it under 8 1.1 christos the terms of the GNU General Public License as published by the Free 9 1.1 christos Software Foundation; either version 3, or (at your option) any later 10 1.1 christos version. 11 1.1 christos 12 1.1 christos GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 christos WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 1.1 christos FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 1.1 christos for more details. 16 1.1 christos 17 1.1 christos Under Section 7 of GPL version 3, you are granted additional 18 1.1 christos permissions described in the GCC Runtime Library Exception, version 19 1.1 christos 3.1, as published by the Free Software Foundation. 20 1.1 christos 21 1.1 christos You should have received a copy of the GNU General Public License and 22 1.1 christos a copy of the GCC Runtime Library Exception along with this program; 23 1.1 christos see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 christos <http://www.gnu.org/licenses/>. */ 25 1.1 christos 26 1.1 christos /* ------------------------------------------------------------------ */ 27 1.1 christos /* decBasic.c -- common base code for Basic decimal types */ 28 1.1 christos /* ------------------------------------------------------------------ */ 29 1.1 christos /* This module comprises code that is shared between decDouble and */ 30 1.1 christos /* decQuad (but not decSingle). The main arithmetic operations are */ 31 1.1 christos /* here (Add, Subtract, Multiply, FMA, and Division operators). */ 32 1.1 christos /* */ 33 1.1 christos /* Unlike decNumber, parameterization takes place at compile time */ 34 1.1 christos /* rather than at runtime. The parameters are set in the decDouble.c */ 35 1.1 christos /* (etc.) files, which then include this one to produce the compiled */ 36 1.1 christos /* code. The functions here, therefore, are code shared between */ 37 1.1 christos /* multiple formats. */ 38 1.1 christos /* */ 39 1.1 christos /* This must be included after decCommon.c. */ 40 1.1 christos /* ------------------------------------------------------------------ */ 41 1.1 christos /* Names here refer to decFloat rather than to decDouble, etc., and */ 42 1.1 christos /* the functions are in strict alphabetical order. */ 43 1.1 christos 44 1.1 christos /* The compile-time flags SINGLE, DOUBLE, and QUAD are set up in */ 45 1.1 christos /* decCommon.c */ 46 1.1 christos #if !defined(QUAD) 47 1.1 christos #error decBasic.c must be included after decCommon.c 48 1.1 christos #endif 49 1.1 christos #if SINGLE 50 1.1 christos #error Routines in decBasic.c are for decDouble and decQuad only 51 1.1 christos #endif 52 1.1 christos 53 1.1 christos /* Private constants */ 54 1.1 christos #define DIVIDE 0x80000000 /* Divide operations [as flags] */ 55 1.1 christos #define REMAINDER 0x40000000 /* .. */ 56 1.1 christos #define DIVIDEINT 0x20000000 /* .. */ 57 1.1 christos #define REMNEAR 0x10000000 /* .. */ 58 1.1 christos 59 1.1 christos /* Private functions (local, used only by routines in this module) */ 60 1.1 christos static decFloat *decDivide(decFloat *, const decFloat *, 61 1.1 christos const decFloat *, decContext *, uInt); 62 1.1 christos static decFloat *decCanonical(decFloat *, const decFloat *); 63 1.1 christos static void decFiniteMultiply(bcdnum *, uByte *, const decFloat *, 64 1.1 christos const decFloat *); 65 1.1 christos static decFloat *decInfinity(decFloat *, const decFloat *); 66 1.1 christos static decFloat *decInvalid(decFloat *, decContext *); 67 1.1 christos static decFloat *decNaNs(decFloat *, const decFloat *, const decFloat *, 68 1.1 christos decContext *); 69 1.1 christos static Int decNumCompare(const decFloat *, const decFloat *, Flag); 70 1.1 christos static decFloat *decToIntegral(decFloat *, const decFloat *, decContext *, 71 1.1 christos enum rounding, Flag); 72 1.1 christos static uInt decToInt32(const decFloat *, decContext *, enum rounding, 73 1.1 christos Flag, Flag); 74 1.1 christos 75 1.1 christos /* ------------------------------------------------------------------ */ 76 1.1 christos /* decCanonical -- copy a decFloat, making canonical */ 77 1.1 christos /* */ 78 1.1 christos /* result gets the canonicalized df */ 79 1.1 christos /* df is the decFloat to copy and make canonical */ 80 1.1 christos /* returns result */ 81 1.1 christos /* */ 82 1.1 christos /* This is exposed via decFloatCanonical for Double and Quad only. */ 83 1.1 christos /* This works on specials, too; no error or exception is possible. */ 84 1.1 christos /* ------------------------------------------------------------------ */ 85 1.1 christos static decFloat * decCanonical(decFloat *result, const decFloat *df) { 86 1.1 christos uInt encode, precode, dpd; /* work */ 87 1.1 christos uInt inword, uoff, canon; /* .. */ 88 1.1 christos Int n; /* counter (down) */ 89 1.1 christos if (df!=result) *result=*df; /* effect copy if needed */ 90 1.1 christos if (DFISSPECIAL(result)) { 91 1.1 christos if (DFISINF(result)) return decInfinity(result, df); /* clean Infinity */ 92 1.1 christos /* is a NaN */ 93 1.1 christos DFWORD(result, 0)&=~ECONNANMASK; /* clear ECON except selector */ 94 1.1 christos if (DFISCCZERO(df)) return result; /* coefficient continuation is 0 */ 95 1.1 christos /* drop through to check payload */ 96 1.1 christos } 97 1.1 christos /* return quickly if the coefficient continuation is canonical */ 98 1.1 christos { /* declare block */ 99 1.1 christos #if DOUBLE 100 1.1 christos uInt sourhi=DFWORD(df, 0); 101 1.1 christos uInt sourlo=DFWORD(df, 1); 102 1.1 christos if (CANONDPDOFF(sourhi, 8) 103 1.1 christos && CANONDPDTWO(sourhi, sourlo, 30) 104 1.1 christos && CANONDPDOFF(sourlo, 20) 105 1.1 christos && CANONDPDOFF(sourlo, 10) 106 1.1 christos && CANONDPDOFF(sourlo, 0)) return result; 107 1.1 christos #elif QUAD 108 1.1 christos uInt sourhi=DFWORD(df, 0); 109 1.1 christos uInt sourmh=DFWORD(df, 1); 110 1.1 christos uInt sourml=DFWORD(df, 2); 111 1.1 christos uInt sourlo=DFWORD(df, 3); 112 1.1 christos if (CANONDPDOFF(sourhi, 4) 113 1.1 christos && CANONDPDTWO(sourhi, sourmh, 26) 114 1.1 christos && CANONDPDOFF(sourmh, 16) 115 1.1 christos && CANONDPDOFF(sourmh, 6) 116 1.1 christos && CANONDPDTWO(sourmh, sourml, 28) 117 1.1 christos && CANONDPDOFF(sourml, 18) 118 1.1 christos && CANONDPDOFF(sourml, 8) 119 1.1 christos && CANONDPDTWO(sourml, sourlo, 30) 120 1.1 christos && CANONDPDOFF(sourlo, 20) 121 1.1 christos && CANONDPDOFF(sourlo, 10) 122 1.1 christos && CANONDPDOFF(sourlo, 0)) return result; 123 1.1 christos #endif 124 1.1 christos } /* block */ 125 1.1 christos 126 1.1 christos /* Loop to repair a non-canonical coefficent, as needed */ 127 1.1 christos inword=DECWORDS-1; /* current input word */ 128 1.1 christos uoff=0; /* bit offset of declet */ 129 1.1 christos encode=DFWORD(result, inword); 130 1.1 christos for (n=DECLETS-1; n>=0; n--) { /* count down declets of 10 bits */ 131 1.1 christos dpd=encode>>uoff; 132 1.1 christos uoff+=10; 133 1.1 christos if (uoff>32) { /* crossed uInt boundary */ 134 1.1 christos inword--; 135 1.1 christos encode=DFWORD(result, inword); 136 1.1 christos uoff-=32; 137 1.1 christos dpd|=encode<<(10-uoff); /* get pending bits */ 138 1.1 christos } 139 1.1 christos dpd&=0x3ff; /* clear uninteresting bits */ 140 1.1 christos if (dpd<0x16e) continue; /* must be canonical */ 141 1.1 christos canon=BIN2DPD[DPD2BIN[dpd]]; /* determine canonical declet */ 142 1.1 christos if (canon==dpd) continue; /* have canonical declet */ 143 1.1 christos /* need to replace declet */ 144 1.1 christos if (uoff>=10) { /* all within current word */ 145 1.1 christos encode&=~(0x3ff<<(uoff-10)); /* clear the 10 bits ready for replace */ 146 1.1 christos encode|=canon<<(uoff-10); /* insert the canonical form */ 147 1.1 christos DFWORD(result, inword)=encode; /* .. and save */ 148 1.1 christos continue; 149 1.1 christos } 150 1.1 christos /* straddled words */ 151 1.1 christos precode=DFWORD(result, inword+1); /* get previous */ 152 1.1 christos precode&=0xffffffff>>(10-uoff); /* clear top bits */ 153 1.1 christos DFWORD(result, inword+1)=precode|(canon<<(32-(10-uoff))); 154 1.1 christos encode&=0xffffffff<<uoff; /* clear bottom bits */ 155 1.1 christos encode|=canon>>(10-uoff); /* insert canonical */ 156 1.1 christos DFWORD(result, inword)=encode; /* .. and save */ 157 1.1 christos } /* n */ 158 1.1 christos return result; 159 1.1 christos } /* decCanonical */ 160 1.1 christos 161 1.1 christos /* ------------------------------------------------------------------ */ 162 1.1 christos /* decDivide -- divide operations */ 163 1.1 christos /* */ 164 1.1 christos /* result gets the result of dividing dfl by dfr: */ 165 1.1 christos /* dfl is the first decFloat (lhs) */ 166 1.1 christos /* dfr is the second decFloat (rhs) */ 167 1.1 christos /* set is the context */ 168 1.1 christos /* op is the operation selector */ 169 1.1 christos /* returns result */ 170 1.1 christos /* */ 171 1.1 christos /* op is one of DIVIDE, REMAINDER, DIVIDEINT, or REMNEAR. */ 172 1.1 christos /* ------------------------------------------------------------------ */ 173 1.1 christos #define DIVCOUNT 0 /* 1 to instrument subtractions counter */ 174 1.1 christos #define DIVBASE ((uInt)BILLION) /* the base used for divide */ 175 1.1 christos #define DIVOPLEN DECPMAX9 /* operand length ('digits' base 10**9) */ 176 1.1 christos #define DIVACCLEN (DIVOPLEN*3) /* accumulator length (ditto) */ 177 1.1 christos static decFloat * decDivide(decFloat *result, const decFloat *dfl, 178 1.1 christos const decFloat *dfr, decContext *set, uInt op) { 179 1.1 christos decFloat quotient; /* for remainders */ 180 1.1 christos bcdnum num; /* for final conversion */ 181 1.1 christos uInt acc[DIVACCLEN]; /* coefficent in base-billion .. */ 182 1.1 christos uInt div[DIVOPLEN]; /* divisor in base-billion .. */ 183 1.1 christos uInt quo[DIVOPLEN+1]; /* quotient in base-billion .. */ 184 1.1 christos uByte bcdacc[(DIVOPLEN+1)*9+2]; /* for quotient in BCD, +1, +1 */ 185 1.1 christos uInt *msua, *msud, *msuq; /* -> msu of acc, div, and quo */ 186 1.1 christos Int divunits, accunits; /* lengths */ 187 1.1 christos Int quodigits; /* digits in quotient */ 188 1.1 christos uInt *lsua, *lsuq; /* -> current acc and quo lsus */ 189 1.1 christos Int length, multiplier; /* work */ 190 1.1 christos uInt carry, sign; /* .. */ 191 1.1 christos uInt *ua, *ud, *uq; /* .. */ 192 1.1 christos uByte *ub; /* .. */ 193 1.1 christos uInt uiwork; /* for macros */ 194 1.1 christos uInt divtop; /* top unit of div adjusted for estimating */ 195 1.1 christos #if DIVCOUNT 196 1.1 christos static uInt maxcount=0; /* worst-seen subtractions count */ 197 1.1 christos uInt divcount=0; /* subtractions count [this divide] */ 198 1.1 christos #endif 199 1.1 christos 200 1.1 christos /* calculate sign */ 201 1.1 christos num.sign=(DFWORD(dfl, 0)^DFWORD(dfr, 0)) & DECFLOAT_Sign; 202 1.1 christos 203 1.1 christos if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr)) { /* either is special? */ 204 1.1 christos /* NaNs are handled as usual */ 205 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 206 1.1 christos /* one or two infinities */ 207 1.1 christos if (DFISINF(dfl)) { 208 1.1 christos if (DFISINF(dfr)) return decInvalid(result, set); /* Two infinities bad */ 209 1.1 christos if (op&(REMAINDER|REMNEAR)) return decInvalid(result, set); /* as is rem */ 210 1.1 christos /* Infinity/x is infinite and quiet, even if x=0 */ 211 1.1 christos DFWORD(result, 0)=num.sign; 212 1.1 christos return decInfinity(result, result); 213 1.1 christos } 214 1.1 christos /* must be x/Infinity -- remainders are lhs */ 215 1.1 christos if (op&(REMAINDER|REMNEAR)) return decCanonical(result, dfl); 216 1.1 christos /* divides: return zero with correct sign and exponent depending */ 217 1.1 christos /* on op (Etiny for divide, 0 for divideInt) */ 218 1.1 christos decFloatZero(result); 219 1.1 christos if (op==DIVIDEINT) DFWORD(result, 0)|=num.sign; /* add sign */ 220 1.1 christos else DFWORD(result, 0)=num.sign; /* zeros the exponent, too */ 221 1.1 christos return result; 222 1.1 christos } 223 1.1 christos /* next, handle zero operands (x/0 and 0/x) */ 224 1.1 christos if (DFISZERO(dfr)) { /* x/0 */ 225 1.1 christos if (DFISZERO(dfl)) { /* 0/0 is undefined */ 226 1.1 christos decFloatZero(result); 227 1.1 christos DFWORD(result, 0)=DECFLOAT_qNaN; 228 1.1 christos set->status|=DEC_Division_undefined; 229 1.1 christos return result; 230 1.1 christos } 231 1.1 christos if (op&(REMAINDER|REMNEAR)) return decInvalid(result, set); /* bad rem */ 232 1.1 christos set->status|=DEC_Division_by_zero; 233 1.1 christos DFWORD(result, 0)=num.sign; 234 1.1 christos return decInfinity(result, result); /* x/0 -> signed Infinity */ 235 1.1 christos } 236 1.1 christos num.exponent=GETEXPUN(dfl)-GETEXPUN(dfr); /* ideal exponent */ 237 1.1 christos if (DFISZERO(dfl)) { /* 0/x (x!=0) */ 238 1.1 christos /* if divide, result is 0 with ideal exponent; divideInt has */ 239 1.1 christos /* exponent=0, remainders give zero with lower exponent */ 240 1.1 christos if (op&DIVIDEINT) { 241 1.1 christos decFloatZero(result); 242 1.1 christos DFWORD(result, 0)|=num.sign; /* add sign */ 243 1.1 christos return result; 244 1.1 christos } 245 1.1 christos if (!(op&DIVIDE)) { /* a remainder */ 246 1.1 christos /* exponent is the minimum of the operands */ 247 1.1 christos num.exponent=MINI(GETEXPUN(dfl), GETEXPUN(dfr)); 248 1.1 christos /* if the result is zero the sign shall be sign of dfl */ 249 1.1 christos num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; 250 1.1 christos } 251 1.1 christos bcdacc[0]=0; 252 1.1 christos num.msd=bcdacc; /* -> 0 */ 253 1.1 christos num.lsd=bcdacc; /* .. */ 254 1.1 christos return decFinalize(result, &num, set); /* [divide may clamp exponent] */ 255 1.1 christos } /* 0/x */ 256 1.1 christos /* [here, both operands are known to be finite and non-zero] */ 257 1.1 christos 258 1.1 christos /* extract the operand coefficents into 'units' which are */ 259 1.1 christos /* base-billion; the lhs is high-aligned in acc and the msu of both */ 260 1.1 christos /* acc and div is at the right-hand end of array (offset length-1); */ 261 1.1 christos /* the quotient can need one more unit than the operands as digits */ 262 1.1 christos /* in it are not necessarily aligned neatly; further, the quotient */ 263 1.1 christos /* may not start accumulating until after the end of the initial */ 264 1.1 christos /* operand in acc if that is small (e.g., 1) so the accumulator */ 265 1.1 christos /* must have at least that number of units extra (at the ls end) */ 266 1.1 christos GETCOEFFBILL(dfl, acc+DIVACCLEN-DIVOPLEN); 267 1.1 christos GETCOEFFBILL(dfr, div); 268 1.1 christos /* zero the low uInts of acc */ 269 1.1 christos acc[0]=0; 270 1.1 christos acc[1]=0; 271 1.1 christos acc[2]=0; 272 1.1 christos acc[3]=0; 273 1.1 christos #if DOUBLE 274 1.1 christos #if DIVOPLEN!=2 275 1.1 christos #error Unexpected Double DIVOPLEN 276 1.1 christos #endif 277 1.1 christos #elif QUAD 278 1.1 christos acc[4]=0; 279 1.1 christos acc[5]=0; 280 1.1 christos acc[6]=0; 281 1.1 christos acc[7]=0; 282 1.1 christos #if DIVOPLEN!=4 283 1.1 christos #error Unexpected Quad DIVOPLEN 284 1.1 christos #endif 285 1.1 christos #endif 286 1.1 christos 287 1.1 christos /* set msu and lsu pointers */ 288 1.1 christos msua=acc+DIVACCLEN-1; /* [leading zeros removed below] */ 289 1.1 christos msuq=quo+DIVOPLEN; 290 1.1 christos /*[loop for div will terminate because operands are non-zero] */ 291 1.1 christos for (msud=div+DIVOPLEN-1; *msud==0;) msud--; 292 1.1 christos /* the initial least-significant unit of acc is set so acc appears */ 293 1.1 christos /* to have the same length as div. */ 294 1.1 christos /* This moves one position towards the least possible for each */ 295 1.1 christos /* iteration */ 296 1.1 christos divunits=(Int)(msud-div+1); /* precalculate */ 297 1.1 christos lsua=msua-divunits+1; /* initial working lsu of acc */ 298 1.1 christos lsuq=msuq; /* and of quo */ 299 1.1 christos 300 1.1 christos /* set up the estimator for the multiplier; this is the msu of div, */ 301 1.1 christos /* plus two bits from the unit below (if any) rounded up by one if */ 302 1.1 christos /* there are any non-zero bits or units below that [the extra two */ 303 1.1 christos /* bits makes for a much better estimate when the top unit is small] */ 304 1.1 christos divtop=*msud<<2; 305 1.1 christos if (divunits>1) { 306 1.1 christos uInt *um=msud-1; 307 1.1 christos uInt d=*um; 308 1.1 christos if (d>=750000000) {divtop+=3; d-=750000000;} 309 1.1 christos else if (d>=500000000) {divtop+=2; d-=500000000;} 310 1.1 christos else if (d>=250000000) {divtop++; d-=250000000;} 311 1.1 christos if (d) divtop++; 312 1.1 christos else for (um--; um>=div; um--) if (*um) { 313 1.1 christos divtop++; 314 1.1 christos break; 315 1.1 christos } 316 1.1 christos } /* >1 unit */ 317 1.1 christos 318 1.1 christos #if DECTRACE 319 1.1 christos {Int i; 320 1.1 christos printf("----- div="); 321 1.1 christos for (i=divunits-1; i>=0; i--) printf("%09ld ", (LI)div[i]); 322 1.1 christos printf("\n");} 323 1.1 christos #endif 324 1.1 christos 325 1.1 christos /* now collect up to DECPMAX+1 digits in the quotient (this may */ 326 1.1 christos /* need OPLEN+1 uInts if unaligned) */ 327 1.1 christos quodigits=0; /* no digits yet */ 328 1.1 christos for (;; lsua--) { /* outer loop -- each input position */ 329 1.1 christos #if DECCHECK 330 1.1 christos if (lsua<acc) { 331 1.1 christos printf("Acc underrun...\n"); 332 1.1 christos break; 333 1.1 christos } 334 1.1 christos #endif 335 1.1 christos #if DECTRACE 336 1.1 christos printf("Outer: quodigits=%ld acc=", (LI)quodigits); 337 1.1 christos for (ua=msua; ua>=lsua; ua--) printf("%09ld ", (LI)*ua); 338 1.1 christos printf("\n"); 339 1.1 christos #endif 340 1.1 christos *lsuq=0; /* default unit result is 0 */ 341 1.1 christos for (;;) { /* inner loop -- calculate quotient unit */ 342 1.1 christos /* strip leading zero units from acc (either there initially or */ 343 1.1 christos /* from subtraction below); this may strip all if exactly 0 */ 344 1.1 christos for (; *msua==0 && msua>=lsua;) msua--; 345 1.1 christos accunits=(Int)(msua-lsua+1); /* [maybe 0] */ 346 1.1 christos /* subtraction is only necessary and possible if there are as */ 347 1.1 christos /* least as many units remaining in acc for this iteration as */ 348 1.1 christos /* there are in div */ 349 1.1 christos if (accunits<divunits) { 350 1.1 christos if (accunits==0) msua++; /* restore */ 351 1.1 christos break; 352 1.1 christos } 353 1.1 christos 354 1.1 christos /* If acc is longer than div then subtraction is definitely */ 355 1.1 christos /* possible (as msu of both is non-zero), but if they are the */ 356 1.1 christos /* same length a comparison is needed. */ 357 1.1 christos /* If a subtraction is needed then a good estimate of the */ 358 1.1 christos /* multiplier for the subtraction is also needed in order to */ 359 1.1 christos /* minimise the iterations of this inner loop because the */ 360 1.1 christos /* subtractions needed dominate division performance. */ 361 1.1 christos if (accunits==divunits) { 362 1.1 christos /* compare the high divunits of acc and div: */ 363 1.1 christos /* acc<div: this quotient unit is unchanged; subtraction */ 364 1.1 christos /* will be possible on the next iteration */ 365 1.1 christos /* acc==div: quotient gains 1, set acc=0 */ 366 1.1 christos /* acc>div: subtraction necessary at this position */ 367 1.1 christos for (ud=msud, ua=msua; ud>div; ud--, ua--) if (*ud!=*ua) break; 368 1.1 christos /* [now at first mismatch or lsu] */ 369 1.1 christos if (*ud>*ua) break; /* next time... */ 370 1.1 christos if (*ud==*ua) { /* all compared equal */ 371 1.1 christos *lsuq+=1; /* increment result */ 372 1.1 christos msua=lsua; /* collapse acc units */ 373 1.1 christos *msua=0; /* .. to a zero */ 374 1.1 christos break; 375 1.1 christos } 376 1.1 christos 377 1.1 christos /* subtraction necessary; estimate multiplier [see above] */ 378 1.1 christos /* if both *msud and *msua are small it is cost-effective to */ 379 1.1 christos /* bring in part of the following units (if any) to get a */ 380 1.1 christos /* better estimate (assume some other non-zero in div) */ 381 1.1 christos #define DIVLO 1000000U 382 1.1 christos #define DIVHI (DIVBASE/DIVLO) 383 1.1 christos #if DECUSE64 384 1.1 christos if (divunits>1) { 385 1.1 christos /* there cannot be a *(msud-2) for DECDOUBLE so next is */ 386 1.1 christos /* an exact calculation unless DECQUAD (which needs to */ 387 1.1 christos /* assume bits out there if divunits>2) */ 388 1.1 christos uLong mul=(uLong)*msua * DIVBASE + *(msua-1); 389 1.1 christos uLong div=(uLong)*msud * DIVBASE + *(msud-1); 390 1.1 christos #if QUAD 391 1.1 christos if (divunits>2) div++; 392 1.1 christos #endif 393 1.1 christos mul/=div; 394 1.1 christos multiplier=(Int)mul; 395 1.1 christos } 396 1.1 christos else multiplier=*msua/(*msud); 397 1.1 christos #else 398 1.1 christos if (divunits>1 && *msua<DIVLO && *msud<DIVLO) { 399 1.1 christos multiplier=(*msua*DIVHI + *(msua-1)/DIVLO) 400 1.1 christos /(*msud*DIVHI + *(msud-1)/DIVLO +1); 401 1.1 christos } 402 1.1 christos else multiplier=(*msua<<2)/divtop; 403 1.1 christos #endif 404 1.1 christos } 405 1.1 christos else { /* accunits>divunits */ 406 1.1 christos /* msud is one unit 'lower' than msua, so estimate differently */ 407 1.1 christos #if DECUSE64 408 1.1 christos uLong mul; 409 1.1 christos /* as before, bring in extra digits if possible */ 410 1.1 christos if (divunits>1 && *msua<DIVLO && *msud<DIVLO) { 411 1.1 christos mul=((uLong)*msua * DIVHI * DIVBASE) + *(msua-1) * DIVHI 412 1.1 christos + *(msua-2)/DIVLO; 413 1.1 christos mul/=(*msud*DIVHI + *(msud-1)/DIVLO +1); 414 1.1 christos } 415 1.1 christos else if (divunits==1) { 416 1.1 christos mul=(uLong)*msua * DIVBASE + *(msua-1); 417 1.1 christos mul/=*msud; /* no more to the right */ 418 1.1 christos } 419 1.1 christos else { 420 1.1 christos mul=(uLong)(*msua) * (uInt)(DIVBASE<<2) 421 1.1 christos + (*(msua-1)<<2); 422 1.1 christos mul/=divtop; /* [divtop already allows for sticky bits] */ 423 1.1 christos } 424 1.1 christos multiplier=(Int)mul; 425 1.1 christos #else 426 1.1 christos multiplier=*msua * ((DIVBASE<<2)/divtop); 427 1.1 christos #endif 428 1.1 christos } 429 1.1 christos if (multiplier==0) multiplier=1; /* marginal case */ 430 1.1 christos *lsuq+=multiplier; 431 1.1 christos 432 1.1 christos #if DIVCOUNT 433 1.1 christos /* printf("Multiplier: %ld\n", (LI)multiplier); */ 434 1.1 christos divcount++; 435 1.1 christos #endif 436 1.1 christos 437 1.1 christos /* Carry out the subtraction acc-(div*multiplier); for each */ 438 1.1 christos /* unit in div, do the multiply, split to units (see */ 439 1.1 christos /* decFloatMultiply for the algorithm), and subtract from acc */ 440 1.1 christos #define DIVMAGIC 2305843009U /* 2**61/10**9 */ 441 1.1 christos #define DIVSHIFTA 29 442 1.1 christos #define DIVSHIFTB 32 443 1.1 christos carry=0; 444 1.1 christos for (ud=div, ua=lsua; ud<=msud; ud++, ua++) { 445 1.1 christos uInt lo, hop; 446 1.1 christos #if DECUSE64 447 1.1 christos uLong sub=(uLong)multiplier*(*ud)+carry; 448 1.1 christos if (sub<DIVBASE) { 449 1.1 christos carry=0; 450 1.1 christos lo=(uInt)sub; 451 1.1 christos } 452 1.1 christos else { 453 1.1 christos hop=(uInt)(sub>>DIVSHIFTA); 454 1.1 christos carry=(uInt)(((uLong)hop*DIVMAGIC)>>DIVSHIFTB); 455 1.1 christos /* the estimate is now in hi; now calculate sub-hi*10**9 */ 456 1.1 christos /* to get the remainder (which will be <DIVBASE)) */ 457 1.1 christos lo=(uInt)sub; 458 1.1 christos lo-=carry*DIVBASE; /* low word of result */ 459 1.1 christos if (lo>=DIVBASE) { 460 1.1 christos lo-=DIVBASE; /* correct by +1 */ 461 1.1 christos carry++; 462 1.1 christos } 463 1.1 christos } 464 1.1 christos #else /* 32-bit */ 465 1.1 christos uInt hi; 466 1.1 christos /* calculate multiplier*(*ud) into hi and lo */ 467 1.1 christos LONGMUL32HI(hi, *ud, multiplier); /* get the high word */ 468 1.1 christos lo=multiplier*(*ud); /* .. and the low */ 469 1.1 christos lo+=carry; /* add the old hi */ 470 1.1 christos carry=hi+(lo<carry); /* .. with any carry */ 471 1.1 christos if (carry || lo>=DIVBASE) { /* split is needed */ 472 1.1 christos hop=(carry<<3)+(lo>>DIVSHIFTA); /* hi:lo/2**29 */ 473 1.1 christos LONGMUL32HI(carry, hop, DIVMAGIC); /* only need the high word */ 474 1.1 christos /* [DIVSHIFTB is 32, so carry can be used directly] */ 475 1.1 christos /* the estimate is now in carry; now calculate hi:lo-est*10**9; */ 476 1.1 christos /* happily the top word of the result is irrelevant because it */ 477 1.1 christos /* will always be zero so this needs only one multiplication */ 478 1.1 christos lo-=(carry*DIVBASE); 479 1.1 christos /* the correction here will be at most +1; do it */ 480 1.1 christos if (lo>=DIVBASE) { 481 1.1 christos lo-=DIVBASE; 482 1.1 christos carry++; 483 1.1 christos } 484 1.1 christos } 485 1.1 christos #endif 486 1.1 christos if (lo>*ua) { /* borrow needed */ 487 1.1 christos *ua+=DIVBASE; 488 1.1 christos carry++; 489 1.1 christos } 490 1.1 christos *ua-=lo; 491 1.1 christos } /* ud loop */ 492 1.1 christos if (carry) *ua-=carry; /* accdigits>divdigits [cannot borrow] */ 493 1.1 christos } /* inner loop */ 494 1.1 christos 495 1.1 christos /* the outer loop terminates when there is either an exact result */ 496 1.1 christos /* or enough digits; first update the quotient digit count and */ 497 1.1 christos /* pointer (if any significant digits) */ 498 1.1 christos #if DECTRACE 499 1.1 christos if (*lsuq || quodigits) printf("*lsuq=%09ld\n", (LI)*lsuq); 500 1.1 christos #endif 501 1.1 christos if (quodigits) { 502 1.1 christos quodigits+=9; /* had leading unit earlier */ 503 1.1 christos lsuq--; 504 1.1 christos if (quodigits>DECPMAX+1) break; /* have enough */ 505 1.1 christos } 506 1.1 christos else if (*lsuq) { /* first quotient digits */ 507 1.1 christos const uInt *pow; 508 1.1 christos for (pow=DECPOWERS; *lsuq>=*pow; pow++) quodigits++; 509 1.1 christos lsuq--; 510 1.1 christos /* [cannot have >DECPMAX+1 on first unit] */ 511 1.1 christos } 512 1.1 christos 513 1.1 christos if (*msua!=0) continue; /* not an exact result */ 514 1.1 christos /* acc is zero iff used all of original units and zero down to lsua */ 515 1.1 christos /* (must also continue to original lsu for correct quotient length) */ 516 1.1 christos if (lsua>acc+DIVACCLEN-DIVOPLEN) continue; 517 1.1 christos for (; msua>lsua && *msua==0;) msua--; 518 1.1 christos if (*msua==0 && msua==lsua) break; 519 1.1 christos } /* outer loop */ 520 1.1 christos 521 1.1 christos /* all of the original operand in acc has been covered at this point */ 522 1.1 christos /* quotient now has at least DECPMAX+2 digits */ 523 1.1 christos /* *msua is now non-0 if inexact and sticky bits */ 524 1.1 christos /* lsuq is one below the last uint of the quotient */ 525 1.1 christos lsuq++; /* set -> true lsu of quo */ 526 1.1 christos if (*msua) *lsuq|=1; /* apply sticky bit */ 527 1.1 christos 528 1.1 christos /* quo now holds the (unrounded) quotient in base-billion; one */ 529 1.1 christos /* base-billion 'digit' per uInt. */ 530 1.1 christos #if DECTRACE 531 1.1 christos printf("DivQuo:"); 532 1.1 christos for (uq=msuq; uq>=lsuq; uq--) printf(" %09ld", (LI)*uq); 533 1.1 christos printf("\n"); 534 1.1 christos #endif 535 1.1 christos 536 1.1 christos /* Now convert to BCD for rounding and cleanup, starting from the */ 537 1.1 christos /* most significant end [offset by one into bcdacc to leave room */ 538 1.1 christos /* for a possible carry digit if rounding for REMNEAR is needed] */ 539 1.1 christos for (uq=msuq, ub=bcdacc+1; uq>=lsuq; uq--, ub+=9) { 540 1.1 christos uInt top, mid, rem; /* work */ 541 1.1 christos if (*uq==0) { /* no split needed */ 542 1.1 christos UBFROMUI(ub, 0); /* clear 9 BCD8s */ 543 1.1 christos UBFROMUI(ub+4, 0); /* .. */ 544 1.1 christos *(ub+8)=0; /* .. */ 545 1.1 christos continue; 546 1.1 christos } 547 1.1 christos /* *uq is non-zero -- split the base-billion digit into */ 548 1.1 christos /* hi, mid, and low three-digits */ 549 1.1 christos #define divsplit9 1000000 /* divisor */ 550 1.1 christos #define divsplit6 1000 /* divisor */ 551 1.1 christos /* The splitting is done by simple divides and remainders, */ 552 1.1 christos /* assuming the compiler will optimize these [GCC does] */ 553 1.1 christos top=*uq/divsplit9; 554 1.1 christos rem=*uq%divsplit9; 555 1.1 christos mid=rem/divsplit6; 556 1.1 christos rem=rem%divsplit6; 557 1.1 christos /* lay out the nine BCD digits (plus one unwanted byte) */ 558 1.1 christos UBFROMUI(ub, UBTOUI(&BIN2BCD8[top*4])); 559 1.1 christos UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4])); 560 1.1 christos UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4])); 561 1.1 christos } /* BCD conversion loop */ 562 1.1 christos ub--; /* -> lsu */ 563 1.1 christos 564 1.1 christos /* complete the bcdnum; quodigits is correct, so the position of */ 565 1.1 christos /* the first non-zero is known */ 566 1.1 christos num.msd=bcdacc+1+(msuq-lsuq+1)*9-quodigits; 567 1.1 christos num.lsd=ub; 568 1.1 christos 569 1.1 christos /* make exponent adjustments, etc */ 570 1.1 christos if (lsua<acc+DIVACCLEN-DIVOPLEN) { /* used extra digits */ 571 1.1 christos num.exponent-=(Int)((acc+DIVACCLEN-DIVOPLEN-lsua)*9); 572 1.1 christos /* if the result was exact then there may be up to 8 extra */ 573 1.1 christos /* trailing zeros in the overflowed quotient final unit */ 574 1.1 christos if (*msua==0) { 575 1.1 christos for (; *ub==0;) ub--; /* drop zeros */ 576 1.1 christos num.exponent+=(Int)(num.lsd-ub); /* and adjust exponent */ 577 1.1 christos num.lsd=ub; 578 1.1 christos } 579 1.1 christos } /* adjustment needed */ 580 1.1 christos 581 1.1 christos #if DIVCOUNT 582 1.1 christos if (divcount>maxcount) { /* new high-water nark */ 583 1.1 christos maxcount=divcount; 584 1.1 christos printf("DivNewMaxCount: %ld\n", (LI)maxcount); 585 1.1 christos } 586 1.1 christos #endif 587 1.1 christos 588 1.1 christos if (op&DIVIDE) return decFinalize(result, &num, set); /* all done */ 589 1.1 christos 590 1.1 christos /* Is DIVIDEINT or a remainder; there is more to do -- first form */ 591 1.1 christos /* the integer (this is done 'after the fact', unlike as in */ 592 1.1 christos /* decNumber, so as not to tax DIVIDE) */ 593 1.1 christos 594 1.1 christos /* The first non-zero digit will be in the first 9 digits, known */ 595 1.1 christos /* from quodigits and num.msd, so there is always space for DECPMAX */ 596 1.1 christos /* digits */ 597 1.1 christos 598 1.1 christos length=(Int)(num.lsd-num.msd+1); 599 1.1 christos /*printf("Length exp: %ld %ld\n", (LI)length, (LI)num.exponent); */ 600 1.1 christos 601 1.1 christos if (length+num.exponent>DECPMAX) { /* cannot fit */ 602 1.1 christos decFloatZero(result); 603 1.1 christos DFWORD(result, 0)=DECFLOAT_qNaN; 604 1.1 christos set->status|=DEC_Division_impossible; 605 1.1 christos return result; 606 1.1 christos } 607 1.1 christos 608 1.1 christos if (num.exponent>=0) { /* already an int, or need pad zeros */ 609 1.1 christos for (ub=num.lsd+1; ub<=num.lsd+num.exponent; ub++) *ub=0; 610 1.1 christos num.lsd+=num.exponent; 611 1.1 christos } 612 1.1 christos else { /* too long: round or truncate needed */ 613 1.1 christos Int drop=-num.exponent; 614 1.1 christos if (!(op&REMNEAR)) { /* simple truncate */ 615 1.1 christos num.lsd-=drop; 616 1.1 christos if (num.lsd<num.msd) { /* truncated all */ 617 1.1 christos num.lsd=num.msd; /* make 0 */ 618 1.1 christos *num.lsd=0; /* .. [sign still relevant] */ 619 1.1 christos } 620 1.1 christos } 621 1.1 christos else { /* round to nearest even [sigh] */ 622 1.1 christos /* round-to-nearest, in-place; msd is at or to right of bcdacc+1 */ 623 1.1 christos /* (this is a special case of Quantize -- q.v. for commentary) */ 624 1.1 christos uByte *roundat; /* -> re-round digit */ 625 1.1 christos uByte reround; /* reround value */ 626 1.1 christos *(num.msd-1)=0; /* in case of left carry, or make 0 */ 627 1.1 christos if (drop<length) roundat=num.lsd-drop+1; 628 1.1 christos else if (drop==length) roundat=num.msd; 629 1.1 christos else roundat=num.msd-1; /* [-> 0] */ 630 1.1 christos reround=*roundat; 631 1.1 christos for (ub=roundat+1; ub<=num.lsd; ub++) { 632 1.1 christos if (*ub!=0) { 633 1.1 christos reround=DECSTICKYTAB[reround]; 634 1.1 christos break; 635 1.1 christos } 636 1.1 christos } /* check stickies */ 637 1.1 christos if (roundat>num.msd) num.lsd=roundat-1; 638 1.1 christos else { 639 1.1 christos num.msd--; /* use the 0 .. */ 640 1.1 christos num.lsd=num.msd; /* .. at the new MSD place */ 641 1.1 christos } 642 1.1 christos if (reround!=0) { /* discarding non-zero */ 643 1.1 christos uInt bump=0; 644 1.1 christos /* rounding is DEC_ROUND_HALF_EVEN always */ 645 1.1 christos if (reround>5) bump=1; /* >0.5 goes up */ 646 1.1 christos else if (reround==5) /* exactly 0.5000 .. */ 647 1.1 christos bump=*(num.lsd) & 0x01; /* .. up iff [new] lsd is odd */ 648 1.1 christos if (bump!=0) { /* need increment */ 649 1.1 christos /* increment the coefficient; this might end up with 1000... */ 650 1.1 christos ub=num.lsd; 651 1.1 christos for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0); 652 1.1 christos for (; *ub==9; ub--) *ub=0; /* at most 3 more */ 653 1.1 christos *ub+=1; 654 1.1 christos if (ub<num.msd) num.msd--; /* carried */ 655 1.1 christos } /* bump needed */ 656 1.1 christos } /* reround!=0 */ 657 1.1 christos } /* remnear */ 658 1.1 christos } /* round or truncate needed */ 659 1.1 christos num.exponent=0; /* all paths */ 660 1.1 christos /*decShowNum(&num, "int"); */ 661 1.1 christos 662 1.1 christos if (op&DIVIDEINT) return decFinalize(result, &num, set); /* all done */ 663 1.1 christos 664 1.1 christos /* Have a remainder to calculate */ 665 1.1 christos decFinalize("ient, &num, set); /* lay out the integer so far */ 666 1.1 christos DFWORD("ient, 0)^=DECFLOAT_Sign; /* negate it */ 667 1.1 christos sign=DFWORD(dfl, 0); /* save sign of dfl */ 668 1.1 christos decFloatFMA(result, "ient, dfr, dfl, set); 669 1.1 christos if (!DFISZERO(result)) return result; 670 1.1 christos /* if the result is zero the sign shall be sign of dfl */ 671 1.1 christos DFWORD("ient, 0)=sign; /* construct decFloat of sign */ 672 1.1 christos return decFloatCopySign(result, result, "ient); 673 1.1 christos } /* decDivide */ 674 1.1 christos 675 1.1 christos /* ------------------------------------------------------------------ */ 676 1.1 christos /* decFiniteMultiply -- multiply two finite decFloats */ 677 1.1 christos /* */ 678 1.1 christos /* num gets the result of multiplying dfl and dfr */ 679 1.1 christos /* bcdacc .. with the coefficient in this array */ 680 1.1 christos /* dfl is the first decFloat (lhs) */ 681 1.1 christos /* dfr is the second decFloat (rhs) */ 682 1.1 christos /* */ 683 1.1 christos /* This effects the multiplication of two decFloats, both known to be */ 684 1.1 christos /* finite, leaving the result in a bcdnum ready for decFinalize (for */ 685 1.1 christos /* use in Multiply) or in a following addition (FMA). */ 686 1.1 christos /* */ 687 1.1 christos /* bcdacc must have space for at least DECPMAX9*18+1 bytes. */ 688 1.1 christos /* No error is possible and no status is set. */ 689 1.1 christos /* ------------------------------------------------------------------ */ 690 1.1 christos /* This routine has two separate implementations of the core */ 691 1.1 christos /* multiplication; both using base-billion. One uses only 32-bit */ 692 1.1 christos /* variables (Ints and uInts) or smaller; the other uses uLongs (for */ 693 1.1 christos /* multiplication and addition only). Both implementations cover */ 694 1.1 christos /* both arithmetic sizes (DOUBLE and QUAD) in order to allow timing */ 695 1.1 christos /* comparisons. In any one compilation only one implementation for */ 696 1.1 christos /* each size can be used, and if DECUSE64 is 0 then use of the 32-bit */ 697 1.1 christos /* version is forced. */ 698 1.1 christos /* */ 699 1.1 christos /* Historical note: an earlier version of this code also supported the */ 700 1.1 christos /* 256-bit format and has been preserved. That is somewhat trickier */ 701 1.1 christos /* during lazy carry splitting because the initial quotient estimate */ 702 1.1 christos /* (est) can exceed 32 bits. */ 703 1.1 christos 704 1.1 christos #define MULTBASE ((uInt)BILLION) /* the base used for multiply */ 705 1.1 christos #define MULOPLEN DECPMAX9 /* operand length ('digits' base 10**9) */ 706 1.1 christos #define MULACCLEN (MULOPLEN*2) /* accumulator length (ditto) */ 707 1.1 christos #define LEADZEROS (MULACCLEN*9 - DECPMAX*2) /* leading zeros always */ 708 1.1 christos 709 1.1 christos /* Assertions: exponent not too large and MULACCLEN is a multiple of 4 */ 710 1.1 christos #if DECEMAXD>9 711 1.1 christos #error Exponent may overflow when doubled for Multiply 712 1.1 christos #endif 713 1.1 christos #if MULACCLEN!=(MULACCLEN/4)*4 714 1.1 christos /* This assumption is used below only for initialization */ 715 1.1 christos #error MULACCLEN is not a multiple of 4 716 1.1 christos #endif 717 1.1 christos 718 1.1 christos static void decFiniteMultiply(bcdnum *num, uByte *bcdacc, 719 1.1 christos const decFloat *dfl, const decFloat *dfr) { 720 1.1 christos uInt bufl[MULOPLEN]; /* left coefficient (base-billion) */ 721 1.1 christos uInt bufr[MULOPLEN]; /* right coefficient (base-billion) */ 722 1.1 christos uInt *ui, *uj; /* work */ 723 1.1 christos uByte *ub; /* .. */ 724 1.1 christos uInt uiwork; /* for macros */ 725 1.1 christos 726 1.1 christos #if DECUSE64 727 1.1 christos uLong accl[MULACCLEN]; /* lazy accumulator (base-billion+) */ 728 1.1 christos uLong *pl; /* work -> lazy accumulator */ 729 1.1 christos uInt acc[MULACCLEN]; /* coefficent in base-billion .. */ 730 1.1 christos #else 731 1.1 christos uInt acc[MULACCLEN*2]; /* accumulator in base-billion .. */ 732 1.1 christos #endif 733 1.1 christos uInt *pa; /* work -> accumulator */ 734 1.1 christos /*printf("Base10**9: OpLen=%d MulAcclen=%d\n", OPLEN, MULACCLEN); */ 735 1.1 christos 736 1.1 christos /* Calculate sign and exponent */ 737 1.1 christos num->sign=(DFWORD(dfl, 0)^DFWORD(dfr, 0)) & DECFLOAT_Sign; 738 1.1 christos num->exponent=GETEXPUN(dfl)+GETEXPUN(dfr); /* [see assertion above] */ 739 1.1 christos 740 1.1 christos /* Extract the coefficients and prepare the accumulator */ 741 1.1 christos /* the coefficients of the operands are decoded into base-billion */ 742 1.1 christos /* numbers in uInt arrays (bufl and bufr, LSD at offset 0) of the */ 743 1.1 christos /* appropriate size. */ 744 1.1 christos GETCOEFFBILL(dfl, bufl); 745 1.1 christos GETCOEFFBILL(dfr, bufr); 746 1.1 christos #if DECTRACE && 0 747 1.1 christos printf("CoeffbL:"); 748 1.1 christos for (ui=bufl+MULOPLEN-1; ui>=bufl; ui--) printf(" %08lx", (LI)*ui); 749 1.1 christos printf("\n"); 750 1.1 christos printf("CoeffbR:"); 751 1.1 christos for (uj=bufr+MULOPLEN-1; uj>=bufr; uj--) printf(" %08lx", (LI)*uj); 752 1.1 christos printf("\n"); 753 1.1 christos #endif 754 1.1 christos 755 1.1 christos /* start the 64-bit/32-bit differing paths... */ 756 1.1 christos #if DECUSE64 757 1.1 christos 758 1.1 christos /* zero the accumulator */ 759 1.1 christos #if MULACCLEN==4 760 1.1 christos accl[0]=0; accl[1]=0; accl[2]=0; accl[3]=0; 761 1.1 christos #else /* use a loop */ 762 1.1 christos /* MULACCLEN is a multiple of four, asserted above */ 763 1.1 christos for (pl=accl; pl<accl+MULACCLEN; pl+=4) { 764 1.1 christos *pl=0; *(pl+1)=0; *(pl+2)=0; *(pl+3)=0;/* [reduce overhead] */ 765 1.1 christos } /* pl */ 766 1.1 christos #endif 767 1.1 christos 768 1.1 christos /* Effect the multiplication */ 769 1.1 christos /* The multiplcation proceeds using MFC's lazy-carry resolution */ 770 1.1 christos /* algorithm from decNumber. First, the multiplication is */ 771 1.1 christos /* effected, allowing accumulation of the partial products (which */ 772 1.1 christos /* are in base-billion at each column position) into 64 bits */ 773 1.1 christos /* without resolving back to base=billion after each addition. */ 774 1.1 christos /* These 64-bit numbers (which may contain up to 19 decimal digits) */ 775 1.1 christos /* are then split using the Clark & Cowlishaw algorithm (see below). */ 776 1.1 christos /* [Testing for 0 in the inner loop is not really a 'win'] */ 777 1.1 christos for (ui=bufr; ui<bufr+MULOPLEN; ui++) { /* over each item in rhs */ 778 1.1 christos if (*ui==0) continue; /* product cannot affect result */ 779 1.1 christos pl=accl+(ui-bufr); /* where to add the lhs */ 780 1.1 christos for (uj=bufl; uj<bufl+MULOPLEN; uj++, pl++) { /* over each item in lhs */ 781 1.1 christos /* if (*uj==0) continue; // product cannot affect result */ 782 1.1 christos *pl+=((uLong)*ui)*(*uj); 783 1.1 christos } /* uj */ 784 1.1 christos } /* ui */ 785 1.1 christos 786 1.1 christos /* The 64-bit carries must now be resolved; this means that a */ 787 1.1 christos /* quotient/remainder has to be calculated for base-billion (1E+9). */ 788 1.1 christos /* For this, Clark & Cowlishaw's quotient estimation approach (also */ 789 1.1 christos /* used in decNumber) is needed, because 64-bit divide is generally */ 790 1.1 christos /* extremely slow on 32-bit machines, and may be slower than this */ 791 1.1 christos /* approach even on 64-bit machines. This algorithm splits X */ 792 1.1 christos /* using: */ 793 1.1 christos /* */ 794 1.1 christos /* magic=2**(A+B)/1E+9; // 'magic number' */ 795 1.1 christos /* hop=X/2**A; // high order part of X (by shift) */ 796 1.1 christos /* est=magic*hop/2**B // quotient estimate (may be low by 1) */ 797 1.1 christos /* */ 798 1.1 christos /* A and B are quite constrained; hop and magic must fit in 32 bits, */ 799 1.1 christos /* and 2**(A+B) must be as large as possible (which is 2**61 if */ 800 1.1 christos /* magic is to fit). Further, maxX increases with the length of */ 801 1.1 christos /* the operands (and hence the number of partial products */ 802 1.1 christos /* accumulated); maxX is OPLEN*(10**18), which is up to 19 digits. */ 803 1.1 christos /* */ 804 1.1 christos /* It can be shown that when OPLEN is 2 then the maximum error in */ 805 1.1 christos /* the estimated quotient is <1, but for larger maximum x the */ 806 1.1 christos /* maximum error is above 1 so a correction that is >1 may be */ 807 1.1 christos /* needed. Values of A and B are chosen to satisfy the constraints */ 808 1.1 christos /* just mentioned while minimizing the maximum error (and hence the */ 809 1.1 christos /* maximum correction), as shown in the following table: */ 810 1.1 christos /* */ 811 1.1 christos /* Type OPLEN A B maxX maxError maxCorrection */ 812 1.1 christos /* --------------------------------------------------------- */ 813 1.1 christos /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ 814 1.1 christos /* QUAD 4 30 31 <4*10**18 1.17 2 */ 815 1.1 christos /* */ 816 1.1 christos /* In the OPLEN==2 case there is most choice, but the value for B */ 817 1.1 christos /* of 32 has a big advantage as then the calculation of the */ 818 1.1 christos /* estimate requires no shifting; the compiler can extract the high */ 819 1.1 christos /* word directly after multiplying magic*hop. */ 820 1.1 christos #define MULMAGIC 2305843009U /* 2**61/10**9 [both cases] */ 821 1.1 christos #if DOUBLE 822 1.1 christos #define MULSHIFTA 29 823 1.1 christos #define MULSHIFTB 32 824 1.1 christos #elif QUAD 825 1.1 christos #define MULSHIFTA 30 826 1.1 christos #define MULSHIFTB 31 827 1.1 christos #else 828 1.1 christos #error Unexpected type 829 1.1 christos #endif 830 1.1 christos 831 1.1 christos #if DECTRACE 832 1.1 christos printf("MulAccl:"); 833 1.1 christos for (pl=accl+MULACCLEN-1; pl>=accl; pl--) 834 1.1 christos printf(" %08lx:%08lx", (LI)(*pl>>32), (LI)(*pl&0xffffffff)); 835 1.1 christos printf("\n"); 836 1.1 christos #endif 837 1.1 christos 838 1.1 christos for (pl=accl, pa=acc; pl<accl+MULACCLEN; pl++, pa++) { /* each column position */ 839 1.1 christos uInt lo, hop; /* work */ 840 1.1 christos uInt est; /* cannot exceed 4E+9 */ 841 1.1 christos if (*pl>=MULTBASE) { 842 1.1 christos /* *pl holds a binary number which needs to be split */ 843 1.1 christos hop=(uInt)(*pl>>MULSHIFTA); 844 1.1 christos est=(uInt)(((uLong)hop*MULMAGIC)>>MULSHIFTB); 845 1.1 christos /* the estimate is now in est; now calculate hi:lo-est*10**9; */ 846 1.1 christos /* happily the top word of the result is irrelevant because it */ 847 1.1 christos /* will always be zero so this needs only one multiplication */ 848 1.1 christos lo=(uInt)(*pl-((uLong)est*MULTBASE)); /* low word of result */ 849 1.1 christos /* If QUAD, the correction here could be +2 */ 850 1.1 christos if (lo>=MULTBASE) { 851 1.1 christos lo-=MULTBASE; /* correct by +1 */ 852 1.1 christos est++; 853 1.1 christos #if QUAD 854 1.1 christos /* may need to correct by +2 */ 855 1.1 christos if (lo>=MULTBASE) { 856 1.1 christos lo-=MULTBASE; 857 1.1 christos est++; 858 1.1 christos } 859 1.1 christos #endif 860 1.1 christos } 861 1.1 christos /* finally place lo as the new coefficient 'digit' and add est to */ 862 1.1 christos /* the next place up [this is safe because this path is never */ 863 1.1 christos /* taken on the final iteration as *pl will fit] */ 864 1.1 christos *pa=lo; 865 1.1 christos *(pl+1)+=est; 866 1.1 christos } /* *pl needed split */ 867 1.1 christos else { /* *pl<MULTBASE */ 868 1.1 christos *pa=(uInt)*pl; /* just copy across */ 869 1.1 christos } 870 1.1 christos } /* pl loop */ 871 1.1 christos 872 1.1 christos #else /* 32-bit */ 873 1.1 christos for (pa=acc;; pa+=4) { /* zero the accumulator */ 874 1.1 christos *pa=0; *(pa+1)=0; *(pa+2)=0; *(pa+3)=0; /* [reduce overhead] */ 875 1.1 christos if (pa==acc+MULACCLEN*2-4) break; /* multiple of 4 asserted */ 876 1.1 christos } /* pa */ 877 1.1 christos 878 1.1 christos /* Effect the multiplication */ 879 1.1 christos /* uLongs are not available (and in particular, there is no uLong */ 880 1.1 christos /* divide) but it is still possible to use MFC's lazy-carry */ 881 1.1 christos /* resolution algorithm from decNumber. First, the multiplication */ 882 1.1 christos /* is effected, allowing accumulation of the partial products */ 883 1.1 christos /* (which are in base-billion at each column position) into 64 bits */ 884 1.1 christos /* [with the high-order 32 bits in each position being held at */ 885 1.1 christos /* offset +ACCLEN from the low-order 32 bits in the accumulator]. */ 886 1.1 christos /* These 64-bit numbers (which may contain up to 19 decimal digits) */ 887 1.1 christos /* are then split using the Clark & Cowlishaw algorithm (see */ 888 1.1 christos /* below). */ 889 1.1 christos for (ui=bufr;; ui++) { /* over each item in rhs */ 890 1.1 christos uInt hi, lo; /* words of exact multiply result */ 891 1.1 christos pa=acc+(ui-bufr); /* where to add the lhs */ 892 1.1 christos for (uj=bufl;; uj++, pa++) { /* over each item in lhs */ 893 1.1 christos LONGMUL32HI(hi, *ui, *uj); /* calculate product of digits */ 894 1.1 christos lo=(*ui)*(*uj); /* .. */ 895 1.1 christos *pa+=lo; /* accumulate low bits and .. */ 896 1.1 christos *(pa+MULACCLEN)+=hi+(*pa<lo); /* .. high bits with any carry */ 897 1.1 christos if (uj==bufl+MULOPLEN-1) break; 898 1.1 christos } 899 1.1 christos if (ui==bufr+MULOPLEN-1) break; 900 1.1 christos } 901 1.1 christos 902 1.1 christos /* The 64-bit carries must now be resolved; this means that a */ 903 1.1 christos /* quotient/remainder has to be calculated for base-billion (1E+9). */ 904 1.1 christos /* For this, Clark & Cowlishaw's quotient estimation approach (also */ 905 1.1 christos /* used in decNumber) is needed, because 64-bit divide is generally */ 906 1.1 christos /* extremely slow on 32-bit machines. This algorithm splits X */ 907 1.1 christos /* using: */ 908 1.1 christos /* */ 909 1.1 christos /* magic=2**(A+B)/1E+9; // 'magic number' */ 910 1.1 christos /* hop=X/2**A; // high order part of X (by shift) */ 911 1.1 christos /* est=magic*hop/2**B // quotient estimate (may be low by 1) */ 912 1.1 christos /* */ 913 1.1 christos /* A and B are quite constrained; hop and magic must fit in 32 bits, */ 914 1.1 christos /* and 2**(A+B) must be as large as possible (which is 2**61 if */ 915 1.1 christos /* magic is to fit). Further, maxX increases with the length of */ 916 1.1 christos /* the operands (and hence the number of partial products */ 917 1.1 christos /* accumulated); maxX is OPLEN*(10**18), which is up to 19 digits. */ 918 1.1 christos /* */ 919 1.1 christos /* It can be shown that when OPLEN is 2 then the maximum error in */ 920 1.1 christos /* the estimated quotient is <1, but for larger maximum x the */ 921 1.1 christos /* maximum error is above 1 so a correction that is >1 may be */ 922 1.1 christos /* needed. Values of A and B are chosen to satisfy the constraints */ 923 1.1 christos /* just mentioned while minimizing the maximum error (and hence the */ 924 1.1 christos /* maximum correction), as shown in the following table: */ 925 1.1 christos /* */ 926 1.1 christos /* Type OPLEN A B maxX maxError maxCorrection */ 927 1.1 christos /* --------------------------------------------------------- */ 928 1.1 christos /* DOUBLE 2 29 32 <2*10**18 0.63 1 */ 929 1.1 christos /* QUAD 4 30 31 <4*10**18 1.17 2 */ 930 1.1 christos /* */ 931 1.1 christos /* In the OPLEN==2 case there is most choice, but the value for B */ 932 1.1 christos /* of 32 has a big advantage as then the calculation of the */ 933 1.1 christos /* estimate requires no shifting; the high word is simply */ 934 1.1 christos /* calculated from multiplying magic*hop. */ 935 1.1 christos #define MULMAGIC 2305843009U /* 2**61/10**9 [both cases] */ 936 1.1 christos #if DOUBLE 937 1.1 christos #define MULSHIFTA 29 938 1.1 christos #define MULSHIFTB 32 939 1.1 christos #elif QUAD 940 1.1 christos #define MULSHIFTA 30 941 1.1 christos #define MULSHIFTB 31 942 1.1 christos #else 943 1.1 christos #error Unexpected type 944 1.1 christos #endif 945 1.1 christos 946 1.1 christos #if DECTRACE 947 1.1 christos printf("MulHiLo:"); 948 1.1 christos for (pa=acc+MULACCLEN-1; pa>=acc; pa--) 949 1.1 christos printf(" %08lx:%08lx", (LI)*(pa+MULACCLEN), (LI)*pa); 950 1.1 christos printf("\n"); 951 1.1 christos #endif 952 1.1 christos 953 1.1 christos for (pa=acc;; pa++) { /* each low uInt */ 954 1.1 christos uInt hi, lo; /* words of exact multiply result */ 955 1.1 christos uInt hop, estlo; /* work */ 956 1.1 christos #if QUAD 957 1.1 christos uInt esthi; /* .. */ 958 1.1 christos #endif 959 1.1 christos 960 1.1 christos lo=*pa; 961 1.1 christos hi=*(pa+MULACCLEN); /* top 32 bits */ 962 1.1 christos /* hi and lo now hold a binary number which needs to be split */ 963 1.1 christos 964 1.1 christos #if DOUBLE 965 1.1 christos hop=(hi<<3)+(lo>>MULSHIFTA); /* hi:lo/2**29 */ 966 1.1 christos LONGMUL32HI(estlo, hop, MULMAGIC);/* only need the high word */ 967 1.1 christos /* [MULSHIFTB is 32, so estlo can be used directly] */ 968 1.1 christos /* the estimate is now in estlo; now calculate hi:lo-est*10**9; */ 969 1.1 christos /* happily the top word of the result is irrelevant because it */ 970 1.1 christos /* will always be zero so this needs only one multiplication */ 971 1.1 christos lo-=(estlo*MULTBASE); 972 1.1 christos /* esthi=0; // high word is ignored below */ 973 1.1 christos /* the correction here will be at most +1; do it */ 974 1.1 christos if (lo>=MULTBASE) { 975 1.1 christos lo-=MULTBASE; 976 1.1 christos estlo++; 977 1.1 christos } 978 1.1 christos #elif QUAD 979 1.1 christos hop=(hi<<2)+(lo>>MULSHIFTA); /* hi:lo/2**30 */ 980 1.1 christos LONGMUL32HI(esthi, hop, MULMAGIC);/* shift will be 31 .. */ 981 1.1 christos estlo=hop*MULMAGIC; /* .. so low word needed */ 982 1.1 christos estlo=(esthi<<1)+(estlo>>MULSHIFTB); /* [just the top bit] */ 983 1.1 christos /* esthi=0; // high word is ignored below */ 984 1.1 christos lo-=(estlo*MULTBASE); /* as above */ 985 1.1 christos /* the correction here could be +1 or +2 */ 986 1.1 christos if (lo>=MULTBASE) { 987 1.1 christos lo-=MULTBASE; 988 1.1 christos estlo++; 989 1.1 christos } 990 1.1 christos if (lo>=MULTBASE) { 991 1.1 christos lo-=MULTBASE; 992 1.1 christos estlo++; 993 1.1 christos } 994 1.1 christos #else 995 1.1 christos #error Unexpected type 996 1.1 christos #endif 997 1.1 christos 998 1.1 christos /* finally place lo as the new accumulator digit and add est to */ 999 1.1 christos /* the next place up; this latter add could cause a carry of 1 */ 1000 1.1 christos /* to the high word of the next place */ 1001 1.1 christos *pa=lo; 1002 1.1 christos *(pa+1)+=estlo; 1003 1.1 christos /* esthi is always 0 for DOUBLE and QUAD so this is skipped */ 1004 1.1 christos /* *(pa+1+MULACCLEN)+=esthi; */ 1005 1.1 christos if (*(pa+1)<estlo) *(pa+1+MULACCLEN)+=1; /* carry */ 1006 1.1 christos if (pa==acc+MULACCLEN-2) break; /* [MULACCLEN-1 will never need split] */ 1007 1.1 christos } /* pa loop */ 1008 1.1 christos #endif 1009 1.1 christos 1010 1.1 christos /* At this point, whether using the 64-bit or the 32-bit paths, the */ 1011 1.1 christos /* accumulator now holds the (unrounded) result in base-billion; */ 1012 1.1 christos /* one base-billion 'digit' per uInt. */ 1013 1.1 christos #if DECTRACE 1014 1.1 christos printf("MultAcc:"); 1015 1.1 christos for (pa=acc+MULACCLEN-1; pa>=acc; pa--) printf(" %09ld", (LI)*pa); 1016 1.1 christos printf("\n"); 1017 1.1 christos #endif 1018 1.1 christos 1019 1.1 christos /* Now convert to BCD for rounding and cleanup, starting from the */ 1020 1.1 christos /* most significant end */ 1021 1.1 christos pa=acc+MULACCLEN-1; 1022 1.1 christos if (*pa!=0) num->msd=bcdacc+LEADZEROS;/* drop known lead zeros */ 1023 1.1 christos else { /* >=1 word of leading zeros */ 1024 1.1 christos num->msd=bcdacc; /* known leading zeros are gone */ 1025 1.1 christos pa--; /* skip first word .. */ 1026 1.1 christos for (; *pa==0; pa--) if (pa==acc) break; /* .. and any more leading 0s */ 1027 1.1 christos } 1028 1.1 christos for (ub=bcdacc;; pa--, ub+=9) { 1029 1.1 christos if (*pa!=0) { /* split(s) needed */ 1030 1.1 christos uInt top, mid, rem; /* work */ 1031 1.1 christos /* *pa is non-zero -- split the base-billion acc digit into */ 1032 1.1 christos /* hi, mid, and low three-digits */ 1033 1.1 christos #define mulsplit9 1000000 /* divisor */ 1034 1.1 christos #define mulsplit6 1000 /* divisor */ 1035 1.1 christos /* The splitting is done by simple divides and remainders, */ 1036 1.1 christos /* assuming the compiler will optimize these where useful */ 1037 1.1 christos /* [GCC does] */ 1038 1.1 christos top=*pa/mulsplit9; 1039 1.1 christos rem=*pa%mulsplit9; 1040 1.1 christos mid=rem/mulsplit6; 1041 1.1 christos rem=rem%mulsplit6; 1042 1.1 christos /* lay out the nine BCD digits (plus one unwanted byte) */ 1043 1.1 christos UBFROMUI(ub, UBTOUI(&BIN2BCD8[top*4])); 1044 1.1 christos UBFROMUI(ub+3, UBTOUI(&BIN2BCD8[mid*4])); 1045 1.1 christos UBFROMUI(ub+6, UBTOUI(&BIN2BCD8[rem*4])); 1046 1.1 christos } 1047 1.1 christos else { /* *pa==0 */ 1048 1.1 christos UBFROMUI(ub, 0); /* clear 9 BCD8s */ 1049 1.1 christos UBFROMUI(ub+4, 0); /* .. */ 1050 1.1 christos *(ub+8)=0; /* .. */ 1051 1.1 christos } 1052 1.1 christos if (pa==acc) break; 1053 1.1 christos } /* BCD conversion loop */ 1054 1.1 christos 1055 1.1 christos num->lsd=ub+8; /* complete the bcdnum .. */ 1056 1.1 christos 1057 1.1 christos #if DECTRACE 1058 1.1 christos decShowNum(num, "postmult"); 1059 1.1 christos decFloatShow(dfl, "dfl"); 1060 1.1 christos decFloatShow(dfr, "dfr"); 1061 1.1 christos #endif 1062 1.1 christos return; 1063 1.1 christos } /* decFiniteMultiply */ 1064 1.1 christos 1065 1.1 christos /* ------------------------------------------------------------------ */ 1066 1.1 christos /* decFloatAbs -- absolute value, heeding NaNs, etc. */ 1067 1.1 christos /* */ 1068 1.1 christos /* result gets the canonicalized df with sign 0 */ 1069 1.1 christos /* df is the decFloat to abs */ 1070 1.1 christos /* set is the context */ 1071 1.1 christos /* returns result */ 1072 1.1 christos /* */ 1073 1.1 christos /* This has the same effect as decFloatPlus unless df is negative, */ 1074 1.1 christos /* in which case it has the same effect as decFloatMinus. The */ 1075 1.1 christos /* effect is also the same as decFloatCopyAbs except that NaNs are */ 1076 1.1 christos /* handled normally (the sign of a NaN is not affected, and an sNaN */ 1077 1.1 christos /* will signal) and the result will be canonical. */ 1078 1.1 christos /* ------------------------------------------------------------------ */ 1079 1.1 christos decFloat * decFloatAbs(decFloat *result, const decFloat *df, 1080 1.1 christos decContext *set) { 1081 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); 1082 1.1 christos decCanonical(result, df); /* copy and check */ 1083 1.1 christos DFBYTE(result, 0)&=~0x80; /* zero sign bit */ 1084 1.1 christos return result; 1085 1.1 christos } /* decFloatAbs */ 1086 1.1 christos 1087 1.1 christos /* ------------------------------------------------------------------ */ 1088 1.1 christos /* decFloatAdd -- add two decFloats */ 1089 1.1 christos /* */ 1090 1.1 christos /* result gets the result of adding dfl and dfr: */ 1091 1.1 christos /* dfl is the first decFloat (lhs) */ 1092 1.1 christos /* dfr is the second decFloat (rhs) */ 1093 1.1 christos /* set is the context */ 1094 1.1 christos /* returns result */ 1095 1.1 christos /* */ 1096 1.1 christos /* ------------------------------------------------------------------ */ 1097 1.1 christos #if QUAD 1098 1.1 christos /* Table for testing MSDs for fastpath elimination; returns the MSD of */ 1099 1.1 christos /* a decDouble or decQuad (top 6 bits tested) ignoring the sign. */ 1100 1.1 christos /* Infinities return -32 and NaNs return -128 so that summing the two */ 1101 1.1 christos /* MSDs also allows rapid tests for the Specials (see code below). */ 1102 1.1 christos const Int DECTESTMSD[64]={ 1103 1.1 christos 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 1104 1.1 christos 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128, 1105 1.1 christos 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 1106 1.1 christos 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, -32, -128}; 1107 1.1 christos #else 1108 1.1 christos /* The table for testing MSDs is shared between the modules */ 1109 1.1 christos extern const Int DECTESTMSD[64]; 1110 1.1 christos #endif 1111 1.1 christos 1112 1.1 christos decFloat * decFloatAdd(decFloat *result, 1113 1.1 christos const decFloat *dfl, const decFloat *dfr, 1114 1.1 christos decContext *set) { 1115 1.1 christos bcdnum num; /* for final conversion */ 1116 1.1 christos Int bexpl, bexpr; /* left and right biased exponents */ 1117 1.1 christos uByte *ub, *us, *ut; /* work */ 1118 1.1 christos uInt uiwork; /* for macros */ 1119 1.1 christos #if QUAD 1120 1.1 christos uShort uswork; /* .. */ 1121 1.1 christos #endif 1122 1.1 christos 1123 1.1 christos uInt sourhil, sourhir; /* top words from source decFloats */ 1124 1.1 christos /* [valid only through end of */ 1125 1.1 christos /* fastpath code -- before swap] */ 1126 1.1 christos uInt diffsign; /* non-zero if signs differ */ 1127 1.1 christos uInt carry; /* carry: 0 or 1 before add loop */ 1128 1.1 christos Int overlap; /* coefficient overlap (if full) */ 1129 1.1 christos Int summ; /* sum of the MSDs */ 1130 1.1 christos /* the following buffers hold coefficients with various alignments */ 1131 1.1 christos /* (see commentary and diagrams below) */ 1132 1.1 christos uByte acc[4+2+DECPMAX*3+8]; 1133 1.1 christos uByte buf[4+2+DECPMAX*2]; 1134 1.1 christos uByte *umsd, *ulsd; /* local MSD and LSD pointers */ 1135 1.1 christos 1136 1.1 christos #if DECLITEND 1137 1.1 christos #define CARRYPAT 0x01000000 /* carry=1 pattern */ 1138 1.1 christos #else 1139 1.1 christos #define CARRYPAT 0x00000001 /* carry=1 pattern */ 1140 1.1 christos #endif 1141 1.1 christos 1142 1.1 christos /* Start decoding the arguments */ 1143 1.1 christos /* The initial exponents are placed into the opposite Ints to */ 1144 1.1 christos /* that which might be expected; there are two sets of data to */ 1145 1.1 christos /* keep track of (each decFloat and the corresponding exponent), */ 1146 1.1 christos /* and this scheme means that at the swap point (after comparing */ 1147 1.1 christos /* exponents) only one pair of words needs to be swapped */ 1148 1.1 christos /* whichever path is taken (thereby minimising worst-case path). */ 1149 1.1 christos /* The calculated exponents will be nonsense when the arguments are */ 1150 1.1 christos /* Special, but are not used in that path */ 1151 1.1 christos sourhil=DFWORD(dfl, 0); /* LHS top word */ 1152 1.1 christos summ=DECTESTMSD[sourhil>>26]; /* get first MSD for testing */ 1153 1.1 christos bexpr=DECCOMBEXP[sourhil>>26]; /* get exponent high bits (in place) */ 1154 1.1 christos bexpr+=GETECON(dfl); /* .. + continuation */ 1155 1.1 christos 1156 1.1 christos sourhir=DFWORD(dfr, 0); /* RHS top word */ 1157 1.1 christos summ+=DECTESTMSD[sourhir>>26]; /* sum MSDs for testing */ 1158 1.1 christos bexpl=DECCOMBEXP[sourhir>>26]; 1159 1.1 christos bexpl+=GETECON(dfr); 1160 1.1 christos 1161 1.1 christos /* here bexpr has biased exponent from lhs, and vice versa */ 1162 1.1 christos 1163 1.1 christos diffsign=(sourhil^sourhir)&DECFLOAT_Sign; 1164 1.1 christos 1165 1.1 christos /* now determine whether to take a fast path or the full-function */ 1166 1.1 christos /* slow path. The slow path must be taken when: */ 1167 1.1 christos /* -- both numbers are finite, and: */ 1168 1.1 christos /* the exponents are different, or */ 1169 1.1 christos /* the signs are different, or */ 1170 1.1 christos /* the sum of the MSDs is >8 (hence might overflow) */ 1171 1.1 christos /* specialness and the sum of the MSDs can be tested at once using */ 1172 1.1 christos /* the summ value just calculated, so the test for specials is no */ 1173 1.1 christos /* longer on the worst-case path (as of 3.60) */ 1174 1.1 christos 1175 1.1 christos if (summ<=8) { /* MSD+MSD is good, or there is a special */ 1176 1.1 christos if (summ<0) { /* there is a special */ 1177 1.1 christos /* Inf+Inf would give -64; Inf+finite is -32 or higher */ 1178 1.1 christos if (summ<-64) return decNaNs(result, dfl, dfr, set); /* one or two NaNs */ 1179 1.1 christos /* two infinities with different signs is invalid */ 1180 1.1 christos if (summ==-64 && diffsign) return decInvalid(result, set); 1181 1.1 christos if (DFISINF(dfl)) return decInfinity(result, dfl); /* LHS is infinite */ 1182 1.1 christos return decInfinity(result, dfr); /* RHS must be Inf */ 1183 1.1 christos } 1184 1.1 christos /* Here when both arguments are finite; fast path is possible */ 1185 1.1 christos /* (currently only for aligned and same-sign) */ 1186 1.1 christos if (bexpr==bexpl && !diffsign) { 1187 1.1 christos uInt tac[DECLETS+1]; /* base-1000 coefficient */ 1188 1.1 christos uInt encode; /* work */ 1189 1.1 christos 1190 1.1 christos /* Get one coefficient as base-1000 and add the other */ 1191 1.1 christos GETCOEFFTHOU(dfl, tac); /* least-significant goes to [0] */ 1192 1.1 christos ADDCOEFFTHOU(dfr, tac); 1193 1.1 christos /* here the sum of the MSDs (plus any carry) will be <10 due to */ 1194 1.1 christos /* the fastpath test earlier */ 1195 1.1 christos 1196 1.1 christos /* construct the result; low word is the same for both formats */ 1197 1.1 christos encode =BIN2DPD[tac[0]]; 1198 1.1 christos encode|=BIN2DPD[tac[1]]<<10; 1199 1.1 christos encode|=BIN2DPD[tac[2]]<<20; 1200 1.1 christos encode|=BIN2DPD[tac[3]]<<30; 1201 1.1 christos DFWORD(result, (DECBYTES/4)-1)=encode; 1202 1.1 christos 1203 1.1 christos /* collect next two declets (all that remains, for Double) */ 1204 1.1 christos encode =BIN2DPD[tac[3]]>>2; 1205 1.1 christos encode|=BIN2DPD[tac[4]]<<8; 1206 1.1 christos 1207 1.1 christos #if QUAD 1208 1.1 christos /* complete and lay out middling words */ 1209 1.1 christos encode|=BIN2DPD[tac[5]]<<18; 1210 1.1 christos encode|=BIN2DPD[tac[6]]<<28; 1211 1.1 christos DFWORD(result, 2)=encode; 1212 1.1 christos 1213 1.1 christos encode =BIN2DPD[tac[6]]>>4; 1214 1.1 christos encode|=BIN2DPD[tac[7]]<<6; 1215 1.1 christos encode|=BIN2DPD[tac[8]]<<16; 1216 1.1 christos encode|=BIN2DPD[tac[9]]<<26; 1217 1.1 christos DFWORD(result, 1)=encode; 1218 1.1 christos 1219 1.1 christos /* and final two declets */ 1220 1.1 christos encode =BIN2DPD[tac[9]]>>6; 1221 1.1 christos encode|=BIN2DPD[tac[10]]<<4; 1222 1.1 christos #endif 1223 1.1 christos 1224 1.1 christos /* add exponent continuation and sign (from either argument) */ 1225 1.1 christos encode|=sourhil & (ECONMASK | DECFLOAT_Sign); 1226 1.1 christos 1227 1.1 christos /* create lookup index = MSD + top two bits of biased exponent <<4 */ 1228 1.1 christos tac[DECLETS]|=(bexpl>>DECECONL)<<4; 1229 1.1 christos encode|=DECCOMBFROM[tac[DECLETS]]; /* add constructed combination field */ 1230 1.1 christos DFWORD(result, 0)=encode; /* complete */ 1231 1.1 christos 1232 1.1 christos /* decFloatShow(result, ">"); */ 1233 1.1 christos return result; 1234 1.1 christos } /* fast path OK */ 1235 1.1 christos /* drop through to slow path */ 1236 1.1 christos } /* low sum or Special(s) */ 1237 1.1 christos 1238 1.1 christos /* Slow path required -- arguments are finite and might overflow, */ 1239 1.1 christos /* or require alignment, or might have different signs */ 1240 1.1 christos 1241 1.1 christos /* now swap either exponents or argument pointers */ 1242 1.1 christos if (bexpl<=bexpr) { 1243 1.1 christos /* original left is bigger */ 1244 1.1 christos Int bexpswap=bexpl; 1245 1.1 christos bexpl=bexpr; 1246 1.1 christos bexpr=bexpswap; 1247 1.1 christos /* printf("left bigger\n"); */ 1248 1.1 christos } 1249 1.1 christos else { 1250 1.1 christos const decFloat *dfswap=dfl; 1251 1.1 christos dfl=dfr; 1252 1.1 christos dfr=dfswap; 1253 1.1 christos /* printf("right bigger\n"); */ 1254 1.1 christos } 1255 1.1 christos /* [here dfl and bexpl refer to the datum with the larger exponent, */ 1256 1.1 christos /* of if the exponents are equal then the original LHS argument] */ 1257 1.1 christos 1258 1.1 christos /* if lhs is zero then result will be the rhs (now known to have */ 1259 1.1 christos /* the smaller exponent), which also may need to be tested for zero */ 1260 1.1 christos /* for the weird IEEE 754 sign rules */ 1261 1.1 christos if (DFISZERO(dfl)) { 1262 1.1 christos decCanonical(result, dfr); /* clean copy */ 1263 1.1 christos /* "When the sum of two operands with opposite signs is */ 1264 1.1 christos /* exactly zero, the sign of that sum shall be '+' in all */ 1265 1.1 christos /* rounding modes except round toward -Infinity, in which */ 1266 1.1 christos /* mode that sign shall be '-'." */ 1267 1.1 christos if (diffsign && DFISZERO(result)) { 1268 1.1 christos DFWORD(result, 0)&=~DECFLOAT_Sign; /* assume sign 0 */ 1269 1.1 christos if (set->round==DEC_ROUND_FLOOR) DFWORD(result, 0)|=DECFLOAT_Sign; 1270 1.1 christos } 1271 1.1 christos return result; 1272 1.1 christos } /* numfl is zero */ 1273 1.1 christos /* [here, LHS is non-zero; code below assumes that] */ 1274 1.1 christos 1275 1.1 christos /* Coefficients layout during the calculations to follow: */ 1276 1.1 christos /* */ 1277 1.1 christos /* Overlap case: */ 1278 1.1 christos /* +------------------------------------------------+ */ 1279 1.1 christos /* acc: |0000| coeffa | tail B | | */ 1280 1.1 christos /* +------------------------------------------------+ */ 1281 1.1 christos /* buf: |0000| pad0s | coeffb | | */ 1282 1.1 christos /* +------------------------------------------------+ */ 1283 1.1 christos /* */ 1284 1.1 christos /* Touching coefficients or gap: */ 1285 1.1 christos /* +------------------------------------------------+ */ 1286 1.1 christos /* acc: |0000| coeffa | gap | coeffb | */ 1287 1.1 christos /* +------------------------------------------------+ */ 1288 1.1 christos /* [buf not used or needed; gap clamped to Pmax] */ 1289 1.1 christos 1290 1.1 christos /* lay out lhs coefficient into accumulator; this starts at acc+4 */ 1291 1.1 christos /* for decDouble or acc+6 for decQuad so the LSD is word- */ 1292 1.1 christos /* aligned; the top word gap is there only in case a carry digit */ 1293 1.1 christos /* is prefixed after the add -- it does not need to be zeroed */ 1294 1.1 christos #if DOUBLE 1295 1.1 christos #define COFF 4 /* offset into acc */ 1296 1.1 christos #elif QUAD 1297 1.1 christos UBFROMUS(acc+4, 0); /* prefix 00 */ 1298 1.1 christos #define COFF 6 /* offset into acc */ 1299 1.1 christos #endif 1300 1.1 christos 1301 1.1 christos GETCOEFF(dfl, acc+COFF); /* decode from decFloat */ 1302 1.1 christos ulsd=acc+COFF+DECPMAX-1; 1303 1.1 christos umsd=acc+4; /* [having this here avoids */ 1304 1.1 christos 1305 1.1 christos #if DECTRACE 1306 1.1 christos {bcdnum tum; 1307 1.1 christos tum.msd=umsd; 1308 1.1 christos tum.lsd=ulsd; 1309 1.1 christos tum.exponent=bexpl-DECBIAS; 1310 1.1 christos tum.sign=DFWORD(dfl, 0) & DECFLOAT_Sign; 1311 1.1 christos decShowNum(&tum, "dflx");} 1312 1.1 christos #endif 1313 1.1 christos 1314 1.1 christos /* if signs differ, take ten's complement of lhs (here the */ 1315 1.1 christos /* coefficient is subtracted from all-nines; the 1 is added during */ 1316 1.1 christos /* the later add cycle -- zeros to the right do not matter because */ 1317 1.1 christos /* the complement of zero is zero); these are fixed-length inverts */ 1318 1.1 christos /* where the lsd is known to be at a 4-byte boundary (so no borrow */ 1319 1.1 christos /* possible) */ 1320 1.1 christos carry=0; /* assume no carry */ 1321 1.1 christos if (diffsign) { 1322 1.1 christos carry=CARRYPAT; /* for +1 during add */ 1323 1.1 christos UBFROMUI(acc+ 4, 0x09090909-UBTOUI(acc+ 4)); 1324 1.1 christos UBFROMUI(acc+ 8, 0x09090909-UBTOUI(acc+ 8)); 1325 1.1 christos UBFROMUI(acc+12, 0x09090909-UBTOUI(acc+12)); 1326 1.1 christos UBFROMUI(acc+16, 0x09090909-UBTOUI(acc+16)); 1327 1.1 christos #if QUAD 1328 1.1 christos UBFROMUI(acc+20, 0x09090909-UBTOUI(acc+20)); 1329 1.1 christos UBFROMUI(acc+24, 0x09090909-UBTOUI(acc+24)); 1330 1.1 christos UBFROMUI(acc+28, 0x09090909-UBTOUI(acc+28)); 1331 1.1 christos UBFROMUI(acc+32, 0x09090909-UBTOUI(acc+32)); 1332 1.1 christos UBFROMUI(acc+36, 0x09090909-UBTOUI(acc+36)); 1333 1.1 christos #endif 1334 1.1 christos } /* diffsign */ 1335 1.1 christos 1336 1.1 christos /* now process the rhs coefficient; if it cannot overlap lhs then */ 1337 1.1 christos /* it can be put straight into acc (with an appropriate gap, if */ 1338 1.1 christos /* needed) because no actual addition will be needed (except */ 1339 1.1 christos /* possibly to complete ten's complement) */ 1340 1.1 christos overlap=DECPMAX-(bexpl-bexpr); 1341 1.1 christos #if DECTRACE 1342 1.1 christos printf("exps: %ld %ld\n", (LI)(bexpl-DECBIAS), (LI)(bexpr-DECBIAS)); 1343 1.1 christos printf("Overlap=%ld carry=%08lx\n", (LI)overlap, (LI)carry); 1344 1.1 christos #endif 1345 1.1 christos 1346 1.1 christos if (overlap<=0) { /* no overlap possible */ 1347 1.1 christos uInt gap; /* local work */ 1348 1.1 christos /* since a full addition is not needed, a ten's complement */ 1349 1.1 christos /* calculation started above may need to be completed */ 1350 1.1 christos if (carry) { 1351 1.1 christos for (ub=ulsd; *ub==9; ub--) *ub=0; 1352 1.1 christos *ub+=1; 1353 1.1 christos carry=0; /* taken care of */ 1354 1.1 christos } 1355 1.1 christos /* up to DECPMAX-1 digits of the final result can extend down */ 1356 1.1 christos /* below the LSD of the lhs, so if the gap is >DECPMAX then the */ 1357 1.1 christos /* rhs will be simply sticky bits. In this case the gap is */ 1358 1.1 christos /* clamped to DECPMAX and the exponent adjusted to suit [this is */ 1359 1.1 christos /* safe because the lhs is non-zero]. */ 1360 1.1 christos gap=-overlap; 1361 1.1 christos if (gap>DECPMAX) { 1362 1.1 christos bexpr+=gap-1; 1363 1.1 christos gap=DECPMAX; 1364 1.1 christos } 1365 1.1 christos ub=ulsd+gap+1; /* where MSD will go */ 1366 1.1 christos /* Fill the gap with 0s; note that there is no addition to do */ 1367 1.1 christos ut=acc+COFF+DECPMAX; /* start of gap */ 1368 1.1 christos for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* mind the gap */ 1369 1.1 christos if (overlap<-DECPMAX) { /* gap was > DECPMAX */ 1370 1.1 christos *ub=(uByte)(!DFISZERO(dfr)); /* make sticky digit */ 1371 1.1 christos } 1372 1.1 christos else { /* need full coefficient */ 1373 1.1 christos GETCOEFF(dfr, ub); /* decode from decFloat */ 1374 1.1 christos ub+=DECPMAX-1; /* new LSD... */ 1375 1.1 christos } 1376 1.1 christos ulsd=ub; /* save new LSD */ 1377 1.1 christos } /* no overlap possible */ 1378 1.1 christos 1379 1.1 christos else { /* overlap>0 */ 1380 1.1 christos /* coefficients overlap (perhaps completely, although also */ 1381 1.1 christos /* perhaps only where zeros) */ 1382 1.1 christos if (overlap==DECPMAX) { /* aligned */ 1383 1.1 christos ub=buf+COFF; /* where msd will go */ 1384 1.1 christos #if QUAD 1385 1.1 christos UBFROMUS(buf+4, 0); /* clear quad's 00 */ 1386 1.1 christos #endif 1387 1.1 christos GETCOEFF(dfr, ub); /* decode from decFloat */ 1388 1.1 christos } 1389 1.1 christos else { /* unaligned */ 1390 1.1 christos ub=buf+COFF+DECPMAX-overlap; /* where MSD will go */ 1391 1.1 christos /* Fill the prefix gap with 0s; 8 will cover most common */ 1392 1.1 christos /* unalignments, so start with direct assignments (a loop is */ 1393 1.1 christos /* then used for any remaining -- the loop (and the one in a */ 1394 1.1 christos /* moment) is not then on the critical path because the number */ 1395 1.1 christos /* of additions is reduced by (at least) two in this case) */ 1396 1.1 christos UBFROMUI(buf+4, 0); /* [clears decQuad 00 too] */ 1397 1.1 christos UBFROMUI(buf+8, 0); 1398 1.1 christos if (ub>buf+12) { 1399 1.1 christos ut=buf+12; /* start any remaining */ 1400 1.1 christos for (; ut<ub; ut+=4) UBFROMUI(ut, 0); /* fill them */ 1401 1.1 christos } 1402 1.1 christos GETCOEFF(dfr, ub); /* decode from decFloat */ 1403 1.1 christos 1404 1.1 christos /* now move tail of rhs across to main acc; again use direct */ 1405 1.1 christos /* copies for 8 digits-worth */ 1406 1.1 christos UBFROMUI(acc+COFF+DECPMAX, UBTOUI(buf+COFF+DECPMAX)); 1407 1.1 christos UBFROMUI(acc+COFF+DECPMAX+4, UBTOUI(buf+COFF+DECPMAX+4)); 1408 1.1 christos if (buf+COFF+DECPMAX+8<ub+DECPMAX) { 1409 1.1 christos us=buf+COFF+DECPMAX+8; /* source */ 1410 1.1 christos ut=acc+COFF+DECPMAX+8; /* target */ 1411 1.1 christos for (; us<ub+DECPMAX; us+=4, ut+=4) UBFROMUI(ut, UBTOUI(us)); 1412 1.1 christos } 1413 1.1 christos } /* unaligned */ 1414 1.1 christos 1415 1.1 christos ulsd=acc+(ub-buf+DECPMAX-1); /* update LSD pointer */ 1416 1.1 christos 1417 1.1 christos /* Now do the add of the non-tail; this is all nicely aligned, */ 1418 1.1 christos /* and is over a multiple of four digits (because for Quad two */ 1419 1.1 christos /* zero digits were added on the left); words in both acc and */ 1420 1.1 christos /* buf (buf especially) will often be zero */ 1421 1.1 christos /* [byte-by-byte add, here, is about 15% slower total effect than */ 1422 1.1 christos /* the by-fours] */ 1423 1.1 christos 1424 1.1 christos /* Now effect the add; this is harder on a little-endian */ 1425 1.1 christos /* machine as the inter-digit carry cannot use the usual BCD */ 1426 1.1 christos /* addition trick because the bytes are loaded in the wrong order */ 1427 1.1 christos /* [this loop could be unrolled, but probably scarcely worth it] */ 1428 1.1 christos 1429 1.1 christos ut=acc+COFF+DECPMAX-4; /* target LSW (acc) */ 1430 1.1 christos us=buf+COFF+DECPMAX-4; /* source LSW (buf, to add to acc) */ 1431 1.1 christos 1432 1.1 christos #if !DECLITEND 1433 1.1 christos for (; ut>=acc+4; ut-=4, us-=4) { /* big-endian add loop */ 1434 1.1 christos /* bcd8 add */ 1435 1.1 christos carry+=UBTOUI(us); /* rhs + carry */ 1436 1.1 christos if (carry==0) continue; /* no-op */ 1437 1.1 christos carry+=UBTOUI(ut); /* lhs */ 1438 1.1 christos /* Big-endian BCD adjust (uses internal carry) */ 1439 1.1 christos carry+=0x76f6f6f6; /* note top nibble not all bits */ 1440 1.1 christos /* apply BCD adjust and save */ 1441 1.1 christos UBFROMUI(ut, (carry & 0x0f0f0f0f) - ((carry & 0x60606060)>>4)); 1442 1.1 christos carry>>=31; /* true carry was at far left */ 1443 1.1 christos } /* add loop */ 1444 1.1 christos #else 1445 1.1 christos for (; ut>=acc+4; ut-=4, us-=4) { /* little-endian add loop */ 1446 1.1 christos /* bcd8 add */ 1447 1.1 christos carry+=UBTOUI(us); /* rhs + carry */ 1448 1.1 christos if (carry==0) continue; /* no-op [common if unaligned] */ 1449 1.1 christos carry+=UBTOUI(ut); /* lhs */ 1450 1.1 christos /* Little-endian BCD adjust; inter-digit carry must be manual */ 1451 1.1 christos /* because the lsb from the array will be in the most-significant */ 1452 1.1 christos /* byte of carry */ 1453 1.1 christos carry+=0x76767676; /* note no inter-byte carries */ 1454 1.1 christos carry+=(carry & 0x80000000)>>15; 1455 1.1 christos carry+=(carry & 0x00800000)>>15; 1456 1.1 christos carry+=(carry & 0x00008000)>>15; 1457 1.1 christos carry-=(carry & 0x60606060)>>4; /* BCD adjust back */ 1458 1.1 christos UBFROMUI(ut, carry & 0x0f0f0f0f); /* clear debris and save */ 1459 1.1 christos /* here, final carry-out bit is at 0x00000080; move it ready */ 1460 1.1 christos /* for next word-add (i.e., to 0x01000000) */ 1461 1.1 christos carry=(carry & 0x00000080)<<17; 1462 1.1 christos } /* add loop */ 1463 1.1 christos #endif 1464 1.1 christos 1465 1.1 christos #if DECTRACE 1466 1.1 christos {bcdnum tum; 1467 1.1 christos printf("Add done, carry=%08lx, diffsign=%ld\n", (LI)carry, (LI)diffsign); 1468 1.1 christos tum.msd=umsd; /* acc+4; */ 1469 1.1 christos tum.lsd=ulsd; 1470 1.1 christos tum.exponent=0; 1471 1.1 christos tum.sign=0; 1472 1.1 christos decShowNum(&tum, "dfadd");} 1473 1.1 christos #endif 1474 1.1 christos } /* overlap possible */ 1475 1.1 christos 1476 1.1 christos /* ordering here is a little strange in order to have slowest path */ 1477 1.1 christos /* first in GCC asm listing */ 1478 1.1 christos if (diffsign) { /* subtraction */ 1479 1.1 christos if (!carry) { /* no carry out means RHS<LHS */ 1480 1.1 christos /* borrowed -- take ten's complement */ 1481 1.1 christos /* sign is lhs sign */ 1482 1.1 christos num.sign=DFWORD(dfl, 0) & DECFLOAT_Sign; 1483 1.1 christos 1484 1.1 christos /* invert the coefficient first by fours, then add one; space */ 1485 1.1 christos /* at the end of the buffer ensures the by-fours is always */ 1486 1.1 christos /* safe, but lsd+1 must be cleared to prevent a borrow */ 1487 1.1 christos /* if big-endian */ 1488 1.1 christos #if !DECLITEND 1489 1.1 christos *(ulsd+1)=0; 1490 1.1 christos #endif 1491 1.1 christos /* there are always at least four coefficient words */ 1492 1.1 christos UBFROMUI(umsd, 0x09090909-UBTOUI(umsd)); 1493 1.1 christos UBFROMUI(umsd+4, 0x09090909-UBTOUI(umsd+4)); 1494 1.1 christos UBFROMUI(umsd+8, 0x09090909-UBTOUI(umsd+8)); 1495 1.1 christos UBFROMUI(umsd+12, 0x09090909-UBTOUI(umsd+12)); 1496 1.1 christos #if DOUBLE 1497 1.1 christos #define BNEXT 16 1498 1.1 christos #elif QUAD 1499 1.1 christos UBFROMUI(umsd+16, 0x09090909-UBTOUI(umsd+16)); 1500 1.1 christos UBFROMUI(umsd+20, 0x09090909-UBTOUI(umsd+20)); 1501 1.1 christos UBFROMUI(umsd+24, 0x09090909-UBTOUI(umsd+24)); 1502 1.1 christos UBFROMUI(umsd+28, 0x09090909-UBTOUI(umsd+28)); 1503 1.1 christos UBFROMUI(umsd+32, 0x09090909-UBTOUI(umsd+32)); 1504 1.1 christos #define BNEXT 36 1505 1.1 christos #endif 1506 1.1 christos if (ulsd>=umsd+BNEXT) { /* unaligned */ 1507 1.1 christos /* eight will handle most unaligments for Double; 16 for Quad */ 1508 1.1 christos UBFROMUI(umsd+BNEXT, 0x09090909-UBTOUI(umsd+BNEXT)); 1509 1.1 christos UBFROMUI(umsd+BNEXT+4, 0x09090909-UBTOUI(umsd+BNEXT+4)); 1510 1.1 christos #if DOUBLE 1511 1.1 christos #define BNEXTY (BNEXT+8) 1512 1.1 christos #elif QUAD 1513 1.1 christos UBFROMUI(umsd+BNEXT+8, 0x09090909-UBTOUI(umsd+BNEXT+8)); 1514 1.1 christos UBFROMUI(umsd+BNEXT+12, 0x09090909-UBTOUI(umsd+BNEXT+12)); 1515 1.1 christos #define BNEXTY (BNEXT+16) 1516 1.1 christos #endif 1517 1.1 christos if (ulsd>=umsd+BNEXTY) { /* very unaligned */ 1518 1.1 christos ut=umsd+BNEXTY; /* -> continue */ 1519 1.1 christos for (;;ut+=4) { 1520 1.1 christos UBFROMUI(ut, 0x09090909-UBTOUI(ut)); /* invert four digits */ 1521 1.1 christos if (ut>=ulsd-3) break; /* all done */ 1522 1.1 christos } 1523 1.1 christos } 1524 1.1 christos } 1525 1.1 christos /* complete the ten's complement by adding 1 */ 1526 1.1 christos for (ub=ulsd; *ub==9; ub--) *ub=0; 1527 1.1 christos *ub+=1; 1528 1.1 christos } /* borrowed */ 1529 1.1 christos 1530 1.1 christos else { /* carry out means RHS>=LHS */ 1531 1.1 christos num.sign=DFWORD(dfr, 0) & DECFLOAT_Sign; 1532 1.1 christos /* all done except for the special IEEE 754 exact-zero-result */ 1533 1.1 christos /* rule (see above); while testing for zero, strip leading */ 1534 1.1 christos /* zeros (which will save decFinalize doing it) (this is in */ 1535 1.1 christos /* diffsign path, so carry impossible and true umsd is */ 1536 1.1 christos /* acc+COFF) */ 1537 1.1 christos 1538 1.1 christos /* Check the initial coefficient area using the fast macro; */ 1539 1.1 christos /* this will often be all that needs to be done (as on the */ 1540 1.1 christos /* worst-case path when the subtraction was aligned and */ 1541 1.1 christos /* full-length) */ 1542 1.1 christos if (ISCOEFFZERO(acc+COFF)) { 1543 1.1 christos umsd=acc+COFF+DECPMAX-1; /* so far, so zero */ 1544 1.1 christos if (ulsd>umsd) { /* more to check */ 1545 1.1 christos umsd++; /* to align after checked area */ 1546 1.1 christos for (; UBTOUI(umsd)==0 && umsd+3<ulsd;) umsd+=4; 1547 1.1 christos for (; *umsd==0 && umsd<ulsd;) umsd++; 1548 1.1 christos } 1549 1.1 christos if (*umsd==0) { /* must be true zero (and diffsign) */ 1550 1.1 christos num.sign=0; /* assume + */ 1551 1.1 christos if (set->round==DEC_ROUND_FLOOR) num.sign=DECFLOAT_Sign; 1552 1.1 christos } 1553 1.1 christos } 1554 1.1 christos /* [else was not zero, might still have leading zeros] */ 1555 1.1 christos } /* subtraction gave positive result */ 1556 1.1 christos } /* diffsign */ 1557 1.1 christos 1558 1.1 christos else { /* same-sign addition */ 1559 1.1 christos num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; 1560 1.1 christos #if DOUBLE 1561 1.1 christos if (carry) { /* only possible with decDouble */ 1562 1.1 christos *(acc+3)=1; /* [Quad has leading 00] */ 1563 1.1 christos umsd=acc+3; 1564 1.1 christos } 1565 1.1 christos #endif 1566 1.1 christos } /* same sign */ 1567 1.1 christos 1568 1.1 christos num.msd=umsd; /* set MSD .. */ 1569 1.1 christos num.lsd=ulsd; /* .. and LSD */ 1570 1.1 christos num.exponent=bexpr-DECBIAS; /* set exponent to smaller, unbiassed */ 1571 1.1 christos 1572 1.1 christos #if DECTRACE 1573 1.1 christos decFloatShow(dfl, "dfl"); 1574 1.1 christos decFloatShow(dfr, "dfr"); 1575 1.1 christos decShowNum(&num, "postadd"); 1576 1.1 christos #endif 1577 1.1 christos return decFinalize(result, &num, set); /* round, check, and lay out */ 1578 1.1 christos } /* decFloatAdd */ 1579 1.1 christos 1580 1.1 christos /* ------------------------------------------------------------------ */ 1581 1.1 christos /* decFloatAnd -- logical digitwise AND of two decFloats */ 1582 1.1 christos /* */ 1583 1.1 christos /* result gets the result of ANDing dfl and dfr */ 1584 1.1 christos /* dfl is the first decFloat (lhs) */ 1585 1.1 christos /* dfr is the second decFloat (rhs) */ 1586 1.1 christos /* set is the context */ 1587 1.1 christos /* returns result, which will be canonical with sign=0 */ 1588 1.1 christos /* */ 1589 1.1 christos /* The operands must be positive, finite with exponent q=0, and */ 1590 1.1 christos /* comprise just zeros and ones; if not, Invalid operation results. */ 1591 1.1 christos /* ------------------------------------------------------------------ */ 1592 1.1 christos decFloat * decFloatAnd(decFloat *result, 1593 1.1 christos const decFloat *dfl, const decFloat *dfr, 1594 1.1 christos decContext *set) { 1595 1.1 christos if (!DFISUINT01(dfl) || !DFISUINT01(dfr) 1596 1.1 christos || !DFISCC01(dfl) || !DFISCC01(dfr)) return decInvalid(result, set); 1597 1.1 christos /* the operands are positive finite integers (q=0) with just 0s and 1s */ 1598 1.1 christos #if DOUBLE 1599 1.1 christos DFWORD(result, 0)=ZEROWORD 1600 1.1 christos |((DFWORD(dfl, 0) & DFWORD(dfr, 0))&0x04009124); 1601 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) & DFWORD(dfr, 1))&0x49124491; 1602 1.1 christos #elif QUAD 1603 1.1 christos DFWORD(result, 0)=ZEROWORD 1604 1.1 christos |((DFWORD(dfl, 0) & DFWORD(dfr, 0))&0x04000912); 1605 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) & DFWORD(dfr, 1))&0x44912449; 1606 1.1 christos DFWORD(result, 2)=(DFWORD(dfl, 2) & DFWORD(dfr, 2))&0x12449124; 1607 1.1 christos DFWORD(result, 3)=(DFWORD(dfl, 3) & DFWORD(dfr, 3))&0x49124491; 1608 1.1 christos #endif 1609 1.1 christos return result; 1610 1.1 christos } /* decFloatAnd */ 1611 1.1 christos 1612 1.1 christos /* ------------------------------------------------------------------ */ 1613 1.1 christos /* decFloatCanonical -- copy a decFloat, making canonical */ 1614 1.1 christos /* */ 1615 1.1 christos /* result gets the canonicalized df */ 1616 1.1 christos /* df is the decFloat to copy and make canonical */ 1617 1.1 christos /* returns result */ 1618 1.1 christos /* */ 1619 1.1 christos /* This works on specials, too; no error or exception is possible. */ 1620 1.1 christos /* ------------------------------------------------------------------ */ 1621 1.1 christos decFloat * decFloatCanonical(decFloat *result, const decFloat *df) { 1622 1.1 christos return decCanonical(result, df); 1623 1.1 christos } /* decFloatCanonical */ 1624 1.1 christos 1625 1.1 christos /* ------------------------------------------------------------------ */ 1626 1.1 christos /* decFloatClass -- return the class of a decFloat */ 1627 1.1 christos /* */ 1628 1.1 christos /* df is the decFloat to test */ 1629 1.1 christos /* returns the decClass that df falls into */ 1630 1.1 christos /* ------------------------------------------------------------------ */ 1631 1.1 christos enum decClass decFloatClass(const decFloat *df) { 1632 1.1 christos Int exp; /* exponent */ 1633 1.1 christos if (DFISSPECIAL(df)) { 1634 1.1 christos if (DFISQNAN(df)) return DEC_CLASS_QNAN; 1635 1.1 christos if (DFISSNAN(df)) return DEC_CLASS_SNAN; 1636 1.1 christos /* must be an infinity */ 1637 1.1 christos if (DFISSIGNED(df)) return DEC_CLASS_NEG_INF; 1638 1.1 christos return DEC_CLASS_POS_INF; 1639 1.1 christos } 1640 1.1 christos if (DFISZERO(df)) { /* quite common */ 1641 1.1 christos if (DFISSIGNED(df)) return DEC_CLASS_NEG_ZERO; 1642 1.1 christos return DEC_CLASS_POS_ZERO; 1643 1.1 christos } 1644 1.1 christos /* is finite and non-zero; similar code to decFloatIsNormal, here */ 1645 1.1 christos /* [this could be speeded up slightly by in-lining decFloatDigits] */ 1646 1.1 christos exp=GETEXPUN(df) /* get unbiased exponent .. */ 1647 1.1 christos +decFloatDigits(df)-1; /* .. and make adjusted exponent */ 1648 1.1 christos if (exp>=DECEMIN) { /* is normal */ 1649 1.1 christos if (DFISSIGNED(df)) return DEC_CLASS_NEG_NORMAL; 1650 1.1 christos return DEC_CLASS_POS_NORMAL; 1651 1.1 christos } 1652 1.1 christos /* is subnormal */ 1653 1.1 christos if (DFISSIGNED(df)) return DEC_CLASS_NEG_SUBNORMAL; 1654 1.1 christos return DEC_CLASS_POS_SUBNORMAL; 1655 1.1 christos } /* decFloatClass */ 1656 1.1 christos 1657 1.1 christos /* ------------------------------------------------------------------ */ 1658 1.1 christos /* decFloatClassString -- return the class of a decFloat as a string */ 1659 1.1 christos /* */ 1660 1.1 christos /* df is the decFloat to test */ 1661 1.1 christos /* returns a constant string describing the class df falls into */ 1662 1.1 christos /* ------------------------------------------------------------------ */ 1663 1.1 christos const char *decFloatClassString(const decFloat *df) { 1664 1.1 christos enum decClass eclass=decFloatClass(df); 1665 1.1 christos if (eclass==DEC_CLASS_POS_NORMAL) return DEC_ClassString_PN; 1666 1.1 christos if (eclass==DEC_CLASS_NEG_NORMAL) return DEC_ClassString_NN; 1667 1.1 christos if (eclass==DEC_CLASS_POS_ZERO) return DEC_ClassString_PZ; 1668 1.1 christos if (eclass==DEC_CLASS_NEG_ZERO) return DEC_ClassString_NZ; 1669 1.1 christos if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS; 1670 1.1 christos if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS; 1671 1.1 christos if (eclass==DEC_CLASS_POS_INF) return DEC_ClassString_PI; 1672 1.1 christos if (eclass==DEC_CLASS_NEG_INF) return DEC_ClassString_NI; 1673 1.1 christos if (eclass==DEC_CLASS_QNAN) return DEC_ClassString_QN; 1674 1.1 christos if (eclass==DEC_CLASS_SNAN) return DEC_ClassString_SN; 1675 1.1 christos return DEC_ClassString_UN; /* Unknown */ 1676 1.1 christos } /* decFloatClassString */ 1677 1.1 christos 1678 1.1 christos /* ------------------------------------------------------------------ */ 1679 1.1 christos /* decFloatCompare -- compare two decFloats; quiet NaNs allowed */ 1680 1.1 christos /* */ 1681 1.1 christos /* result gets the result of comparing dfl and dfr */ 1682 1.1 christos /* dfl is the first decFloat (lhs) */ 1683 1.1 christos /* dfr is the second decFloat (rhs) */ 1684 1.1 christos /* set is the context */ 1685 1.1 christos /* returns result, which may be -1, 0, 1, or NaN (Unordered) */ 1686 1.1 christos /* ------------------------------------------------------------------ */ 1687 1.1 christos decFloat * decFloatCompare(decFloat *result, 1688 1.1 christos const decFloat *dfl, const decFloat *dfr, 1689 1.1 christos decContext *set) { 1690 1.1 christos Int comp; /* work */ 1691 1.1 christos /* NaNs are handled as usual */ 1692 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 1693 1.1 christos /* numeric comparison needed */ 1694 1.1 christos comp=decNumCompare(dfl, dfr, 0); 1695 1.1 christos decFloatZero(result); 1696 1.1 christos if (comp==0) return result; 1697 1.1 christos DFBYTE(result, DECBYTES-1)=0x01; /* LSD=1 */ 1698 1.1 christos if (comp<0) DFBYTE(result, 0)|=0x80; /* set sign bit */ 1699 1.1 christos return result; 1700 1.1 christos } /* decFloatCompare */ 1701 1.1 christos 1702 1.1 christos /* ------------------------------------------------------------------ */ 1703 1.1 christos /* decFloatCompareSignal -- compare two decFloats; all NaNs signal */ 1704 1.1 christos /* */ 1705 1.1 christos /* result gets the result of comparing dfl and dfr */ 1706 1.1 christos /* dfl is the first decFloat (lhs) */ 1707 1.1 christos /* dfr is the second decFloat (rhs) */ 1708 1.1 christos /* set is the context */ 1709 1.1 christos /* returns result, which may be -1, 0, 1, or NaN (Unordered) */ 1710 1.1 christos /* ------------------------------------------------------------------ */ 1711 1.1 christos decFloat * decFloatCompareSignal(decFloat *result, 1712 1.1 christos const decFloat *dfl, const decFloat *dfr, 1713 1.1 christos decContext *set) { 1714 1.1 christos Int comp; /* work */ 1715 1.1 christos /* NaNs are handled as usual, except that all NaNs signal */ 1716 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) { 1717 1.1 christos set->status|=DEC_Invalid_operation; 1718 1.1 christos return decNaNs(result, dfl, dfr, set); 1719 1.1 christos } 1720 1.1 christos /* numeric comparison needed */ 1721 1.1 christos comp=decNumCompare(dfl, dfr, 0); 1722 1.1 christos decFloatZero(result); 1723 1.1 christos if (comp==0) return result; 1724 1.1 christos DFBYTE(result, DECBYTES-1)=0x01; /* LSD=1 */ 1725 1.1 christos if (comp<0) DFBYTE(result, 0)|=0x80; /* set sign bit */ 1726 1.1 christos return result; 1727 1.1 christos } /* decFloatCompareSignal */ 1728 1.1 christos 1729 1.1 christos /* ------------------------------------------------------------------ */ 1730 1.1 christos /* decFloatCompareTotal -- compare two decFloats with total ordering */ 1731 1.1 christos /* */ 1732 1.1 christos /* result gets the result of comparing dfl and dfr */ 1733 1.1 christos /* dfl is the first decFloat (lhs) */ 1734 1.1 christos /* dfr is the second decFloat (rhs) */ 1735 1.1 christos /* returns result, which may be -1, 0, or 1 */ 1736 1.1 christos /* ------------------------------------------------------------------ */ 1737 1.1 christos decFloat * decFloatCompareTotal(decFloat *result, 1738 1.1 christos const decFloat *dfl, const decFloat *dfr) { 1739 1.1 christos Int comp; /* work */ 1740 1.1 christos uInt uiwork; /* for macros */ 1741 1.1 christos #if QUAD 1742 1.1 christos uShort uswork; /* .. */ 1743 1.1 christos #endif 1744 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) { 1745 1.1 christos Int nanl, nanr; /* work */ 1746 1.1 christos /* morph NaNs to +/- 1 or 2, leave numbers as 0 */ 1747 1.1 christos nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2; /* quiet > signalling */ 1748 1.1 christos if (DFISSIGNED(dfl)) nanl=-nanl; 1749 1.1 christos nanr=DFISSNAN(dfr)+DFISQNAN(dfr)*2; 1750 1.1 christos if (DFISSIGNED(dfr)) nanr=-nanr; 1751 1.1 christos if (nanl>nanr) comp=+1; 1752 1.1 christos else if (nanl<nanr) comp=-1; 1753 1.1 christos else { /* NaNs are the same type and sign .. must compare payload */ 1754 1.1 christos /* buffers need +2 for QUAD */ 1755 1.1 christos uByte bufl[DECPMAX+4]; /* for LHS coefficient + foot */ 1756 1.1 christos uByte bufr[DECPMAX+4]; /* for RHS coefficient + foot */ 1757 1.1 christos uByte *ub, *uc; /* work */ 1758 1.1 christos Int sigl; /* signum of LHS */ 1759 1.1 christos sigl=(DFISSIGNED(dfl) ? -1 : +1); 1760 1.1 christos 1761 1.1 christos /* decode the coefficients */ 1762 1.1 christos /* (shift both right two if Quad to make a multiple of four) */ 1763 1.1 christos #if QUAD 1764 1.1 christos UBFROMUS(bufl, 0); 1765 1.1 christos UBFROMUS(bufr, 0); 1766 1.1 christos #endif 1767 1.1 christos GETCOEFF(dfl, bufl+QUAD*2); /* decode from decFloat */ 1768 1.1 christos GETCOEFF(dfr, bufr+QUAD*2); /* .. */ 1769 1.1 christos /* all multiples of four, here */ 1770 1.1 christos comp=0; /* assume equal */ 1771 1.1 christos for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) { 1772 1.1 christos uInt ui=UBTOUI(ub); 1773 1.1 christos if (ui==UBTOUI(uc)) continue; /* so far so same */ 1774 1.1 christos /* about to find a winner; go by bytes in case little-endian */ 1775 1.1 christos for (;; ub++, uc++) { 1776 1.1 christos if (*ub==*uc) continue; 1777 1.1 christos if (*ub>*uc) comp=sigl; /* difference found */ 1778 1.1 christos else comp=-sigl; /* .. */ 1779 1.1 christos break; 1780 1.1 christos } 1781 1.1 christos } 1782 1.1 christos } /* same NaN type and sign */ 1783 1.1 christos } 1784 1.1 christos else { 1785 1.1 christos /* numeric comparison needed */ 1786 1.1 christos comp=decNumCompare(dfl, dfr, 1); /* total ordering */ 1787 1.1 christos } 1788 1.1 christos decFloatZero(result); 1789 1.1 christos if (comp==0) return result; 1790 1.1 christos DFBYTE(result, DECBYTES-1)=0x01; /* LSD=1 */ 1791 1.1 christos if (comp<0) DFBYTE(result, 0)|=0x80; /* set sign bit */ 1792 1.1 christos return result; 1793 1.1 christos } /* decFloatCompareTotal */ 1794 1.1 christos 1795 1.1 christos /* ------------------------------------------------------------------ */ 1796 1.1 christos /* decFloatCompareTotalMag -- compare magnitudes with total ordering */ 1797 1.1 christos /* */ 1798 1.1 christos /* result gets the result of comparing abs(dfl) and abs(dfr) */ 1799 1.1 christos /* dfl is the first decFloat (lhs) */ 1800 1.1 christos /* dfr is the second decFloat (rhs) */ 1801 1.1 christos /* returns result, which may be -1, 0, or 1 */ 1802 1.1 christos /* ------------------------------------------------------------------ */ 1803 1.1 christos decFloat * decFloatCompareTotalMag(decFloat *result, 1804 1.1 christos const decFloat *dfl, const decFloat *dfr) { 1805 1.1 christos decFloat a, b; /* for copy if needed */ 1806 1.1 christos /* copy and redirect signed operand(s) */ 1807 1.1 christos if (DFISSIGNED(dfl)) { 1808 1.1 christos decFloatCopyAbs(&a, dfl); 1809 1.1 christos dfl=&a; 1810 1.1 christos } 1811 1.1 christos if (DFISSIGNED(dfr)) { 1812 1.1 christos decFloatCopyAbs(&b, dfr); 1813 1.1 christos dfr=&b; 1814 1.1 christos } 1815 1.1 christos return decFloatCompareTotal(result, dfl, dfr); 1816 1.1 christos } /* decFloatCompareTotalMag */ 1817 1.1 christos 1818 1.1 christos /* ------------------------------------------------------------------ */ 1819 1.1 christos /* decFloatCopy -- copy a decFloat as-is */ 1820 1.1 christos /* */ 1821 1.1 christos /* result gets the copy of dfl */ 1822 1.1 christos /* dfl is the decFloat to copy */ 1823 1.1 christos /* returns result */ 1824 1.1 christos /* */ 1825 1.1 christos /* This is a bitwise operation; no errors or exceptions are possible. */ 1826 1.1 christos /* ------------------------------------------------------------------ */ 1827 1.1 christos decFloat * decFloatCopy(decFloat *result, const decFloat *dfl) { 1828 1.1 christos if (dfl!=result) *result=*dfl; /* copy needed */ 1829 1.1 christos return result; 1830 1.1 christos } /* decFloatCopy */ 1831 1.1 christos 1832 1.1 christos /* ------------------------------------------------------------------ */ 1833 1.1 christos /* decFloatCopyAbs -- copy a decFloat as-is and set sign bit to 0 */ 1834 1.1 christos /* */ 1835 1.1 christos /* result gets the copy of dfl with sign bit 0 */ 1836 1.1 christos /* dfl is the decFloat to copy */ 1837 1.1 christos /* returns result */ 1838 1.1 christos /* */ 1839 1.1 christos /* This is a bitwise operation; no errors or exceptions are possible. */ 1840 1.1 christos /* ------------------------------------------------------------------ */ 1841 1.1 christos decFloat * decFloatCopyAbs(decFloat *result, const decFloat *dfl) { 1842 1.1 christos if (dfl!=result) *result=*dfl; /* copy needed */ 1843 1.1 christos DFBYTE(result, 0)&=~0x80; /* zero sign bit */ 1844 1.1 christos return result; 1845 1.1 christos } /* decFloatCopyAbs */ 1846 1.1 christos 1847 1.1 christos /* ------------------------------------------------------------------ */ 1848 1.1 christos /* decFloatCopyNegate -- copy a decFloat as-is with inverted sign bit */ 1849 1.1 christos /* */ 1850 1.1 christos /* result gets the copy of dfl with sign bit inverted */ 1851 1.1 christos /* dfl is the decFloat to copy */ 1852 1.1 christos /* returns result */ 1853 1.1 christos /* */ 1854 1.1 christos /* This is a bitwise operation; no errors or exceptions are possible. */ 1855 1.1 christos /* ------------------------------------------------------------------ */ 1856 1.1 christos decFloat * decFloatCopyNegate(decFloat *result, const decFloat *dfl) { 1857 1.1 christos if (dfl!=result) *result=*dfl; /* copy needed */ 1858 1.1 christos DFBYTE(result, 0)^=0x80; /* invert sign bit */ 1859 1.1 christos return result; 1860 1.1 christos } /* decFloatCopyNegate */ 1861 1.1 christos 1862 1.1 christos /* ------------------------------------------------------------------ */ 1863 1.1 christos /* decFloatCopySign -- copy a decFloat with the sign of another */ 1864 1.1 christos /* */ 1865 1.1 christos /* result gets the result of copying dfl with the sign of dfr */ 1866 1.1 christos /* dfl is the first decFloat (lhs) */ 1867 1.1 christos /* dfr is the second decFloat (rhs) */ 1868 1.1 christos /* returns result */ 1869 1.1 christos /* */ 1870 1.1 christos /* This is a bitwise operation; no errors or exceptions are possible. */ 1871 1.1 christos /* ------------------------------------------------------------------ */ 1872 1.1 christos decFloat * decFloatCopySign(decFloat *result, 1873 1.1 christos const decFloat *dfl, const decFloat *dfr) { 1874 1.1 christos uByte sign=(uByte)(DFBYTE(dfr, 0)&0x80); /* save sign bit */ 1875 1.1 christos if (dfl!=result) *result=*dfl; /* copy needed */ 1876 1.1 christos DFBYTE(result, 0)&=~0x80; /* clear sign .. */ 1877 1.1 christos DFBYTE(result, 0)=(uByte)(DFBYTE(result, 0)|sign); /* .. and set saved */ 1878 1.1 christos return result; 1879 1.1 christos } /* decFloatCopySign */ 1880 1.1 christos 1881 1.1 christos /* ------------------------------------------------------------------ */ 1882 1.1 christos /* decFloatDigits -- return the number of digits in a decFloat */ 1883 1.1 christos /* */ 1884 1.1 christos /* df is the decFloat to investigate */ 1885 1.1 christos /* returns the number of significant digits in the decFloat; a */ 1886 1.1 christos /* zero coefficient returns 1 as does an infinity (a NaN returns */ 1887 1.1 christos /* the number of digits in the payload) */ 1888 1.1 christos /* ------------------------------------------------------------------ */ 1889 1.1 christos /* private macro to extract a declet according to provided formula */ 1890 1.1 christos /* (form), and if it is non-zero then return the calculated digits */ 1891 1.1 christos /* depending on the declet number (n), where n=0 for the most */ 1892 1.1 christos /* significant declet; uses uInt dpd for work */ 1893 1.1 christos #define dpdlenchk(n, form) {dpd=(form)&0x3ff; \ 1894 1.1 christos if (dpd) return (DECPMAX-1-3*(n))-(3-DPD2BCD8[dpd*4+3]);} 1895 1.1 christos /* next one is used when it is known that the declet must be */ 1896 1.1 christos /* non-zero, or is the final zero declet */ 1897 1.1 christos #define dpdlendun(n, form) {dpd=(form)&0x3ff; \ 1898 1.1 christos if (dpd==0) return 1; \ 1899 1.1 christos return (DECPMAX-1-3*(n))-(3-DPD2BCD8[dpd*4+3]);} 1900 1.1 christos 1901 1.1 christos uInt decFloatDigits(const decFloat *df) { 1902 1.1 christos uInt dpd; /* work */ 1903 1.1 christos uInt sourhi=DFWORD(df, 0); /* top word from source decFloat */ 1904 1.1 christos #if QUAD 1905 1.1 christos uInt sourmh, sourml; 1906 1.1 christos #endif 1907 1.1 christos uInt sourlo; 1908 1.1 christos 1909 1.1 christos if (DFISINF(df)) return 1; 1910 1.1 christos /* A NaN effectively has an MSD of 0; otherwise if non-zero MSD */ 1911 1.1 christos /* then the coefficient is full-length */ 1912 1.1 christos if (!DFISNAN(df) && DECCOMBMSD[sourhi>>26]) return DECPMAX; 1913 1.1 christos 1914 1.1 christos #if DOUBLE 1915 1.1 christos if (sourhi&0x0003ffff) { /* ends in first */ 1916 1.1 christos dpdlenchk(0, sourhi>>8); 1917 1.1 christos sourlo=DFWORD(df, 1); 1918 1.1 christos dpdlendun(1, (sourhi<<2) | (sourlo>>30)); 1919 1.1 christos } /* [cannot drop through] */ 1920 1.1 christos sourlo=DFWORD(df, 1); /* sourhi not involved now */ 1921 1.1 christos if (sourlo&0xfff00000) { /* in one of first two */ 1922 1.1 christos dpdlenchk(1, sourlo>>30); /* very rare */ 1923 1.1 christos dpdlendun(2, sourlo>>20); 1924 1.1 christos } /* [cannot drop through] */ 1925 1.1 christos dpdlenchk(3, sourlo>>10); 1926 1.1 christos dpdlendun(4, sourlo); 1927 1.1 christos /* [cannot drop through] */ 1928 1.1 christos 1929 1.1 christos #elif QUAD 1930 1.1 christos if (sourhi&0x00003fff) { /* ends in first */ 1931 1.1 christos dpdlenchk(0, sourhi>>4); 1932 1.1 christos sourmh=DFWORD(df, 1); 1933 1.1 christos dpdlendun(1, ((sourhi)<<6) | (sourmh>>26)); 1934 1.1 christos } /* [cannot drop through] */ 1935 1.1 christos sourmh=DFWORD(df, 1); 1936 1.1 christos if (sourmh) { 1937 1.1 christos dpdlenchk(1, sourmh>>26); 1938 1.1 christos dpdlenchk(2, sourmh>>16); 1939 1.1 christos dpdlenchk(3, sourmh>>6); 1940 1.1 christos sourml=DFWORD(df, 2); 1941 1.1 christos dpdlendun(4, ((sourmh)<<4) | (sourml>>28)); 1942 1.1 christos } /* [cannot drop through] */ 1943 1.1 christos sourml=DFWORD(df, 2); 1944 1.1 christos if (sourml) { 1945 1.1 christos dpdlenchk(4, sourml>>28); 1946 1.1 christos dpdlenchk(5, sourml>>18); 1947 1.1 christos dpdlenchk(6, sourml>>8); 1948 1.1 christos sourlo=DFWORD(df, 3); 1949 1.1 christos dpdlendun(7, ((sourml)<<2) | (sourlo>>30)); 1950 1.1 christos } /* [cannot drop through] */ 1951 1.1 christos sourlo=DFWORD(df, 3); 1952 1.1 christos if (sourlo&0xfff00000) { /* in one of first two */ 1953 1.1 christos dpdlenchk(7, sourlo>>30); /* very rare */ 1954 1.1 christos dpdlendun(8, sourlo>>20); 1955 1.1 christos } /* [cannot drop through] */ 1956 1.1 christos dpdlenchk(9, sourlo>>10); 1957 1.1 christos dpdlendun(10, sourlo); 1958 1.1 christos /* [cannot drop through] */ 1959 1.1 christos #endif 1960 1.1 christos } /* decFloatDigits */ 1961 1.1 christos 1962 1.1 christos /* ------------------------------------------------------------------ */ 1963 1.1 christos /* decFloatDivide -- divide a decFloat by another */ 1964 1.1 christos /* */ 1965 1.1 christos /* result gets the result of dividing dfl by dfr: */ 1966 1.1 christos /* dfl is the first decFloat (lhs) */ 1967 1.1 christos /* dfr is the second decFloat (rhs) */ 1968 1.1 christos /* set is the context */ 1969 1.1 christos /* returns result */ 1970 1.1 christos /* */ 1971 1.1 christos /* ------------------------------------------------------------------ */ 1972 1.1 christos /* This is just a wrapper. */ 1973 1.1 christos decFloat * decFloatDivide(decFloat *result, 1974 1.1 christos const decFloat *dfl, const decFloat *dfr, 1975 1.1 christos decContext *set) { 1976 1.1 christos return decDivide(result, dfl, dfr, set, DIVIDE); 1977 1.1 christos } /* decFloatDivide */ 1978 1.1 christos 1979 1.1 christos /* ------------------------------------------------------------------ */ 1980 1.1 christos /* decFloatDivideInteger -- integer divide a decFloat by another */ 1981 1.1 christos /* */ 1982 1.1 christos /* result gets the result of dividing dfl by dfr: */ 1983 1.1 christos /* dfl is the first decFloat (lhs) */ 1984 1.1 christos /* dfr is the second decFloat (rhs) */ 1985 1.1 christos /* set is the context */ 1986 1.1 christos /* returns result */ 1987 1.1 christos /* */ 1988 1.1 christos /* ------------------------------------------------------------------ */ 1989 1.1 christos decFloat * decFloatDivideInteger(decFloat *result, 1990 1.1 christos const decFloat *dfl, const decFloat *dfr, 1991 1.1 christos decContext *set) { 1992 1.1 christos return decDivide(result, dfl, dfr, set, DIVIDEINT); 1993 1.1 christos } /* decFloatDivideInteger */ 1994 1.1 christos 1995 1.1 christos /* ------------------------------------------------------------------ */ 1996 1.1 christos /* decFloatFMA -- multiply and add three decFloats, fused */ 1997 1.1 christos /* */ 1998 1.1 christos /* result gets the result of (dfl*dfr)+dff with a single rounding */ 1999 1.1 christos /* dfl is the first decFloat (lhs) */ 2000 1.1 christos /* dfr is the second decFloat (rhs) */ 2001 1.1 christos /* dff is the final decFloat (fhs) */ 2002 1.1 christos /* set is the context */ 2003 1.1 christos /* returns result */ 2004 1.1 christos /* */ 2005 1.1 christos /* ------------------------------------------------------------------ */ 2006 1.1 christos decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, 2007 1.1 christos const decFloat *dfr, const decFloat *dff, 2008 1.1 christos decContext *set) { 2009 1.1 christos 2010 1.1 christos /* The accumulator has the bytes needed for FiniteMultiply, plus */ 2011 1.1 christos /* one byte to the left in case of carry, plus DECPMAX+2 to the */ 2012 1.1 christos /* right for the final addition (up to full fhs + round & sticky) */ 2013 1.1 christos #define FMALEN (ROUNDUP4(1+ (DECPMAX9*18+1) +DECPMAX+2)) 2014 1.1 christos uByte acc[FMALEN]; /* for multiplied coefficient in BCD */ 2015 1.1 christos /* .. and for final result */ 2016 1.1 christos bcdnum mul; /* for multiplication result */ 2017 1.1 christos bcdnum fin; /* for final operand, expanded */ 2018 1.1 christos uByte coe[ROUNDUP4(DECPMAX)]; /* dff coefficient in BCD */ 2019 1.1 christos bcdnum *hi, *lo; /* bcdnum with higher/lower exponent */ 2020 1.1 christos uInt diffsign; /* non-zero if signs differ */ 2021 1.1 christos uInt hipad; /* pad digit for hi if needed */ 2022 1.1 christos Int padding; /* excess exponent */ 2023 1.1 christos uInt carry; /* +1 for ten's complement and during add */ 2024 1.1 christos uByte *ub, *uh, *ul; /* work */ 2025 1.1 christos uInt uiwork; /* for macros */ 2026 1.1 christos 2027 1.1 christos /* handle all the special values [any special operand leads to a */ 2028 1.1 christos /* special result] */ 2029 1.1 christos if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr) || DFISSPECIAL(dff)) { 2030 1.1 christos decFloat proxy; /* multiplication result proxy */ 2031 1.1 christos /* NaNs are handled as usual, giving priority to sNaNs */ 2032 1.1 christos if (DFISSNAN(dfl) || DFISSNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2033 1.1 christos if (DFISSNAN(dff)) return decNaNs(result, dff, NULL, set); 2034 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2035 1.1 christos if (DFISNAN(dff)) return decNaNs(result, dff, NULL, set); 2036 1.1 christos /* One or more of the three is infinite */ 2037 1.1 christos /* infinity times zero is bad */ 2038 1.1 christos decFloatZero(&proxy); 2039 1.1 christos if (DFISINF(dfl)) { 2040 1.1 christos if (DFISZERO(dfr)) return decInvalid(result, set); 2041 1.1 christos decInfinity(&proxy, &proxy); 2042 1.1 christos } 2043 1.1 christos else if (DFISINF(dfr)) { 2044 1.1 christos if (DFISZERO(dfl)) return decInvalid(result, set); 2045 1.1 christos decInfinity(&proxy, &proxy); 2046 1.1 christos } 2047 1.1 christos /* compute sign of multiplication and place in proxy */ 2048 1.1 christos DFWORD(&proxy, 0)|=(DFWORD(dfl, 0)^DFWORD(dfr, 0))&DECFLOAT_Sign; 2049 1.1 christos if (!DFISINF(dff)) return decFloatCopy(result, &proxy); 2050 1.1 christos /* dff is Infinite */ 2051 1.1 christos if (!DFISINF(&proxy)) return decInfinity(result, dff); 2052 1.1 christos /* both sides of addition are infinite; different sign is bad */ 2053 1.1 christos if ((DFWORD(dff, 0)&DECFLOAT_Sign)!=(DFWORD(&proxy, 0)&DECFLOAT_Sign)) 2054 1.1 christos return decInvalid(result, set); 2055 1.1 christos return decFloatCopy(result, &proxy); 2056 1.1 christos } 2057 1.1 christos 2058 1.1 christos /* Here when all operands are finite */ 2059 1.1 christos 2060 1.1 christos /* First multiply dfl*dfr */ 2061 1.1 christos decFiniteMultiply(&mul, acc+1, dfl, dfr); 2062 1.1 christos /* The multiply is complete, exact and unbounded, and described in */ 2063 1.1 christos /* mul with the coefficient held in acc[1...] */ 2064 1.1 christos 2065 1.1 christos /* now add in dff; the algorithm is essentially the same as */ 2066 1.1 christos /* decFloatAdd, but the code is different because the code there */ 2067 1.1 christos /* is highly optimized for adding two numbers of the same size */ 2068 1.1 christos fin.exponent=GETEXPUN(dff); /* get dff exponent and sign */ 2069 1.1 christos fin.sign=DFWORD(dff, 0)&DECFLOAT_Sign; 2070 1.1 christos diffsign=mul.sign^fin.sign; /* note if signs differ */ 2071 1.1 christos fin.msd=coe; 2072 1.1 christos fin.lsd=coe+DECPMAX-1; 2073 1.1 christos GETCOEFF(dff, coe); /* extract the coefficient */ 2074 1.1 christos 2075 1.1 christos /* now set hi and lo so that hi points to whichever of mul and fin */ 2076 1.1 christos /* has the higher exponent and lo points to the other [don't care, */ 2077 1.1 christos /* if the same]. One coefficient will be in acc, the other in coe. */ 2078 1.1 christos if (mul.exponent>=fin.exponent) { 2079 1.1 christos hi=&mul; 2080 1.1 christos lo=&fin; 2081 1.1 christos } 2082 1.1 christos else { 2083 1.1 christos hi=&fin; 2084 1.1 christos lo=&mul; 2085 1.1 christos } 2086 1.1 christos 2087 1.1 christos /* remove leading zeros on both operands; this will save time later */ 2088 1.1 christos /* and make testing for zero trivial (tests are safe because acc */ 2089 1.1 christos /* and coe are rounded up to uInts) */ 2090 1.1 christos for (; UBTOUI(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4; 2091 1.1 christos for (; *hi->msd==0 && hi->msd<hi->lsd;) hi->msd++; 2092 1.1 christos for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; 2093 1.1 christos for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++; 2094 1.1 christos 2095 1.1 christos /* if hi is zero then result will be lo (which has the smaller */ 2096 1.1 christos /* exponent), which also may need to be tested for zero for the */ 2097 1.1 christos /* weird IEEE 754 sign rules */ 2098 1.1 christos if (*hi->msd==0) { /* hi is zero */ 2099 1.1 christos /* "When the sum of two operands with opposite signs is */ 2100 1.1 christos /* exactly zero, the sign of that sum shall be '+' in all */ 2101 1.1 christos /* rounding modes except round toward -Infinity, in which */ 2102 1.1 christos /* mode that sign shall be '-'." */ 2103 1.1 christos if (diffsign) { 2104 1.1 christos if (*lo->msd==0) { /* lo is zero */ 2105 1.1 christos lo->sign=0; 2106 1.1 christos if (set->round==DEC_ROUND_FLOOR) lo->sign=DECFLOAT_Sign; 2107 1.1 christos } /* diffsign && lo=0 */ 2108 1.1 christos } /* diffsign */ 2109 1.1 christos return decFinalize(result, lo, set); /* may need clamping */ 2110 1.1 christos } /* numfl is zero */ 2111 1.1 christos /* [here, both are minimal length and hi is non-zero] */ 2112 1.1 christos /* (if lo is zero then padding with zeros may be needed, below) */ 2113 1.1 christos 2114 1.1 christos /* if signs differ, take the ten's complement of hi (zeros to the */ 2115 1.1 christos /* right do not matter because the complement of zero is zero); the */ 2116 1.1 christos /* +1 is done later, as part of the addition, inserted at the */ 2117 1.1 christos /* correct digit */ 2118 1.1 christos hipad=0; 2119 1.1 christos carry=0; 2120 1.1 christos if (diffsign) { 2121 1.1 christos hipad=9; 2122 1.1 christos carry=1; 2123 1.1 christos /* exactly the correct number of digits must be inverted */ 2124 1.1 christos for (uh=hi->msd; uh<hi->lsd-3; uh+=4) UBFROMUI(uh, 0x09090909-UBTOUI(uh)); 2125 1.1 christos for (; uh<=hi->lsd; uh++) *uh=(uByte)(0x09-*uh); 2126 1.1 christos } 2127 1.1 christos 2128 1.1 christos /* ready to add; note that hi has no leading zeros so gap */ 2129 1.1 christos /* calculation does not have to be as pessimistic as in decFloatAdd */ 2130 1.1 christos /* (this is much more like the arbitrary-precision algorithm in */ 2131 1.1 christos /* Rexx and decNumber) */ 2132 1.1 christos 2133 1.1 christos /* padding is the number of zeros that would need to be added to hi */ 2134 1.1 christos /* for its lsd to be aligned with the lsd of lo */ 2135 1.1 christos padding=hi->exponent-lo->exponent; 2136 1.1 christos /* printf("FMA pad %ld\n", (LI)padding); */ 2137 1.1 christos 2138 1.1 christos /* the result of the addition will be built into the accumulator, */ 2139 1.1 christos /* starting from the far right; this could be either hi or lo, and */ 2140 1.1 christos /* will be aligned */ 2141 1.1 christos ub=acc+FMALEN-1; /* where lsd of result will go */ 2142 1.1 christos ul=lo->lsd; /* lsd of rhs */ 2143 1.1 christos 2144 1.1 christos if (padding!=0) { /* unaligned */ 2145 1.1 christos /* if the msd of lo is more than DECPMAX+2 digits to the right of */ 2146 1.1 christos /* the original msd of hi then it can be reduced to a single */ 2147 1.1 christos /* digit at the right place, as it stays clear of hi digits */ 2148 1.1 christos /* [it must be DECPMAX+2 because during a subtraction the msd */ 2149 1.1 christos /* could become 0 after a borrow from 1.000 to 0.9999...] */ 2150 1.1 christos 2151 1.1 christos Int hilen=(Int)(hi->lsd-hi->msd+1); /* length of hi */ 2152 1.1 christos Int lolen=(Int)(lo->lsd-lo->msd+1); /* and of lo */ 2153 1.1 christos 2154 1.1 christos if (hilen+padding-lolen > DECPMAX+2) { /* can reduce lo to single */ 2155 1.1 christos /* make sure it is virtually at least DECPMAX from hi->msd, at */ 2156 1.1 christos /* least to right of hi->lsd (in case of destructive subtract), */ 2157 1.1 christos /* and separated by at least two digits from either of those */ 2158 1.1 christos /* (the tricky DOUBLE case is when hi is a 1 that will become a */ 2159 1.1 christos /* 0.9999... by subtraction: */ 2160 1.1 christos /* hi: 1 E+16 */ 2161 1.1 christos /* lo: .................1000000000000000 E-16 */ 2162 1.1 christos /* which for the addition pads to: */ 2163 1.1 christos /* hi: 1000000000000000000 E-16 */ 2164 1.1 christos /* lo: .................1000000000000000 E-16 */ 2165 1.1 christos Int newexp=MINI(hi->exponent, hi->exponent+hilen-DECPMAX)-3; 2166 1.1 christos 2167 1.1 christos /* printf("FMA reduce: %ld\n", (LI)reduce); */ 2168 1.1 christos lo->lsd=lo->msd; /* to single digit [maybe 0] */ 2169 1.1 christos lo->exponent=newexp; /* new lowest exponent */ 2170 1.1 christos padding=hi->exponent-lo->exponent; /* recalculate */ 2171 1.1 christos ul=lo->lsd; /* .. and repoint */ 2172 1.1 christos } 2173 1.1 christos 2174 1.1 christos /* padding is still > 0, but will fit in acc (less leading carry slot) */ 2175 1.1 christos #if DECCHECK 2176 1.1 christos if (padding<=0) printf("FMA low padding: %ld\n", (LI)padding); 2177 1.1 christos if (hilen+padding+1>FMALEN) 2178 1.1 christos printf("FMA excess hilen+padding: %ld+%ld \n", (LI)hilen, (LI)padding); 2179 1.1 christos /* printf("FMA padding: %ld\n", (LI)padding); */ 2180 1.1 christos #endif 2181 1.1 christos 2182 1.1 christos /* padding digits can now be set in the result; one or more of */ 2183 1.1 christos /* these will come from lo; others will be zeros in the gap */ 2184 1.1 christos for (; ul-3>=lo->msd && padding>3; padding-=4, ul-=4, ub-=4) { 2185 1.1 christos UBFROMUI(ub-3, UBTOUI(ul-3)); /* [cannot overlap] */ 2186 1.1 christos } 2187 1.1 christos for (; ul>=lo->msd && padding>0; padding--, ul--, ub--) *ub=*ul; 2188 1.1 christos for (;padding>0; padding--, ub--) *ub=0; /* mind the gap */ 2189 1.1 christos } 2190 1.1 christos 2191 1.1 christos /* addition now complete to the right of the rightmost digit of hi */ 2192 1.1 christos uh=hi->lsd; 2193 1.1 christos 2194 1.1 christos /* dow do the add from hi->lsd to the left */ 2195 1.1 christos /* [bytewise, because either operand can run out at any time] */ 2196 1.1 christos /* carry was set up depending on ten's complement above */ 2197 1.1 christos /* first assume both operands have some digits */ 2198 1.1 christos for (;; ub--) { 2199 1.1 christos if (uh<hi->msd || ul<lo->msd) break; 2200 1.1 christos *ub=(uByte)(carry+(*uh--)+(*ul--)); 2201 1.1 christos carry=0; 2202 1.1 christos if (*ub<10) continue; 2203 1.1 christos *ub-=10; 2204 1.1 christos carry=1; 2205 1.1 christos } /* both loop */ 2206 1.1 christos 2207 1.1 christos if (ul<lo->msd) { /* to left of lo */ 2208 1.1 christos for (;; ub--) { 2209 1.1 christos if (uh<hi->msd) break; 2210 1.1 christos *ub=(uByte)(carry+(*uh--)); /* [+0] */ 2211 1.1 christos carry=0; 2212 1.1 christos if (*ub<10) continue; 2213 1.1 christos *ub-=10; 2214 1.1 christos carry=1; 2215 1.1 christos } /* hi loop */ 2216 1.1 christos } 2217 1.1 christos else { /* to left of hi */ 2218 1.1 christos for (;; ub--) { 2219 1.1 christos if (ul<lo->msd) break; 2220 1.1 christos *ub=(uByte)(carry+hipad+(*ul--)); 2221 1.1 christos carry=0; 2222 1.1 christos if (*ub<10) continue; 2223 1.1 christos *ub-=10; 2224 1.1 christos carry=1; 2225 1.1 christos } /* lo loop */ 2226 1.1 christos } 2227 1.1 christos 2228 1.1 christos /* addition complete -- now handle carry, borrow, etc. */ 2229 1.1 christos /* use lo to set up the num (its exponent is already correct, and */ 2230 1.1 christos /* sign usually is) */ 2231 1.1 christos lo->msd=ub+1; 2232 1.1 christos lo->lsd=acc+FMALEN-1; 2233 1.1 christos /* decShowNum(lo, "lo"); */ 2234 1.1 christos if (!diffsign) { /* same-sign addition */ 2235 1.1 christos if (carry) { /* carry out */ 2236 1.1 christos *ub=1; /* place the 1 .. */ 2237 1.1 christos lo->msd--; /* .. and update */ 2238 1.1 christos } 2239 1.1 christos } /* same sign */ 2240 1.1 christos else { /* signs differed (subtraction) */ 2241 1.1 christos if (!carry) { /* no carry out means hi<lo */ 2242 1.1 christos /* borrowed -- take ten's complement of the right digits */ 2243 1.1 christos lo->sign=hi->sign; /* sign is lhs sign */ 2244 1.1 christos for (ul=lo->msd; ul<lo->lsd-3; ul+=4) UBFROMUI(ul, 0x09090909-UBTOUI(ul)); 2245 1.1 christos for (; ul<=lo->lsd; ul++) *ul=(uByte)(0x09-*ul); /* [leaves ul at lsd+1] */ 2246 1.1 christos /* complete the ten's complement by adding 1 [cannot overrun] */ 2247 1.1 christos for (ul--; *ul==9; ul--) *ul=0; 2248 1.1 christos *ul+=1; 2249 1.1 christos } /* borrowed */ 2250 1.1 christos else { /* carry out means hi>=lo */ 2251 1.1 christos /* sign to use is lo->sign */ 2252 1.1 christos /* all done except for the special IEEE 754 exact-zero-result */ 2253 1.1 christos /* rule (see above); while testing for zero, strip leading */ 2254 1.1 christos /* zeros (which will save decFinalize doing it) */ 2255 1.1 christos for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; 2256 1.1 christos for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++; 2257 1.1 christos if (*lo->msd==0) { /* must be true zero (and diffsign) */ 2258 1.1 christos lo->sign=0; /* assume + */ 2259 1.1 christos if (set->round==DEC_ROUND_FLOOR) lo->sign=DECFLOAT_Sign; 2260 1.1 christos } 2261 1.1 christos /* [else was not zero, might still have leading zeros] */ 2262 1.1 christos } /* subtraction gave positive result */ 2263 1.1 christos } /* diffsign */ 2264 1.1 christos 2265 1.1 christos #if DECCHECK 2266 1.1 christos /* assert no left underrun */ 2267 1.1 christos if (lo->msd<acc) { 2268 1.1 christos printf("FMA underrun by %ld \n", (LI)(acc-lo->msd)); 2269 1.1 christos } 2270 1.1 christos #endif 2271 1.1 christos 2272 1.1 christos return decFinalize(result, lo, set); /* round, check, and lay out */ 2273 1.1 christos } /* decFloatFMA */ 2274 1.1 christos 2275 1.1 christos /* ------------------------------------------------------------------ */ 2276 1.1 christos /* decFloatFromInt -- initialise a decFloat from an Int */ 2277 1.1 christos /* */ 2278 1.1 christos /* result gets the converted Int */ 2279 1.1 christos /* n is the Int to convert */ 2280 1.1 christos /* returns result */ 2281 1.1 christos /* */ 2282 1.1 christos /* The result is Exact; no errors or exceptions are possible. */ 2283 1.1 christos /* ------------------------------------------------------------------ */ 2284 1.1 christos decFloat * decFloatFromInt32(decFloat *result, Int n) { 2285 1.1 christos uInt u=(uInt)n; /* copy as bits */ 2286 1.1 christos uInt encode; /* work */ 2287 1.1 christos DFWORD(result, 0)=ZEROWORD; /* always */ 2288 1.1 christos #if QUAD 2289 1.1 christos DFWORD(result, 1)=0; 2290 1.1 christos DFWORD(result, 2)=0; 2291 1.1 christos #endif 2292 1.1 christos if (n<0) { /* handle -n with care */ 2293 1.1 christos /* [This can be done without the test, but is then slightly slower] */ 2294 1.1 christos u=(~u)+1; 2295 1.1 christos DFWORD(result, 0)|=DECFLOAT_Sign; 2296 1.1 christos } 2297 1.1 christos /* Since the maximum value of u now is 2**31, only the low word of */ 2298 1.1 christos /* result is affected */ 2299 1.1 christos encode=BIN2DPD[u%1000]; 2300 1.1 christos u/=1000; 2301 1.1 christos encode|=BIN2DPD[u%1000]<<10; 2302 1.1 christos u/=1000; 2303 1.1 christos encode|=BIN2DPD[u%1000]<<20; 2304 1.1 christos u/=1000; /* now 0, 1, or 2 */ 2305 1.1 christos encode|=u<<30; 2306 1.1 christos DFWORD(result, DECWORDS-1)=encode; 2307 1.1 christos return result; 2308 1.1 christos } /* decFloatFromInt32 */ 2309 1.1 christos 2310 1.1 christos /* ------------------------------------------------------------------ */ 2311 1.1 christos /* decFloatFromUInt -- initialise a decFloat from a uInt */ 2312 1.1 christos /* */ 2313 1.1 christos /* result gets the converted uInt */ 2314 1.1 christos /* n is the uInt to convert */ 2315 1.1 christos /* returns result */ 2316 1.1 christos /* */ 2317 1.1 christos /* The result is Exact; no errors or exceptions are possible. */ 2318 1.1 christos /* ------------------------------------------------------------------ */ 2319 1.1 christos decFloat * decFloatFromUInt32(decFloat *result, uInt u) { 2320 1.1 christos uInt encode; /* work */ 2321 1.1 christos DFWORD(result, 0)=ZEROWORD; /* always */ 2322 1.1 christos #if QUAD 2323 1.1 christos DFWORD(result, 1)=0; 2324 1.1 christos DFWORD(result, 2)=0; 2325 1.1 christos #endif 2326 1.1 christos encode=BIN2DPD[u%1000]; 2327 1.1 christos u/=1000; 2328 1.1 christos encode|=BIN2DPD[u%1000]<<10; 2329 1.1 christos u/=1000; 2330 1.1 christos encode|=BIN2DPD[u%1000]<<20; 2331 1.1 christos u/=1000; /* now 0 -> 4 */ 2332 1.1 christos encode|=u<<30; 2333 1.1 christos DFWORD(result, DECWORDS-1)=encode; 2334 1.1 christos DFWORD(result, DECWORDS-2)|=u>>2; /* rarely non-zero */ 2335 1.1 christos return result; 2336 1.1 christos } /* decFloatFromUInt32 */ 2337 1.1 christos 2338 1.1 christos /* ------------------------------------------------------------------ */ 2339 1.1 christos /* decFloatInvert -- logical digitwise INVERT of a decFloat */ 2340 1.1 christos /* */ 2341 1.1 christos /* result gets the result of INVERTing df */ 2342 1.1 christos /* df is the decFloat to invert */ 2343 1.1 christos /* set is the context */ 2344 1.1 christos /* returns result, which will be canonical with sign=0 */ 2345 1.1 christos /* */ 2346 1.1 christos /* The operand must be positive, finite with exponent q=0, and */ 2347 1.1 christos /* comprise just zeros and ones; if not, Invalid operation results. */ 2348 1.1 christos /* ------------------------------------------------------------------ */ 2349 1.1 christos decFloat * decFloatInvert(decFloat *result, const decFloat *df, 2350 1.1 christos decContext *set) { 2351 1.1 christos uInt sourhi=DFWORD(df, 0); /* top word of dfs */ 2352 1.1 christos 2353 1.1 christos if (!DFISUINT01(df) || !DFISCC01(df)) return decInvalid(result, set); 2354 1.1 christos /* the operand is a finite integer (q=0) */ 2355 1.1 christos #if DOUBLE 2356 1.1 christos DFWORD(result, 0)=ZEROWORD|((~sourhi)&0x04009124); 2357 1.1 christos DFWORD(result, 1)=(~DFWORD(df, 1)) &0x49124491; 2358 1.1 christos #elif QUAD 2359 1.1 christos DFWORD(result, 0)=ZEROWORD|((~sourhi)&0x04000912); 2360 1.1 christos DFWORD(result, 1)=(~DFWORD(df, 1)) &0x44912449; 2361 1.1 christos DFWORD(result, 2)=(~DFWORD(df, 2)) &0x12449124; 2362 1.1 christos DFWORD(result, 3)=(~DFWORD(df, 3)) &0x49124491; 2363 1.1 christos #endif 2364 1.1 christos return result; 2365 1.1 christos } /* decFloatInvert */ 2366 1.1 christos 2367 1.1 christos /* ------------------------------------------------------------------ */ 2368 1.1 christos /* decFloatIs -- decFloat tests (IsSigned, etc.) */ 2369 1.1 christos /* */ 2370 1.1 christos /* df is the decFloat to test */ 2371 1.1 christos /* returns 0 or 1 in a uInt */ 2372 1.1 christos /* */ 2373 1.1 christos /* Many of these could be macros, but having them as real functions */ 2374 1.1 christos /* is a little cleaner (and they can be referred to here by the */ 2375 1.1 christos /* generic names) */ 2376 1.1 christos /* ------------------------------------------------------------------ */ 2377 1.1 christos uInt decFloatIsCanonical(const decFloat *df) { 2378 1.1 christos if (DFISSPECIAL(df)) { 2379 1.1 christos if (DFISINF(df)) { 2380 1.1 christos if (DFWORD(df, 0)&ECONMASK) return 0; /* exponent continuation */ 2381 1.1 christos if (!DFISCCZERO(df)) return 0; /* coefficient continuation */ 2382 1.1 christos return 1; 2383 1.1 christos } 2384 1.1 christos /* is a NaN */ 2385 1.1 christos if (DFWORD(df, 0)&ECONNANMASK) return 0; /* exponent continuation */ 2386 1.1 christos if (DFISCCZERO(df)) return 1; /* coefficient continuation */ 2387 1.1 christos /* drop through to check payload */ 2388 1.1 christos } 2389 1.1 christos { /* declare block */ 2390 1.1 christos #if DOUBLE 2391 1.1 christos uInt sourhi=DFWORD(df, 0); 2392 1.1 christos uInt sourlo=DFWORD(df, 1); 2393 1.1 christos if (CANONDPDOFF(sourhi, 8) 2394 1.1 christos && CANONDPDTWO(sourhi, sourlo, 30) 2395 1.1 christos && CANONDPDOFF(sourlo, 20) 2396 1.1 christos && CANONDPDOFF(sourlo, 10) 2397 1.1 christos && CANONDPDOFF(sourlo, 0)) return 1; 2398 1.1 christos #elif QUAD 2399 1.1 christos uInt sourhi=DFWORD(df, 0); 2400 1.1 christos uInt sourmh=DFWORD(df, 1); 2401 1.1 christos uInt sourml=DFWORD(df, 2); 2402 1.1 christos uInt sourlo=DFWORD(df, 3); 2403 1.1 christos if (CANONDPDOFF(sourhi, 4) 2404 1.1 christos && CANONDPDTWO(sourhi, sourmh, 26) 2405 1.1 christos && CANONDPDOFF(sourmh, 16) 2406 1.1 christos && CANONDPDOFF(sourmh, 6) 2407 1.1 christos && CANONDPDTWO(sourmh, sourml, 28) 2408 1.1 christos && CANONDPDOFF(sourml, 18) 2409 1.1 christos && CANONDPDOFF(sourml, 8) 2410 1.1 christos && CANONDPDTWO(sourml, sourlo, 30) 2411 1.1 christos && CANONDPDOFF(sourlo, 20) 2412 1.1 christos && CANONDPDOFF(sourlo, 10) 2413 1.1 christos && CANONDPDOFF(sourlo, 0)) return 1; 2414 1.1 christos #endif 2415 1.1 christos } /* block */ 2416 1.1 christos return 0; /* a declet is non-canonical */ 2417 1.1 christos } 2418 1.1 christos 2419 1.1 christos uInt decFloatIsFinite(const decFloat *df) { 2420 1.1 christos return !DFISSPECIAL(df); 2421 1.1 christos } 2422 1.1 christos uInt decFloatIsInfinite(const decFloat *df) { 2423 1.1 christos return DFISINF(df); 2424 1.1 christos } 2425 1.1 christos uInt decFloatIsInteger(const decFloat *df) { 2426 1.1 christos return DFISINT(df); 2427 1.1 christos } 2428 1.1 christos uInt decFloatIsNaN(const decFloat *df) { 2429 1.1 christos return DFISNAN(df); 2430 1.1 christos } 2431 1.1 christos uInt decFloatIsNormal(const decFloat *df) { 2432 1.1 christos Int exp; /* exponent */ 2433 1.1 christos if (DFISSPECIAL(df)) return 0; 2434 1.1 christos if (DFISZERO(df)) return 0; 2435 1.1 christos /* is finite and non-zero */ 2436 1.1 christos exp=GETEXPUN(df) /* get unbiased exponent .. */ 2437 1.1 christos +decFloatDigits(df)-1; /* .. and make adjusted exponent */ 2438 1.1 christos return (exp>=DECEMIN); /* < DECEMIN is subnormal */ 2439 1.1 christos } 2440 1.1 christos uInt decFloatIsSignaling(const decFloat *df) { 2441 1.1 christos return DFISSNAN(df); 2442 1.1 christos } 2443 1.1 christos uInt decFloatIsSignalling(const decFloat *df) { 2444 1.1 christos return DFISSNAN(df); 2445 1.1 christos } 2446 1.1 christos uInt decFloatIsSigned(const decFloat *df) { 2447 1.1 christos return DFISSIGNED(df); 2448 1.1 christos } 2449 1.1 christos uInt decFloatIsSubnormal(const decFloat *df) { 2450 1.1 christos if (DFISSPECIAL(df)) return 0; 2451 1.1 christos /* is finite */ 2452 1.1 christos if (decFloatIsNormal(df)) return 0; 2453 1.1 christos /* it is <Nmin, but could be zero */ 2454 1.1 christos if (DFISZERO(df)) return 0; 2455 1.1 christos return 1; /* is subnormal */ 2456 1.1 christos } 2457 1.1 christos uInt decFloatIsZero(const decFloat *df) { 2458 1.1 christos return DFISZERO(df); 2459 1.1 christos } /* decFloatIs... */ 2460 1.1 christos 2461 1.1 christos /* ------------------------------------------------------------------ */ 2462 1.1 christos /* decFloatLogB -- return adjusted exponent, by 754 rules */ 2463 1.1 christos /* */ 2464 1.1 christos /* result gets the adjusted exponent as an integer, or a NaN etc. */ 2465 1.1 christos /* df is the decFloat to be examined */ 2466 1.1 christos /* set is the context */ 2467 1.1 christos /* returns result */ 2468 1.1 christos /* */ 2469 1.1 christos /* Notable cases: */ 2470 1.1 christos /* A<0 -> Use |A| */ 2471 1.1 christos /* A=0 -> -Infinity (Division by zero) */ 2472 1.1 christos /* A=Infinite -> +Infinity (Exact) */ 2473 1.1 christos /* A=1 exactly -> 0 (Exact) */ 2474 1.1 christos /* NaNs are propagated as usual */ 2475 1.1 christos /* ------------------------------------------------------------------ */ 2476 1.1 christos decFloat * decFloatLogB(decFloat *result, const decFloat *df, 2477 1.1 christos decContext *set) { 2478 1.1 christos Int ae; /* adjusted exponent */ 2479 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); 2480 1.1 christos if (DFISINF(df)) { 2481 1.1 christos DFWORD(result, 0)=0; /* need +ve */ 2482 1.1 christos return decInfinity(result, result); /* canonical +Infinity */ 2483 1.1 christos } 2484 1.1 christos if (DFISZERO(df)) { 2485 1.1 christos set->status|=DEC_Division_by_zero; /* as per 754 */ 2486 1.1 christos DFWORD(result, 0)=DECFLOAT_Sign; /* make negative */ 2487 1.1 christos return decInfinity(result, result); /* canonical -Infinity */ 2488 1.1 christos } 2489 1.1 christos ae=GETEXPUN(df) /* get unbiased exponent .. */ 2490 1.1 christos +decFloatDigits(df)-1; /* .. and make adjusted exponent */ 2491 1.1 christos /* ae has limited range (3 digits for DOUBLE and 4 for QUAD), so */ 2492 1.1 christos /* it is worth using a special case of decFloatFromInt32 */ 2493 1.1 christos DFWORD(result, 0)=ZEROWORD; /* always */ 2494 1.1 christos if (ae<0) { 2495 1.1 christos DFWORD(result, 0)|=DECFLOAT_Sign; /* -0 so far */ 2496 1.1 christos ae=-ae; 2497 1.1 christos } 2498 1.1 christos #if DOUBLE 2499 1.1 christos DFWORD(result, 1)=BIN2DPD[ae]; /* a single declet */ 2500 1.1 christos #elif QUAD 2501 1.1 christos DFWORD(result, 1)=0; 2502 1.1 christos DFWORD(result, 2)=0; 2503 1.1 christos DFWORD(result, 3)=(ae/1000)<<10; /* is <10, so need no DPD encode */ 2504 1.1 christos DFWORD(result, 3)|=BIN2DPD[ae%1000]; 2505 1.1 christos #endif 2506 1.1 christos return result; 2507 1.1 christos } /* decFloatLogB */ 2508 1.1 christos 2509 1.1 christos /* ------------------------------------------------------------------ */ 2510 1.1 christos /* decFloatMax -- return maxnum of two operands */ 2511 1.1 christos /* */ 2512 1.1 christos /* result gets the chosen decFloat */ 2513 1.1 christos /* dfl is the first decFloat (lhs) */ 2514 1.1 christos /* dfr is the second decFloat (rhs) */ 2515 1.1 christos /* set is the context */ 2516 1.1 christos /* returns result */ 2517 1.1 christos /* */ 2518 1.1 christos /* If just one operand is a quiet NaN it is ignored. */ 2519 1.1 christos /* ------------------------------------------------------------------ */ 2520 1.1 christos decFloat * decFloatMax(decFloat *result, 2521 1.1 christos const decFloat *dfl, const decFloat *dfr, 2522 1.1 christos decContext *set) { 2523 1.1 christos Int comp; 2524 1.1 christos if (DFISNAN(dfl)) { 2525 1.1 christos /* sNaN or both NaNs leads to normal NaN processing */ 2526 1.1 christos if (DFISNAN(dfr) || DFISSNAN(dfl)) return decNaNs(result, dfl, dfr, set); 2527 1.1 christos return decCanonical(result, dfr); /* RHS is numeric */ 2528 1.1 christos } 2529 1.1 christos if (DFISNAN(dfr)) { 2530 1.1 christos /* sNaN leads to normal NaN processing (both NaN handled above) */ 2531 1.1 christos if (DFISSNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2532 1.1 christos return decCanonical(result, dfl); /* LHS is numeric */ 2533 1.1 christos } 2534 1.1 christos /* Both operands are numeric; numeric comparison needed -- use */ 2535 1.1 christos /* total order for a well-defined choice (and +0 > -0) */ 2536 1.1 christos comp=decNumCompare(dfl, dfr, 1); 2537 1.1 christos if (comp>=0) return decCanonical(result, dfl); 2538 1.1 christos return decCanonical(result, dfr); 2539 1.1 christos } /* decFloatMax */ 2540 1.1 christos 2541 1.1 christos /* ------------------------------------------------------------------ */ 2542 1.1 christos /* decFloatMaxMag -- return maxnummag of two operands */ 2543 1.1 christos /* */ 2544 1.1 christos /* result gets the chosen decFloat */ 2545 1.1 christos /* dfl is the first decFloat (lhs) */ 2546 1.1 christos /* dfr is the second decFloat (rhs) */ 2547 1.1 christos /* set is the context */ 2548 1.1 christos /* returns result */ 2549 1.1 christos /* */ 2550 1.1 christos /* Returns according to the magnitude comparisons if both numeric and */ 2551 1.1 christos /* unequal, otherwise returns maxnum */ 2552 1.1 christos /* ------------------------------------------------------------------ */ 2553 1.1 christos decFloat * decFloatMaxMag(decFloat *result, 2554 1.1 christos const decFloat *dfl, const decFloat *dfr, 2555 1.1 christos decContext *set) { 2556 1.1 christos Int comp; 2557 1.1 christos decFloat absl, absr; 2558 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decFloatMax(result, dfl, dfr, set); 2559 1.1 christos 2560 1.1 christos decFloatCopyAbs(&absl, dfl); 2561 1.1 christos decFloatCopyAbs(&absr, dfr); 2562 1.1 christos comp=decNumCompare(&absl, &absr, 0); 2563 1.1 christos if (comp>0) return decCanonical(result, dfl); 2564 1.1 christos if (comp<0) return decCanonical(result, dfr); 2565 1.1 christos return decFloatMax(result, dfl, dfr, set); 2566 1.1 christos } /* decFloatMaxMag */ 2567 1.1 christos 2568 1.1 christos /* ------------------------------------------------------------------ */ 2569 1.1 christos /* decFloatMin -- return minnum of two operands */ 2570 1.1 christos /* */ 2571 1.1 christos /* result gets the chosen decFloat */ 2572 1.1 christos /* dfl is the first decFloat (lhs) */ 2573 1.1 christos /* dfr is the second decFloat (rhs) */ 2574 1.1 christos /* set is the context */ 2575 1.1 christos /* returns result */ 2576 1.1 christos /* */ 2577 1.1 christos /* If just one operand is a quiet NaN it is ignored. */ 2578 1.1 christos /* ------------------------------------------------------------------ */ 2579 1.1 christos decFloat * decFloatMin(decFloat *result, 2580 1.1 christos const decFloat *dfl, const decFloat *dfr, 2581 1.1 christos decContext *set) { 2582 1.1 christos Int comp; 2583 1.1 christos if (DFISNAN(dfl)) { 2584 1.1 christos /* sNaN or both NaNs leads to normal NaN processing */ 2585 1.1 christos if (DFISNAN(dfr) || DFISSNAN(dfl)) return decNaNs(result, dfl, dfr, set); 2586 1.1 christos return decCanonical(result, dfr); /* RHS is numeric */ 2587 1.1 christos } 2588 1.1 christos if (DFISNAN(dfr)) { 2589 1.1 christos /* sNaN leads to normal NaN processing (both NaN handled above) */ 2590 1.1 christos if (DFISSNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2591 1.1 christos return decCanonical(result, dfl); /* LHS is numeric */ 2592 1.1 christos } 2593 1.1 christos /* Both operands are numeric; numeric comparison needed -- use */ 2594 1.1 christos /* total order for a well-defined choice (and +0 > -0) */ 2595 1.1 christos comp=decNumCompare(dfl, dfr, 1); 2596 1.1 christos if (comp<=0) return decCanonical(result, dfl); 2597 1.1 christos return decCanonical(result, dfr); 2598 1.1 christos } /* decFloatMin */ 2599 1.1 christos 2600 1.1 christos /* ------------------------------------------------------------------ */ 2601 1.1 christos /* decFloatMinMag -- return minnummag of two operands */ 2602 1.1 christos /* */ 2603 1.1 christos /* result gets the chosen decFloat */ 2604 1.1 christos /* dfl is the first decFloat (lhs) */ 2605 1.1 christos /* dfr is the second decFloat (rhs) */ 2606 1.1 christos /* set is the context */ 2607 1.1 christos /* returns result */ 2608 1.1 christos /* */ 2609 1.1 christos /* Returns according to the magnitude comparisons if both numeric and */ 2610 1.1 christos /* unequal, otherwise returns minnum */ 2611 1.1 christos /* ------------------------------------------------------------------ */ 2612 1.1 christos decFloat * decFloatMinMag(decFloat *result, 2613 1.1 christos const decFloat *dfl, const decFloat *dfr, 2614 1.1 christos decContext *set) { 2615 1.1 christos Int comp; 2616 1.1 christos decFloat absl, absr; 2617 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decFloatMin(result, dfl, dfr, set); 2618 1.1 christos 2619 1.1 christos decFloatCopyAbs(&absl, dfl); 2620 1.1 christos decFloatCopyAbs(&absr, dfr); 2621 1.1 christos comp=decNumCompare(&absl, &absr, 0); 2622 1.1 christos if (comp<0) return decCanonical(result, dfl); 2623 1.1 christos if (comp>0) return decCanonical(result, dfr); 2624 1.1 christos return decFloatMin(result, dfl, dfr, set); 2625 1.1 christos } /* decFloatMinMag */ 2626 1.1 christos 2627 1.1 christos /* ------------------------------------------------------------------ */ 2628 1.1 christos /* decFloatMinus -- negate value, heeding NaNs, etc. */ 2629 1.1 christos /* */ 2630 1.1 christos /* result gets the canonicalized 0-df */ 2631 1.1 christos /* df is the decFloat to minus */ 2632 1.1 christos /* set is the context */ 2633 1.1 christos /* returns result */ 2634 1.1 christos /* */ 2635 1.1 christos /* This has the same effect as 0-df where the exponent of the zero is */ 2636 1.1 christos /* the same as that of df (if df is finite). */ 2637 1.1 christos /* The effect is also the same as decFloatCopyNegate except that NaNs */ 2638 1.1 christos /* are handled normally (the sign of a NaN is not affected, and an */ 2639 1.1 christos /* sNaN will signal), the result is canonical, and zero gets sign 0. */ 2640 1.1 christos /* ------------------------------------------------------------------ */ 2641 1.1 christos decFloat * decFloatMinus(decFloat *result, const decFloat *df, 2642 1.1 christos decContext *set) { 2643 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); 2644 1.1 christos decCanonical(result, df); /* copy and check */ 2645 1.1 christos if (DFISZERO(df)) DFBYTE(result, 0)&=~0x80; /* turn off sign bit */ 2646 1.1 christos else DFBYTE(result, 0)^=0x80; /* flip sign bit */ 2647 1.1 christos return result; 2648 1.1 christos } /* decFloatMinus */ 2649 1.1 christos 2650 1.1 christos /* ------------------------------------------------------------------ */ 2651 1.1 christos /* decFloatMultiply -- multiply two decFloats */ 2652 1.1 christos /* */ 2653 1.1 christos /* result gets the result of multiplying dfl and dfr: */ 2654 1.1 christos /* dfl is the first decFloat (lhs) */ 2655 1.1 christos /* dfr is the second decFloat (rhs) */ 2656 1.1 christos /* set is the context */ 2657 1.1 christos /* returns result */ 2658 1.1 christos /* */ 2659 1.1 christos /* ------------------------------------------------------------------ */ 2660 1.1 christos decFloat * decFloatMultiply(decFloat *result, 2661 1.1 christos const decFloat *dfl, const decFloat *dfr, 2662 1.1 christos decContext *set) { 2663 1.1 christos bcdnum num; /* for final conversion */ 2664 1.1 christos uByte bcdacc[DECPMAX9*18+1]; /* for coefficent in BCD */ 2665 1.1 christos 2666 1.1 christos if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr)) { /* either is special? */ 2667 1.1 christos /* NaNs are handled as usual */ 2668 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2669 1.1 christos /* infinity times zero is bad */ 2670 1.1 christos if (DFISINF(dfl) && DFISZERO(dfr)) return decInvalid(result, set); 2671 1.1 christos if (DFISINF(dfr) && DFISZERO(dfl)) return decInvalid(result, set); 2672 1.1 christos /* both infinite; return canonical infinity with computed sign */ 2673 1.1 christos DFWORD(result, 0)=DFWORD(dfl, 0)^DFWORD(dfr, 0); /* compute sign */ 2674 1.1 christos return decInfinity(result, result); 2675 1.1 christos } 2676 1.1 christos 2677 1.1 christos /* Here when both operands are finite */ 2678 1.1 christos decFiniteMultiply(&num, bcdacc, dfl, dfr); 2679 1.1 christos return decFinalize(result, &num, set); /* round, check, and lay out */ 2680 1.1 christos } /* decFloatMultiply */ 2681 1.1 christos 2682 1.1 christos /* ------------------------------------------------------------------ */ 2683 1.1 christos /* decFloatNextMinus -- next towards -Infinity */ 2684 1.1 christos /* */ 2685 1.1 christos /* result gets the next lesser decFloat */ 2686 1.1 christos /* dfl is the decFloat to start with */ 2687 1.1 christos /* set is the context */ 2688 1.1 christos /* returns result */ 2689 1.1 christos /* */ 2690 1.1 christos /* This is 754 nextdown; Invalid is the only status possible (from */ 2691 1.1 christos /* an sNaN). */ 2692 1.1 christos /* ------------------------------------------------------------------ */ 2693 1.1 christos decFloat * decFloatNextMinus(decFloat *result, const decFloat *dfl, 2694 1.1 christos decContext *set) { 2695 1.1 christos decFloat delta; /* tiny increment */ 2696 1.1 christos uInt savestat; /* saves status */ 2697 1.1 christos enum rounding saveround; /* .. and mode */ 2698 1.1 christos 2699 1.1 christos /* +Infinity is the special case */ 2700 1.1 christos if (DFISINF(dfl) && !DFISSIGNED(dfl)) { 2701 1.1 christos DFSETNMAX(result); 2702 1.1 christos return result; /* [no status to set] */ 2703 1.1 christos } 2704 1.1 christos /* other cases are effected by sutracting a tiny delta -- this */ 2705 1.1 christos /* should be done in a wider format as the delta is unrepresentable */ 2706 1.1 christos /* here (but can be done with normal add if the sign of zero is */ 2707 1.1 christos /* treated carefully, because no Inexactitude is interesting); */ 2708 1.1 christos /* rounding to -Infinity then pushes the result to next below */ 2709 1.1 christos decFloatZero(&delta); /* set up tiny delta */ 2710 1.1 christos DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ 2711 1.1 christos DFWORD(&delta, 0)=DECFLOAT_Sign; /* Sign=1 + biased exponent=0 */ 2712 1.1 christos /* set up for the directional round */ 2713 1.1 christos saveround=set->round; /* save mode */ 2714 1.1 christos set->round=DEC_ROUND_FLOOR; /* .. round towards -Infinity */ 2715 1.1 christos savestat=set->status; /* save status */ 2716 1.1 christos decFloatAdd(result, dfl, &delta, set); 2717 1.1 christos /* Add rules mess up the sign when going from +Ntiny to 0 */ 2718 1.1 christos if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */ 2719 1.1 christos set->status&=DEC_Invalid_operation; /* preserve only sNaN status */ 2720 1.1 christos set->status|=savestat; /* restore pending flags */ 2721 1.1 christos set->round=saveround; /* .. and mode */ 2722 1.1 christos return result; 2723 1.1 christos } /* decFloatNextMinus */ 2724 1.1 christos 2725 1.1 christos /* ------------------------------------------------------------------ */ 2726 1.1 christos /* decFloatNextPlus -- next towards +Infinity */ 2727 1.1 christos /* */ 2728 1.1 christos /* result gets the next larger decFloat */ 2729 1.1 christos /* dfl is the decFloat to start with */ 2730 1.1 christos /* set is the context */ 2731 1.1 christos /* returns result */ 2732 1.1 christos /* */ 2733 1.1 christos /* This is 754 nextup; Invalid is the only status possible (from */ 2734 1.1 christos /* an sNaN). */ 2735 1.1 christos /* ------------------------------------------------------------------ */ 2736 1.1 christos decFloat * decFloatNextPlus(decFloat *result, const decFloat *dfl, 2737 1.1 christos decContext *set) { 2738 1.1 christos uInt savestat; /* saves status */ 2739 1.1 christos enum rounding saveround; /* .. and mode */ 2740 1.1 christos decFloat delta; /* tiny increment */ 2741 1.1 christos 2742 1.1 christos /* -Infinity is the special case */ 2743 1.1 christos if (DFISINF(dfl) && DFISSIGNED(dfl)) { 2744 1.1 christos DFSETNMAX(result); 2745 1.1 christos DFWORD(result, 0)|=DECFLOAT_Sign; /* make negative */ 2746 1.1 christos return result; /* [no status to set] */ 2747 1.1 christos } 2748 1.1 christos /* other cases are effected by sutracting a tiny delta -- this */ 2749 1.1 christos /* should be done in a wider format as the delta is unrepresentable */ 2750 1.1 christos /* here (but can be done with normal add if the sign of zero is */ 2751 1.1 christos /* treated carefully, because no Inexactitude is interesting); */ 2752 1.1 christos /* rounding to +Infinity then pushes the result to next above */ 2753 1.1 christos decFloatZero(&delta); /* set up tiny delta */ 2754 1.1 christos DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ 2755 1.1 christos DFWORD(&delta, 0)=0; /* Sign=0 + biased exponent=0 */ 2756 1.1 christos /* set up for the directional round */ 2757 1.1 christos saveround=set->round; /* save mode */ 2758 1.1 christos set->round=DEC_ROUND_CEILING; /* .. round towards +Infinity */ 2759 1.1 christos savestat=set->status; /* save status */ 2760 1.1 christos decFloatAdd(result, dfl, &delta, set); 2761 1.1 christos /* Add rules mess up the sign when going from -Ntiny to -0 */ 2762 1.1 christos if (DFISZERO(result)) DFWORD(result, 0)^=DECFLOAT_Sign; /* correct */ 2763 1.1 christos set->status&=DEC_Invalid_operation; /* preserve only sNaN status */ 2764 1.1 christos set->status|=savestat; /* restore pending flags */ 2765 1.1 christos set->round=saveround; /* .. and mode */ 2766 1.1 christos return result; 2767 1.1 christos } /* decFloatNextPlus */ 2768 1.1 christos 2769 1.1 christos /* ------------------------------------------------------------------ */ 2770 1.1 christos /* decFloatNextToward -- next towards a decFloat */ 2771 1.1 christos /* */ 2772 1.1 christos /* result gets the next decFloat */ 2773 1.1 christos /* dfl is the decFloat to start with */ 2774 1.1 christos /* dfr is the decFloat to move toward */ 2775 1.1 christos /* set is the context */ 2776 1.1 christos /* returns result */ 2777 1.1 christos /* */ 2778 1.1 christos /* This is 754-1985 nextafter, as modified during revision (dropped */ 2779 1.1 christos /* from 754-2008); status may be set unless the result is a normal */ 2780 1.1 christos /* number. */ 2781 1.1 christos /* ------------------------------------------------------------------ */ 2782 1.1 christos decFloat * decFloatNextToward(decFloat *result, 2783 1.1 christos const decFloat *dfl, const decFloat *dfr, 2784 1.1 christos decContext *set) { 2785 1.1 christos decFloat delta; /* tiny increment or decrement */ 2786 1.1 christos decFloat pointone; /* 1e-1 */ 2787 1.1 christos uInt savestat; /* saves status */ 2788 1.1 christos enum rounding saveround; /* .. and mode */ 2789 1.1 christos uInt deltatop; /* top word for delta */ 2790 1.1 christos Int comp; /* work */ 2791 1.1 christos 2792 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2793 1.1 christos /* Both are numeric, so Invalid no longer a possibility */ 2794 1.1 christos comp=decNumCompare(dfl, dfr, 0); 2795 1.1 christos if (comp==0) return decFloatCopySign(result, dfl, dfr); /* equal */ 2796 1.1 christos /* unequal; do NextPlus or NextMinus but with different status rules */ 2797 1.1 christos 2798 1.1 christos if (comp<0) { /* lhs<rhs, do NextPlus, see above for commentary */ 2799 1.1 christos if (DFISINF(dfl) && DFISSIGNED(dfl)) { /* -Infinity special case */ 2800 1.1 christos DFSETNMAX(result); 2801 1.1 christos DFWORD(result, 0)|=DECFLOAT_Sign; 2802 1.1 christos return result; 2803 1.1 christos } 2804 1.1 christos saveround=set->round; /* save mode */ 2805 1.1 christos set->round=DEC_ROUND_CEILING; /* .. round towards +Infinity */ 2806 1.1 christos deltatop=0; /* positive delta */ 2807 1.1 christos } 2808 1.1 christos else { /* lhs>rhs, do NextMinus, see above for commentary */ 2809 1.1 christos if (DFISINF(dfl) && !DFISSIGNED(dfl)) { /* +Infinity special case */ 2810 1.1 christos DFSETNMAX(result); 2811 1.1 christos return result; 2812 1.1 christos } 2813 1.1 christos saveround=set->round; /* save mode */ 2814 1.1 christos set->round=DEC_ROUND_FLOOR; /* .. round towards -Infinity */ 2815 1.1 christos deltatop=DECFLOAT_Sign; /* negative delta */ 2816 1.1 christos } 2817 1.1 christos savestat=set->status; /* save status */ 2818 1.1 christos /* Here, Inexact is needed where appropriate (and hence Underflow, */ 2819 1.1 christos /* etc.). Therefore the tiny delta which is otherwise */ 2820 1.1 christos /* unrepresentable (see NextPlus and NextMinus) is constructed */ 2821 1.1 christos /* using the multiplication of FMA. */ 2822 1.1 christos decFloatZero(&delta); /* set up tiny delta */ 2823 1.1 christos DFWORD(&delta, DECWORDS-1)=1; /* coefficient=1 */ 2824 1.1 christos DFWORD(&delta, 0)=deltatop; /* Sign + biased exponent=0 */ 2825 1.1 christos decFloatFromString(&pointone, "1E-1", set); /* set up multiplier */ 2826 1.1 christos decFloatFMA(result, &delta, &pointone, dfl, set); 2827 1.1 christos /* [Delta is truly tiny, so no need to correct sign of zero] */ 2828 1.1 christos /* use new status unless the result is normal */ 2829 1.1 christos if (decFloatIsNormal(result)) set->status=savestat; /* else goes forward */ 2830 1.1 christos set->round=saveround; /* restore mode */ 2831 1.1 christos return result; 2832 1.1 christos } /* decFloatNextToward */ 2833 1.1 christos 2834 1.1 christos /* ------------------------------------------------------------------ */ 2835 1.1 christos /* decFloatOr -- logical digitwise OR of two decFloats */ 2836 1.1 christos /* */ 2837 1.1 christos /* result gets the result of ORing dfl and dfr */ 2838 1.1 christos /* dfl is the first decFloat (lhs) */ 2839 1.1 christos /* dfr is the second decFloat (rhs) */ 2840 1.1 christos /* set is the context */ 2841 1.1 christos /* returns result, which will be canonical with sign=0 */ 2842 1.1 christos /* */ 2843 1.1 christos /* The operands must be positive, finite with exponent q=0, and */ 2844 1.1 christos /* comprise just zeros and ones; if not, Invalid operation results. */ 2845 1.1 christos /* ------------------------------------------------------------------ */ 2846 1.1 christos decFloat * decFloatOr(decFloat *result, 2847 1.1 christos const decFloat *dfl, const decFloat *dfr, 2848 1.1 christos decContext *set) { 2849 1.1 christos if (!DFISUINT01(dfl) || !DFISUINT01(dfr) 2850 1.1 christos || !DFISCC01(dfl) || !DFISCC01(dfr)) return decInvalid(result, set); 2851 1.1 christos /* the operands are positive finite integers (q=0) with just 0s and 1s */ 2852 1.1 christos #if DOUBLE 2853 1.1 christos DFWORD(result, 0)=ZEROWORD 2854 1.1 christos |((DFWORD(dfl, 0) | DFWORD(dfr, 0))&0x04009124); 2855 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) | DFWORD(dfr, 1))&0x49124491; 2856 1.1 christos #elif QUAD 2857 1.1 christos DFWORD(result, 0)=ZEROWORD 2858 1.1 christos |((DFWORD(dfl, 0) | DFWORD(dfr, 0))&0x04000912); 2859 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) | DFWORD(dfr, 1))&0x44912449; 2860 1.1 christos DFWORD(result, 2)=(DFWORD(dfl, 2) | DFWORD(dfr, 2))&0x12449124; 2861 1.1 christos DFWORD(result, 3)=(DFWORD(dfl, 3) | DFWORD(dfr, 3))&0x49124491; 2862 1.1 christos #endif 2863 1.1 christos return result; 2864 1.1 christos } /* decFloatOr */ 2865 1.1 christos 2866 1.1 christos /* ------------------------------------------------------------------ */ 2867 1.1 christos /* decFloatPlus -- add value to 0, heeding NaNs, etc. */ 2868 1.1 christos /* */ 2869 1.1 christos /* result gets the canonicalized 0+df */ 2870 1.1 christos /* df is the decFloat to plus */ 2871 1.1 christos /* set is the context */ 2872 1.1 christos /* returns result */ 2873 1.1 christos /* */ 2874 1.1 christos /* This has the same effect as 0+df where the exponent of the zero is */ 2875 1.1 christos /* the same as that of df (if df is finite). */ 2876 1.1 christos /* The effect is also the same as decFloatCopy except that NaNs */ 2877 1.1 christos /* are handled normally (the sign of a NaN is not affected, and an */ 2878 1.1 christos /* sNaN will signal), the result is canonical, and zero gets sign 0. */ 2879 1.1 christos /* ------------------------------------------------------------------ */ 2880 1.1 christos decFloat * decFloatPlus(decFloat *result, const decFloat *df, 2881 1.1 christos decContext *set) { 2882 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); 2883 1.1 christos decCanonical(result, df); /* copy and check */ 2884 1.1 christos if (DFISZERO(df)) DFBYTE(result, 0)&=~0x80; /* turn off sign bit */ 2885 1.1 christos return result; 2886 1.1 christos } /* decFloatPlus */ 2887 1.1 christos 2888 1.1 christos /* ------------------------------------------------------------------ */ 2889 1.1 christos /* decFloatQuantize -- quantize a decFloat */ 2890 1.1 christos /* */ 2891 1.1 christos /* result gets the result of quantizing dfl to match dfr */ 2892 1.1 christos /* dfl is the first decFloat (lhs) */ 2893 1.1 christos /* dfr is the second decFloat (rhs), which sets the exponent */ 2894 1.1 christos /* set is the context */ 2895 1.1 christos /* returns result */ 2896 1.1 christos /* */ 2897 1.1 christos /* Unless there is an error or the result is infinite, the exponent */ 2898 1.1 christos /* of result is guaranteed to be the same as that of dfr. */ 2899 1.1 christos /* ------------------------------------------------------------------ */ 2900 1.1 christos decFloat * decFloatQuantize(decFloat *result, 2901 1.1 christos const decFloat *dfl, const decFloat *dfr, 2902 1.1 christos decContext *set) { 2903 1.1 christos Int explb, exprb; /* left and right biased exponents */ 2904 1.1 christos uByte *ulsd; /* local LSD pointer */ 2905 1.1 christos uByte *ub, *uc; /* work */ 2906 1.1 christos Int drop; /* .. */ 2907 1.1 christos uInt dpd; /* .. */ 2908 1.1 christos uInt encode; /* encoding accumulator */ 2909 1.1 christos uInt sourhil, sourhir; /* top words from source decFloats */ 2910 1.1 christos uInt uiwork; /* for macros */ 2911 1.1 christos #if QUAD 2912 1.1 christos uShort uswork; /* .. */ 2913 1.1 christos #endif 2914 1.1 christos /* the following buffer holds the coefficient for manipulation */ 2915 1.1 christos uByte buf[4+DECPMAX*3+2*QUAD]; /* + space for zeros to left or right */ 2916 1.1 christos #if DECTRACE 2917 1.1 christos bcdnum num; /* for trace displays */ 2918 1.1 christos #endif 2919 1.1 christos 2920 1.1 christos /* Start decoding the arguments */ 2921 1.1 christos sourhil=DFWORD(dfl, 0); /* LHS top word */ 2922 1.1 christos explb=DECCOMBEXP[sourhil>>26]; /* get exponent high bits (in place) */ 2923 1.1 christos sourhir=DFWORD(dfr, 0); /* RHS top word */ 2924 1.1 christos exprb=DECCOMBEXP[sourhir>>26]; 2925 1.1 christos 2926 1.1 christos if (EXPISSPECIAL(explb | exprb)) { /* either is special? */ 2927 1.1 christos /* NaNs are handled as usual */ 2928 1.1 christos if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 2929 1.1 christos /* one infinity but not both is bad */ 2930 1.1 christos if (DFISINF(dfl)!=DFISINF(dfr)) return decInvalid(result, set); 2931 1.1 christos /* both infinite; return canonical infinity with sign of LHS */ 2932 1.1 christos return decInfinity(result, dfl); 2933 1.1 christos } 2934 1.1 christos 2935 1.1 christos /* Here when both arguments are finite */ 2936 1.1 christos /* complete extraction of the exponents [no need to unbias] */ 2937 1.1 christos explb+=GETECON(dfl); /* + continuation */ 2938 1.1 christos exprb+=GETECON(dfr); /* .. */ 2939 1.1 christos 2940 1.1 christos /* calculate the number of digits to drop from the coefficient */ 2941 1.1 christos drop=exprb-explb; /* 0 if nothing to do */ 2942 1.1 christos if (drop==0) return decCanonical(result, dfl); /* return canonical */ 2943 1.1 christos 2944 1.1 christos /* the coefficient is needed; lay it out into buf, offset so zeros */ 2945 1.1 christos /* can be added before or after as needed -- an extra heading is */ 2946 1.1 christos /* added so can safely pad Quad DECPMAX-1 zeros to the left by */ 2947 1.1 christos /* fours */ 2948 1.1 christos #define BUFOFF (buf+4+DECPMAX) 2949 1.1 christos GETCOEFF(dfl, BUFOFF); /* decode from decFloat */ 2950 1.1 christos /* [now the msd is at BUFOFF and the lsd is at BUFOFF+DECPMAX-1] */ 2951 1.1 christos 2952 1.1 christos #if DECTRACE 2953 1.1 christos num.msd=BUFOFF; 2954 1.1 christos num.lsd=BUFOFF+DECPMAX-1; 2955 1.1 christos num.exponent=explb-DECBIAS; 2956 1.1 christos num.sign=sourhil & DECFLOAT_Sign; 2957 1.1 christos decShowNum(&num, "dfl"); 2958 1.1 christos #endif 2959 1.1 christos 2960 1.1 christos if (drop>0) { /* [most common case] */ 2961 1.1 christos /* (this code is very similar to that in decFloatFinalize, but */ 2962 1.1 christos /* has many differences so is duplicated here -- so any changes */ 2963 1.1 christos /* may need to be made there, too) */ 2964 1.1 christos uByte *roundat; /* -> re-round digit */ 2965 1.1 christos uByte reround; /* reround value */ 2966 1.1 christos /* printf("Rounding; drop=%ld\n", (LI)drop); */ 2967 1.1 christos 2968 1.1 christos /* there is at least one zero needed to the left, in all but one */ 2969 1.1 christos /* exceptional (all-nines) case, so place four zeros now; this is */ 2970 1.1 christos /* needed almost always and makes rounding all-nines by fours safe */ 2971 1.1 christos UBFROMUI(BUFOFF-4, 0); 2972 1.1 christos 2973 1.1 christos /* Three cases here: */ 2974 1.1 christos /* 1. new LSD is in coefficient (almost always) */ 2975 1.1 christos /* 2. new LSD is digit to left of coefficient (so MSD is */ 2976 1.1 christos /* round-for-reround digit) */ 2977 1.1 christos /* 3. new LSD is to left of case 2 (whole coefficient is sticky) */ 2978 1.1 christos /* Note that leading zeros can safely be treated as useful digits */ 2979 1.1 christos 2980 1.1 christos /* [duplicate check-stickies code to save a test] */ 2981 1.1 christos /* [by-digit check for stickies as runs of zeros are rare] */ 2982 1.1 christos if (drop<DECPMAX) { /* NB lengths not addresses */ 2983 1.1 christos roundat=BUFOFF+DECPMAX-drop; 2984 1.1 christos reround=*roundat; 2985 1.1 christos for (ub=roundat+1; ub<BUFOFF+DECPMAX; ub++) { 2986 1.1 christos if (*ub!=0) { /* non-zero to be discarded */ 2987 1.1 christos reround=DECSTICKYTAB[reround]; /* apply sticky bit */ 2988 1.1 christos break; /* [remainder don't-care] */ 2989 1.1 christos } 2990 1.1 christos } /* check stickies */ 2991 1.1 christos ulsd=roundat-1; /* set LSD */ 2992 1.1 christos } 2993 1.1 christos else { /* edge case */ 2994 1.1 christos if (drop==DECPMAX) { 2995 1.1 christos roundat=BUFOFF; 2996 1.1 christos reround=*roundat; 2997 1.1 christos } 2998 1.1 christos else { 2999 1.1 christos roundat=BUFOFF-1; 3000 1.1 christos reround=0; 3001 1.1 christos } 3002 1.1 christos for (ub=roundat+1; ub<BUFOFF+DECPMAX; ub++) { 3003 1.1 christos if (*ub!=0) { /* non-zero to be discarded */ 3004 1.1 christos reround=DECSTICKYTAB[reround]; /* apply sticky bit */ 3005 1.1 christos break; /* [remainder don't-care] */ 3006 1.1 christos } 3007 1.1 christos } /* check stickies */ 3008 1.1 christos *BUFOFF=0; /* make a coefficient of 0 */ 3009 1.1 christos ulsd=BUFOFF; /* .. at the MSD place */ 3010 1.1 christos } 3011 1.1 christos 3012 1.1 christos if (reround!=0) { /* discarding non-zero */ 3013 1.1 christos uInt bump=0; 3014 1.1 christos set->status|=DEC_Inexact; 3015 1.1 christos 3016 1.1 christos /* next decide whether to increment the coefficient */ 3017 1.1 christos if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ 3018 1.1 christos if (reround>5) bump=1; /* >0.5 goes up */ 3019 1.1 christos else if (reround==5) /* exactly 0.5000 .. */ 3020 1.1 christos bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ 3021 1.1 christos } /* r-h-e */ 3022 1.1 christos else switch (set->round) { 3023 1.1 christos case DEC_ROUND_DOWN: { 3024 1.1 christos /* no change */ 3025 1.1 christos break;} /* r-d */ 3026 1.1 christos case DEC_ROUND_HALF_DOWN: { 3027 1.1 christos if (reround>5) bump=1; 3028 1.1 christos break;} /* r-h-d */ 3029 1.1 christos case DEC_ROUND_HALF_UP: { 3030 1.1 christos if (reround>=5) bump=1; 3031 1.1 christos break;} /* r-h-u */ 3032 1.1 christos case DEC_ROUND_UP: { 3033 1.1 christos if (reround>0) bump=1; 3034 1.1 christos break;} /* r-u */ 3035 1.1 christos case DEC_ROUND_CEILING: { 3036 1.1 christos /* same as _UP for positive numbers, and as _DOWN for negatives */ 3037 1.1 christos if (!(sourhil&DECFLOAT_Sign) && reround>0) bump=1; 3038 1.1 christos break;} /* r-c */ 3039 1.1 christos case DEC_ROUND_FLOOR: { 3040 1.1 christos /* same as _UP for negative numbers, and as _DOWN for positive */ 3041 1.1 christos /* [negative reround cannot occur on 0] */ 3042 1.1 christos if (sourhil&DECFLOAT_Sign && reround>0) bump=1; 3043 1.1 christos break;} /* r-f */ 3044 1.1 christos case DEC_ROUND_05UP: { 3045 1.1 christos if (reround>0) { /* anything out there is 'sticky' */ 3046 1.1 christos /* bump iff lsd=0 or 5; this cannot carry so it could be */ 3047 1.1 christos /* effected immediately with no bump -- but the code */ 3048 1.1 christos /* is clearer if this is done the same way as the others */ 3049 1.1 christos if (*ulsd==0 || *ulsd==5) bump=1; 3050 1.1 christos } 3051 1.1 christos break;} /* r-r */ 3052 1.1 christos default: { /* e.g., DEC_ROUND_MAX */ 3053 1.1 christos set->status|=DEC_Invalid_context; 3054 1.1 christos #if DECCHECK 3055 1.1 christos printf("Unknown rounding mode: %ld\n", (LI)set->round); 3056 1.1 christos #endif 3057 1.1 christos break;} 3058 1.1 christos } /* switch (not r-h-e) */ 3059 1.1 christos /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ 3060 1.1 christos 3061 1.1 christos if (bump!=0) { /* need increment */ 3062 1.1 christos /* increment the coefficient; this could give 1000... (after */ 3063 1.1 christos /* the all nines case) */ 3064 1.1 christos ub=ulsd; 3065 1.1 christos for (; UBTOUI(ub-3)==0x09090909; ub-=4) UBFROMUI(ub-3, 0); 3066 1.1 christos /* now at most 3 digits left to non-9 (usually just the one) */ 3067 1.1 christos for (; *ub==9; ub--) *ub=0; 3068 1.1 christos *ub+=1; 3069 1.1 christos /* [the all-nines case will have carried one digit to the */ 3070 1.1 christos /* left of the original MSD -- just where it is needed] */ 3071 1.1 christos } /* bump needed */ 3072 1.1 christos } /* inexact rounding */ 3073 1.1 christos 3074 1.1 christos /* now clear zeros to the left so exactly DECPMAX digits will be */ 3075 1.1 christos /* available in the coefficent -- the first word to the left was */ 3076 1.1 christos /* cleared earlier for safe carry; now add any more needed */ 3077 1.1 christos if (drop>4) { 3078 1.1 christos UBFROMUI(BUFOFF-8, 0); /* must be at least 5 */ 3079 1.1 christos for (uc=BUFOFF-12; uc>ulsd-DECPMAX-3; uc-=4) UBFROMUI(uc, 0); 3080 1.1 christos } 3081 1.1 christos } /* need round (drop>0) */ 3082 1.1 christos 3083 1.1 christos else { /* drop<0; padding with -drop digits is needed */ 3084 1.1 christos /* This is the case where an error can occur if the padded */ 3085 1.1 christos /* coefficient will not fit; checking for this can be done in the */ 3086 1.1 christos /* same loop as padding for zeros if the no-hope and zero cases */ 3087 1.1 christos /* are checked first */ 3088 1.1 christos if (-drop>DECPMAX-1) { /* cannot fit unless 0 */ 3089 1.1 christos if (!ISCOEFFZERO(BUFOFF)) return decInvalid(result, set); 3090 1.1 christos /* a zero can have any exponent; just drop through and use it */ 3091 1.1 christos ulsd=BUFOFF+DECPMAX-1; 3092 1.1 christos } 3093 1.1 christos else { /* padding will fit (but may still be too long) */ 3094 1.1 christos /* final-word mask depends on endianess */ 3095 1.1 christos #if DECLITEND 3096 1.1 christos static const uInt dmask[]={0, 0x000000ff, 0x0000ffff, 0x00ffffff}; 3097 1.1 christos #else 3098 1.1 christos static const uInt dmask[]={0, 0xff000000, 0xffff0000, 0xffffff00}; 3099 1.1 christos #endif 3100 1.1 christos /* note that here zeros to the right are added by fours, so in */ 3101 1.1 christos /* the Quad case this could write 36 zeros if the coefficient has */ 3102 1.1 christos /* fewer than three significant digits (hence the +2*QUAD for buf) */ 3103 1.1 christos for (uc=BUFOFF+DECPMAX;; uc+=4) { 3104 1.1 christos UBFROMUI(uc, 0); 3105 1.1 christos if (UBTOUI(uc-DECPMAX)!=0) { /* could be bad */ 3106 1.1 christos /* if all four digits should be zero, definitely bad */ 3107 1.1 christos if (uc<=BUFOFF+DECPMAX+(-drop)-4) 3108 1.1 christos return decInvalid(result, set); 3109 1.1 christos /* must be a 1- to 3-digit sequence; check more carefully */ 3110 1.1 christos if ((UBTOUI(uc-DECPMAX)&dmask[(-drop)%4])!=0) 3111 1.1 christos return decInvalid(result, set); 3112 1.1 christos break; /* no need for loop end test */ 3113 1.1 christos } 3114 1.1 christos if (uc>=BUFOFF+DECPMAX+(-drop)-4) break; /* done */ 3115 1.1 christos } 3116 1.1 christos ulsd=BUFOFF+DECPMAX+(-drop)-1; 3117 1.1 christos } /* pad and check leading zeros */ 3118 1.1 christos } /* drop<0 */ 3119 1.1 christos 3120 1.1 christos #if DECTRACE 3121 1.1 christos num.msd=ulsd-DECPMAX+1; 3122 1.1 christos num.lsd=ulsd; 3123 1.1 christos num.exponent=explb-DECBIAS; 3124 1.1 christos num.sign=sourhil & DECFLOAT_Sign; 3125 1.1 christos decShowNum(&num, "res"); 3126 1.1 christos #endif 3127 1.1 christos 3128 1.1 christos /*------------------------------------------------------------------*/ 3129 1.1 christos /* At this point the result is DECPMAX digits, ending at ulsd, so */ 3130 1.1 christos /* fits the encoding exactly; there is no possibility of error */ 3131 1.1 christos /*------------------------------------------------------------------*/ 3132 1.1 christos encode=((exprb>>DECECONL)<<4) + *(ulsd-DECPMAX+1); /* make index */ 3133 1.1 christos encode=DECCOMBFROM[encode]; /* indexed by (0-2)*16+msd */ 3134 1.1 christos /* the exponent continuation can be extracted from the original RHS */ 3135 1.1 christos encode|=sourhir & ECONMASK; 3136 1.1 christos encode|=sourhil&DECFLOAT_Sign; /* add the sign from LHS */ 3137 1.1 christos 3138 1.1 christos /* finally encode the coefficient */ 3139 1.1 christos /* private macro to encode a declet; this version can be used */ 3140 1.1 christos /* because all coefficient digits exist */ 3141 1.1 christos #define getDPD3q(dpd, n) ub=ulsd-(3*(n))-2; \ 3142 1.1 christos dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; 3143 1.1 christos 3144 1.1 christos #if DOUBLE 3145 1.1 christos getDPD3q(dpd, 4); encode|=dpd<<8; 3146 1.1 christos getDPD3q(dpd, 3); encode|=dpd>>2; 3147 1.1 christos DFWORD(result, 0)=encode; 3148 1.1 christos encode=dpd<<30; 3149 1.1 christos getDPD3q(dpd, 2); encode|=dpd<<20; 3150 1.1 christos getDPD3q(dpd, 1); encode|=dpd<<10; 3151 1.1 christos getDPD3q(dpd, 0); encode|=dpd; 3152 1.1 christos DFWORD(result, 1)=encode; 3153 1.1 christos 3154 1.1 christos #elif QUAD 3155 1.1 christos getDPD3q(dpd,10); encode|=dpd<<4; 3156 1.1 christos getDPD3q(dpd, 9); encode|=dpd>>6; 3157 1.1 christos DFWORD(result, 0)=encode; 3158 1.1 christos encode=dpd<<26; 3159 1.1 christos getDPD3q(dpd, 8); encode|=dpd<<16; 3160 1.1 christos getDPD3q(dpd, 7); encode|=dpd<<6; 3161 1.1 christos getDPD3q(dpd, 6); encode|=dpd>>4; 3162 1.1 christos DFWORD(result, 1)=encode; 3163 1.1 christos encode=dpd<<28; 3164 1.1 christos getDPD3q(dpd, 5); encode|=dpd<<18; 3165 1.1 christos getDPD3q(dpd, 4); encode|=dpd<<8; 3166 1.1 christos getDPD3q(dpd, 3); encode|=dpd>>2; 3167 1.1 christos DFWORD(result, 2)=encode; 3168 1.1 christos encode=dpd<<30; 3169 1.1 christos getDPD3q(dpd, 2); encode|=dpd<<20; 3170 1.1 christos getDPD3q(dpd, 1); encode|=dpd<<10; 3171 1.1 christos getDPD3q(dpd, 0); encode|=dpd; 3172 1.1 christos DFWORD(result, 3)=encode; 3173 1.1 christos #endif 3174 1.1 christos return result; 3175 1.1 christos } /* decFloatQuantize */ 3176 1.1 christos 3177 1.1 christos /* ------------------------------------------------------------------ */ 3178 1.1 christos /* decFloatReduce -- reduce finite coefficient to minimum length */ 3179 1.1 christos /* */ 3180 1.1 christos /* result gets the reduced decFloat */ 3181 1.1 christos /* df is the source decFloat */ 3182 1.1 christos /* set is the context */ 3183 1.1 christos /* returns result, which will be canonical */ 3184 1.1 christos /* */ 3185 1.1 christos /* This removes all possible trailing zeros from the coefficient; */ 3186 1.1 christos /* some may remain when the number is very close to Nmax. */ 3187 1.1 christos /* Special values are unchanged and no status is set unless df=sNaN. */ 3188 1.1 christos /* Reduced zero has an exponent q=0. */ 3189 1.1 christos /* ------------------------------------------------------------------ */ 3190 1.1 christos decFloat * decFloatReduce(decFloat *result, const decFloat *df, 3191 1.1 christos decContext *set) { 3192 1.1 christos bcdnum num; /* work */ 3193 1.1 christos uByte buf[DECPMAX], *ub; /* coefficient and pointer */ 3194 1.1 christos if (df!=result) *result=*df; /* copy, if needed */ 3195 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); /* sNaN */ 3196 1.1 christos /* zeros and infinites propagate too */ 3197 1.1 christos if (DFISINF(df)) return decInfinity(result, df); /* canonical */ 3198 1.1 christos if (DFISZERO(df)) { 3199 1.1 christos uInt sign=DFWORD(df, 0)&DECFLOAT_Sign; 3200 1.1 christos decFloatZero(result); 3201 1.1 christos DFWORD(result, 0)|=sign; 3202 1.1 christos return result; /* exponent dropped, sign OK */ 3203 1.1 christos } 3204 1.1 christos /* non-zero finite */ 3205 1.1 christos GETCOEFF(df, buf); 3206 1.1 christos ub=buf+DECPMAX-1; /* -> lsd */ 3207 1.1 christos if (*ub) return result; /* no trailing zeros */ 3208 1.1 christos for (ub--; *ub==0;) ub--; /* terminates because non-zero */ 3209 1.1 christos /* *ub is the first non-zero from the right */ 3210 1.1 christos num.sign=DFWORD(df, 0)&DECFLOAT_Sign; /* set up number... */ 3211 1.1 christos num.exponent=GETEXPUN(df)+(Int)(buf+DECPMAX-1-ub); /* adjusted exponent */ 3212 1.1 christos num.msd=buf; 3213 1.1 christos num.lsd=ub; 3214 1.1 christos return decFinalize(result, &num, set); 3215 1.1 christos } /* decFloatReduce */ 3216 1.1 christos 3217 1.1 christos /* ------------------------------------------------------------------ */ 3218 1.1 christos /* decFloatRemainder -- integer divide and return remainder */ 3219 1.1 christos /* */ 3220 1.1 christos /* result gets the remainder of dividing dfl by dfr: */ 3221 1.1 christos /* dfl is the first decFloat (lhs) */ 3222 1.1 christos /* dfr is the second decFloat (rhs) */ 3223 1.1 christos /* set is the context */ 3224 1.1 christos /* returns result */ 3225 1.1 christos /* */ 3226 1.1 christos /* ------------------------------------------------------------------ */ 3227 1.1 christos decFloat * decFloatRemainder(decFloat *result, 3228 1.1 christos const decFloat *dfl, const decFloat *dfr, 3229 1.1 christos decContext *set) { 3230 1.1 christos return decDivide(result, dfl, dfr, set, REMAINDER); 3231 1.1 christos } /* decFloatRemainder */ 3232 1.1 christos 3233 1.1 christos /* ------------------------------------------------------------------ */ 3234 1.1 christos /* decFloatRemainderNear -- integer divide to nearest and remainder */ 3235 1.1 christos /* */ 3236 1.1 christos /* result gets the remainder of dividing dfl by dfr: */ 3237 1.1 christos /* dfl is the first decFloat (lhs) */ 3238 1.1 christos /* dfr is the second decFloat (rhs) */ 3239 1.1 christos /* set is the context */ 3240 1.1 christos /* returns result */ 3241 1.1 christos /* */ 3242 1.1 christos /* This is the IEEE remainder, where the nearest integer is used. */ 3243 1.1 christos /* ------------------------------------------------------------------ */ 3244 1.1 christos decFloat * decFloatRemainderNear(decFloat *result, 3245 1.1 christos const decFloat *dfl, const decFloat *dfr, 3246 1.1 christos decContext *set) { 3247 1.1 christos return decDivide(result, dfl, dfr, set, REMNEAR); 3248 1.1 christos } /* decFloatRemainderNear */ 3249 1.1 christos 3250 1.1 christos /* ------------------------------------------------------------------ */ 3251 1.1 christos /* decFloatRotate -- rotate the coefficient of a decFloat left/right */ 3252 1.1 christos /* */ 3253 1.1 christos /* result gets the result of rotating dfl */ 3254 1.1 christos /* dfl is the source decFloat to rotate */ 3255 1.1 christos /* dfr is the count of digits to rotate, an integer (with q=0) */ 3256 1.1 christos /* set is the context */ 3257 1.1 christos /* returns result */ 3258 1.1 christos /* */ 3259 1.1 christos /* The digits of the coefficient of dfl are rotated to the left (if */ 3260 1.1 christos /* dfr is positive) or to the right (if dfr is negative) without */ 3261 1.1 christos /* adjusting the exponent or the sign of dfl. */ 3262 1.1 christos /* */ 3263 1.1 christos /* dfr must be in the range -DECPMAX through +DECPMAX. */ 3264 1.1 christos /* NaNs are propagated as usual. An infinite dfl is unaffected (but */ 3265 1.1 christos /* dfr must be valid). No status is set unless dfr is invalid or an */ 3266 1.1 christos /* operand is an sNaN. The result is canonical. */ 3267 1.1 christos /* ------------------------------------------------------------------ */ 3268 1.1 christos #define PHALF (ROUNDUP(DECPMAX/2, 4)) /* half length, rounded up */ 3269 1.1 christos decFloat * decFloatRotate(decFloat *result, 3270 1.1 christos const decFloat *dfl, const decFloat *dfr, 3271 1.1 christos decContext *set) { 3272 1.1 christos Int rotate; /* dfr as an Int */ 3273 1.1 christos uByte buf[DECPMAX+PHALF]; /* coefficient + half */ 3274 1.1 christos uInt digits, savestat; /* work */ 3275 1.1 christos bcdnum num; /* .. */ 3276 1.1 christos uByte *ub; /* .. */ 3277 1.1 christos 3278 1.1 christos if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 3279 1.1 christos if (!DFISINT(dfr)) return decInvalid(result, set); 3280 1.1 christos digits=decFloatDigits(dfr); /* calculate digits */ 3281 1.1 christos if (digits>2) return decInvalid(result, set); /* definitely out of range */ 3282 1.1 christos rotate=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */ 3283 1.1 christos if (rotate>DECPMAX) return decInvalid(result, set); /* too big */ 3284 1.1 christos /* [from here on no error or status change is possible] */ 3285 1.1 christos if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */ 3286 1.1 christos /* handle no-rotate cases */ 3287 1.1 christos if (rotate==0 || rotate==DECPMAX) return decCanonical(result, dfl); 3288 1.1 christos /* a real rotate is needed: 0 < rotate < DECPMAX */ 3289 1.1 christos /* reduce the rotation to no more than half to reduce copying later */ 3290 1.1 christos /* (for QUAD in fact half + 2 digits) */ 3291 1.1 christos if (DFISSIGNED(dfr)) rotate=-rotate; 3292 1.1 christos if (abs(rotate)>PHALF) { 3293 1.1 christos if (rotate<0) rotate=DECPMAX+rotate; 3294 1.1 christos else rotate=rotate-DECPMAX; 3295 1.1 christos } 3296 1.1 christos /* now lay out the coefficient, leaving room to the right or the */ 3297 1.1 christos /* left depending on the direction of rotation */ 3298 1.1 christos ub=buf; 3299 1.1 christos if (rotate<0) ub+=PHALF; /* rotate right, so space to left */ 3300 1.1 christos GETCOEFF(dfl, ub); 3301 1.1 christos /* copy half the digits to left or right, and set num.msd */ 3302 1.1 christos if (rotate<0) { 3303 1.1 christos memcpy(buf, buf+DECPMAX, PHALF); 3304 1.1 christos num.msd=buf+PHALF+rotate; 3305 1.1 christos } 3306 1.1 christos else { 3307 1.1 christos memcpy(buf+DECPMAX, buf, PHALF); 3308 1.1 christos num.msd=buf+rotate; 3309 1.1 christos } 3310 1.1 christos /* fill in rest of num */ 3311 1.1 christos num.lsd=num.msd+DECPMAX-1; 3312 1.1 christos num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; 3313 1.1 christos num.exponent=GETEXPUN(dfl); 3314 1.1 christos savestat=set->status; /* record */ 3315 1.1 christos decFinalize(result, &num, set); 3316 1.1 christos set->status=savestat; /* restore */ 3317 1.1 christos return result; 3318 1.1 christos } /* decFloatRotate */ 3319 1.1 christos 3320 1.1 christos /* ------------------------------------------------------------------ */ 3321 1.1 christos /* decFloatSameQuantum -- test decFloats for same quantum */ 3322 1.1 christos /* */ 3323 1.1 christos /* dfl is the first decFloat (lhs) */ 3324 1.1 christos /* dfr is the second decFloat (rhs) */ 3325 1.1 christos /* returns 1 if the operands have the same quantum, 0 otherwise */ 3326 1.1 christos /* */ 3327 1.1 christos /* No error is possible and no status results. */ 3328 1.1 christos /* ------------------------------------------------------------------ */ 3329 1.1 christos uInt decFloatSameQuantum(const decFloat *dfl, const decFloat *dfr) { 3330 1.1 christos if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr)) { 3331 1.1 christos if (DFISNAN(dfl) && DFISNAN(dfr)) return 1; 3332 1.1 christos if (DFISINF(dfl) && DFISINF(dfr)) return 1; 3333 1.1 christos return 0; /* any other special mixture gives false */ 3334 1.1 christos } 3335 1.1 christos if (GETEXP(dfl)==GETEXP(dfr)) return 1; /* biased exponents match */ 3336 1.1 christos return 0; 3337 1.1 christos } /* decFloatSameQuantum */ 3338 1.1 christos 3339 1.1 christos /* ------------------------------------------------------------------ */ 3340 1.1 christos /* decFloatScaleB -- multiply by a power of 10, as per 754 */ 3341 1.1 christos /* */ 3342 1.1 christos /* result gets the result of the operation */ 3343 1.1 christos /* dfl is the first decFloat (lhs) */ 3344 1.1 christos /* dfr is the second decFloat (rhs), am integer (with q=0) */ 3345 1.1 christos /* set is the context */ 3346 1.1 christos /* returns result */ 3347 1.1 christos /* */ 3348 1.1 christos /* This computes result=dfl x 10**dfr where dfr is an integer in the */ 3349 1.1 christos /* range +/-2*(emax+pmax), typically resulting from LogB. */ 3350 1.1 christos /* Underflow and Overflow (with Inexact) may occur. NaNs propagate */ 3351 1.1 christos /* as usual. */ 3352 1.1 christos /* ------------------------------------------------------------------ */ 3353 1.1 christos #define SCALEBMAX 2*(DECEMAX+DECPMAX) /* D=800, Q=12356 */ 3354 1.1 christos decFloat * decFloatScaleB(decFloat *result, 3355 1.1 christos const decFloat *dfl, const decFloat *dfr, 3356 1.1 christos decContext *set) { 3357 1.1 christos uInt digits; /* work */ 3358 1.1 christos Int expr; /* dfr as an Int */ 3359 1.1 christos 3360 1.1 christos if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 3361 1.1 christos if (!DFISINT(dfr)) return decInvalid(result, set); 3362 1.1 christos digits=decFloatDigits(dfr); /* calculate digits */ 3363 1.1 christos 3364 1.1 christos #if DOUBLE 3365 1.1 christos if (digits>3) return decInvalid(result, set); /* definitely out of range */ 3366 1.1 christos expr=DPD2BIN[DFWORD(dfr, 1)&0x3ff]; /* must be in bottom declet */ 3367 1.1 christos #elif QUAD 3368 1.1 christos if (digits>5) return decInvalid(result, set); /* definitely out of range */ 3369 1.1 christos expr=DPD2BIN[DFWORD(dfr, 3)&0x3ff] /* in bottom 2 declets .. */ 3370 1.1 christos +DPD2BIN[(DFWORD(dfr, 3)>>10)&0x3ff]*1000; /* .. */ 3371 1.1 christos #endif 3372 1.1 christos if (expr>SCALEBMAX) return decInvalid(result, set); /* oops */ 3373 1.1 christos /* [from now on no error possible] */ 3374 1.1 christos if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */ 3375 1.1 christos if (DFISSIGNED(dfr)) expr=-expr; 3376 1.1 christos /* dfl is finite and expr is valid */ 3377 1.1 christos *result=*dfl; /* copy to target */ 3378 1.1 christos return decFloatSetExponent(result, set, GETEXPUN(result)+expr); 3379 1.1 christos } /* decFloatScaleB */ 3380 1.1 christos 3381 1.1 christos /* ------------------------------------------------------------------ */ 3382 1.1 christos /* decFloatShift -- shift the coefficient of a decFloat left or right */ 3383 1.1 christos /* */ 3384 1.1 christos /* result gets the result of shifting dfl */ 3385 1.1 christos /* dfl is the source decFloat to shift */ 3386 1.1 christos /* dfr is the count of digits to shift, an integer (with q=0) */ 3387 1.1 christos /* set is the context */ 3388 1.1 christos /* returns result */ 3389 1.1 christos /* */ 3390 1.1 christos /* The digits of the coefficient of dfl are shifted to the left (if */ 3391 1.1 christos /* dfr is positive) or to the right (if dfr is negative) without */ 3392 1.1 christos /* adjusting the exponent or the sign of dfl. */ 3393 1.1 christos /* */ 3394 1.1 christos /* dfr must be in the range -DECPMAX through +DECPMAX. */ 3395 1.1 christos /* NaNs are propagated as usual. An infinite dfl is unaffected (but */ 3396 1.1 christos /* dfr must be valid). No status is set unless dfr is invalid or an */ 3397 1.1 christos /* operand is an sNaN. The result is canonical. */ 3398 1.1 christos /* ------------------------------------------------------------------ */ 3399 1.1 christos decFloat * decFloatShift(decFloat *result, 3400 1.1 christos const decFloat *dfl, const decFloat *dfr, 3401 1.1 christos decContext *set) { 3402 1.1 christos Int shift; /* dfr as an Int */ 3403 1.1 christos uByte buf[DECPMAX*2]; /* coefficient + padding */ 3404 1.1 christos uInt digits, savestat; /* work */ 3405 1.1 christos bcdnum num; /* .. */ 3406 1.1 christos uInt uiwork; /* for macros */ 3407 1.1 christos 3408 1.1 christos if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); 3409 1.1 christos if (!DFISINT(dfr)) return decInvalid(result, set); 3410 1.1 christos digits=decFloatDigits(dfr); /* calculate digits */ 3411 1.1 christos if (digits>2) return decInvalid(result, set); /* definitely out of range */ 3412 1.1 christos shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; /* is in bottom declet */ 3413 1.1 christos if (shift>DECPMAX) return decInvalid(result, set); /* too big */ 3414 1.1 christos /* [from here on no error or status change is possible] */ 3415 1.1 christos 3416 1.1 christos if (DFISINF(dfl)) return decInfinity(result, dfl); /* canonical */ 3417 1.1 christos /* handle no-shift and all-shift (clear to zero) cases */ 3418 1.1 christos if (shift==0) return decCanonical(result, dfl); 3419 1.1 christos if (shift==DECPMAX) { /* zero with sign */ 3420 1.1 christos uByte sign=(uByte)(DFBYTE(dfl, 0)&0x80); /* save sign bit */ 3421 1.1 christos decFloatZero(result); /* make +0 */ 3422 1.1 christos DFBYTE(result, 0)=(uByte)(DFBYTE(result, 0)|sign); /* and set sign */ 3423 1.1 christos /* [cannot safely use CopySign] */ 3424 1.1 christos return result; 3425 1.1 christos } 3426 1.1 christos /* a real shift is needed: 0 < shift < DECPMAX */ 3427 1.1 christos num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign; 3428 1.1 christos num.exponent=GETEXPUN(dfl); 3429 1.1 christos num.msd=buf; 3430 1.1 christos GETCOEFF(dfl, buf); 3431 1.1 christos if (DFISSIGNED(dfr)) { /* shift right */ 3432 1.1 christos /* edge cases are taken care of, so this is easy */ 3433 1.1 christos num.lsd=buf+DECPMAX-shift-1; 3434 1.1 christos } 3435 1.1 christos else { /* shift left -- zero padding needed to right */ 3436 1.1 christos UBFROMUI(buf+DECPMAX, 0); /* 8 will handle most cases */ 3437 1.1 christos UBFROMUI(buf+DECPMAX+4, 0); /* .. */ 3438 1.1 christos if (shift>8) memset(buf+DECPMAX+8, 0, 8+QUAD*18); /* all other cases */ 3439 1.1 christos num.msd+=shift; 3440 1.1 christos num.lsd=num.msd+DECPMAX-1; 3441 1.1 christos } 3442 1.1 christos savestat=set->status; /* record */ 3443 1.1 christos decFinalize(result, &num, set); 3444 1.1 christos set->status=savestat; /* restore */ 3445 1.1 christos return result; 3446 1.1 christos } /* decFloatShift */ 3447 1.1 christos 3448 1.1 christos /* ------------------------------------------------------------------ */ 3449 1.1 christos /* decFloatSubtract -- subtract a decFloat from another */ 3450 1.1 christos /* */ 3451 1.1 christos /* result gets the result of subtracting dfr from dfl: */ 3452 1.1 christos /* dfl is the first decFloat (lhs) */ 3453 1.1 christos /* dfr is the second decFloat (rhs) */ 3454 1.1 christos /* set is the context */ 3455 1.1 christos /* returns result */ 3456 1.1 christos /* */ 3457 1.1 christos /* ------------------------------------------------------------------ */ 3458 1.1 christos decFloat * decFloatSubtract(decFloat *result, 3459 1.1 christos const decFloat *dfl, const decFloat *dfr, 3460 1.1 christos decContext *set) { 3461 1.1 christos decFloat temp; 3462 1.1 christos /* NaNs must propagate without sign change */ 3463 1.1 christos if (DFISNAN(dfr)) return decFloatAdd(result, dfl, dfr, set); 3464 1.1 christos temp=*dfr; /* make a copy */ 3465 1.1 christos DFBYTE(&temp, 0)^=0x80; /* flip sign */ 3466 1.1 christos return decFloatAdd(result, dfl, &temp, set); /* and add to the lhs */ 3467 1.1 christos } /* decFloatSubtract */ 3468 1.1 christos 3469 1.1 christos /* ------------------------------------------------------------------ */ 3470 1.1 christos /* decFloatToInt -- round to 32-bit binary integer (4 flavours) */ 3471 1.1 christos /* */ 3472 1.1 christos /* df is the decFloat to round */ 3473 1.1 christos /* set is the context */ 3474 1.1 christos /* round is the rounding mode to use */ 3475 1.1 christos /* returns a uInt or an Int, rounded according to the name */ 3476 1.1 christos /* */ 3477 1.1 christos /* Invalid will always be signaled if df is a NaN, is Infinite, or is */ 3478 1.1 christos /* outside the range of the target; Inexact will not be signaled for */ 3479 1.1 christos /* simple rounding unless 'Exact' appears in the name. */ 3480 1.1 christos /* ------------------------------------------------------------------ */ 3481 1.1 christos uInt decFloatToUInt32(const decFloat *df, decContext *set, 3482 1.1 christos enum rounding round) { 3483 1.1 christos return decToInt32(df, set, round, 0, 1);} 3484 1.1 christos 3485 1.1 christos uInt decFloatToUInt32Exact(const decFloat *df, decContext *set, 3486 1.1 christos enum rounding round) { 3487 1.1 christos return decToInt32(df, set, round, 1, 1);} 3488 1.1 christos 3489 1.1 christos Int decFloatToInt32(const decFloat *df, decContext *set, 3490 1.1 christos enum rounding round) { 3491 1.1 christos return (Int)decToInt32(df, set, round, 0, 0);} 3492 1.1 christos 3493 1.1 christos Int decFloatToInt32Exact(const decFloat *df, decContext *set, 3494 1.1 christos enum rounding round) { 3495 1.1 christos return (Int)decToInt32(df, set, round, 1, 0);} 3496 1.1 christos 3497 1.1 christos /* ------------------------------------------------------------------ */ 3498 1.1 christos /* decFloatToIntegral -- round to integral value (two flavours) */ 3499 1.1 christos /* */ 3500 1.1 christos /* result gets the result */ 3501 1.1 christos /* df is the decFloat to round */ 3502 1.1 christos /* set is the context */ 3503 1.1 christos /* round is the rounding mode to use */ 3504 1.1 christos /* returns result */ 3505 1.1 christos /* */ 3506 1.1 christos /* No exceptions, even Inexact, are raised except for sNaN input, or */ 3507 1.1 christos /* if 'Exact' appears in the name. */ 3508 1.1 christos /* ------------------------------------------------------------------ */ 3509 1.1 christos decFloat * decFloatToIntegralValue(decFloat *result, const decFloat *df, 3510 1.1 christos decContext *set, enum rounding round) { 3511 1.1 christos return decToIntegral(result, df, set, round, 0);} 3512 1.1 christos 3513 1.1 christos decFloat * decFloatToIntegralExact(decFloat *result, const decFloat *df, 3514 1.1 christos decContext *set) { 3515 1.1 christos return decToIntegral(result, df, set, set->round, 1);} 3516 1.1 christos 3517 1.1 christos /* ------------------------------------------------------------------ */ 3518 1.1 christos /* decFloatXor -- logical digitwise XOR of two decFloats */ 3519 1.1 christos /* */ 3520 1.1 christos /* result gets the result of XORing dfl and dfr */ 3521 1.1 christos /* dfl is the first decFloat (lhs) */ 3522 1.1 christos /* dfr is the second decFloat (rhs) */ 3523 1.1 christos /* set is the context */ 3524 1.1 christos /* returns result, which will be canonical with sign=0 */ 3525 1.1 christos /* */ 3526 1.1 christos /* The operands must be positive, finite with exponent q=0, and */ 3527 1.1 christos /* comprise just zeros and ones; if not, Invalid operation results. */ 3528 1.1 christos /* ------------------------------------------------------------------ */ 3529 1.1 christos decFloat * decFloatXor(decFloat *result, 3530 1.1 christos const decFloat *dfl, const decFloat *dfr, 3531 1.1 christos decContext *set) { 3532 1.1 christos if (!DFISUINT01(dfl) || !DFISUINT01(dfr) 3533 1.1 christos || !DFISCC01(dfl) || !DFISCC01(dfr)) return decInvalid(result, set); 3534 1.1 christos /* the operands are positive finite integers (q=0) with just 0s and 1s */ 3535 1.1 christos #if DOUBLE 3536 1.1 christos DFWORD(result, 0)=ZEROWORD 3537 1.1 christos |((DFWORD(dfl, 0) ^ DFWORD(dfr, 0))&0x04009124); 3538 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) ^ DFWORD(dfr, 1))&0x49124491; 3539 1.1 christos #elif QUAD 3540 1.1 christos DFWORD(result, 0)=ZEROWORD 3541 1.1 christos |((DFWORD(dfl, 0) ^ DFWORD(dfr, 0))&0x04000912); 3542 1.1 christos DFWORD(result, 1)=(DFWORD(dfl, 1) ^ DFWORD(dfr, 1))&0x44912449; 3543 1.1 christos DFWORD(result, 2)=(DFWORD(dfl, 2) ^ DFWORD(dfr, 2))&0x12449124; 3544 1.1 christos DFWORD(result, 3)=(DFWORD(dfl, 3) ^ DFWORD(dfr, 3))&0x49124491; 3545 1.1 christos #endif 3546 1.1 christos return result; 3547 1.1 christos } /* decFloatXor */ 3548 1.1 christos 3549 1.1 christos /* ------------------------------------------------------------------ */ 3550 1.1 christos /* decInvalid -- set Invalid_operation result */ 3551 1.1 christos /* */ 3552 1.1 christos /* result gets a canonical NaN */ 3553 1.1 christos /* set is the context */ 3554 1.1 christos /* returns result */ 3555 1.1 christos /* */ 3556 1.1 christos /* status has Invalid_operation added */ 3557 1.1 christos /* ------------------------------------------------------------------ */ 3558 1.1 christos static decFloat *decInvalid(decFloat *result, decContext *set) { 3559 1.1 christos decFloatZero(result); 3560 1.1 christos DFWORD(result, 0)=DECFLOAT_qNaN; 3561 1.1 christos set->status|=DEC_Invalid_operation; 3562 1.1 christos return result; 3563 1.1 christos } /* decInvalid */ 3564 1.1 christos 3565 1.1 christos /* ------------------------------------------------------------------ */ 3566 1.1 christos /* decInfinity -- set canonical Infinity with sign from a decFloat */ 3567 1.1 christos /* */ 3568 1.1 christos /* result gets a canonical Infinity */ 3569 1.1 christos /* df is source decFloat (only the sign is used) */ 3570 1.1 christos /* returns result */ 3571 1.1 christos /* */ 3572 1.1 christos /* df may be the same as result */ 3573 1.1 christos /* ------------------------------------------------------------------ */ 3574 1.1 christos static decFloat *decInfinity(decFloat *result, const decFloat *df) { 3575 1.1 christos uInt sign=DFWORD(df, 0); /* save source signword */ 3576 1.1 christos decFloatZero(result); /* clear everything */ 3577 1.1 christos DFWORD(result, 0)=DECFLOAT_Inf | (sign & DECFLOAT_Sign); 3578 1.1 christos return result; 3579 1.1 christos } /* decInfinity */ 3580 1.1 christos 3581 1.1 christos /* ------------------------------------------------------------------ */ 3582 1.1 christos /* decNaNs -- handle NaN argument(s) */ 3583 1.1 christos /* */ 3584 1.1 christos /* result gets the result of handling dfl and dfr, one or both of */ 3585 1.1 christos /* which is a NaN */ 3586 1.1 christos /* dfl is the first decFloat (lhs) */ 3587 1.1 christos /* dfr is the second decFloat (rhs) -- may be NULL for a single- */ 3588 1.1 christos /* operand operation */ 3589 1.1 christos /* set is the context */ 3590 1.1 christos /* returns result */ 3591 1.1 christos /* */ 3592 1.1 christos /* Called when one or both operands is a NaN, and propagates the */ 3593 1.1 christos /* appropriate result to res. When an sNaN is found, it is changed */ 3594 1.1 christos /* to a qNaN and Invalid operation is set. */ 3595 1.1 christos /* ------------------------------------------------------------------ */ 3596 1.1 christos static decFloat *decNaNs(decFloat *result, 3597 1.1 christos const decFloat *dfl, const decFloat *dfr, 3598 1.1 christos decContext *set) { 3599 1.1 christos /* handle sNaNs first */ 3600 1.1 christos if (dfr!=NULL && DFISSNAN(dfr) && !DFISSNAN(dfl)) dfl=dfr; /* use RHS */ 3601 1.1 christos if (DFISSNAN(dfl)) { 3602 1.1 christos decCanonical(result, dfl); /* propagate canonical sNaN */ 3603 1.1 christos DFWORD(result, 0)&=~(DECFLOAT_qNaN ^ DECFLOAT_sNaN); /* quiet */ 3604 1.1 christos set->status|=DEC_Invalid_operation; 3605 1.1 christos return result; 3606 1.1 christos } 3607 1.1 christos /* one or both is a quiet NaN */ 3608 1.1 christos if (!DFISNAN(dfl)) dfl=dfr; /* RHS must be NaN, use it */ 3609 1.1 christos return decCanonical(result, dfl); /* propagate canonical qNaN */ 3610 1.1 christos } /* decNaNs */ 3611 1.1 christos 3612 1.1 christos /* ------------------------------------------------------------------ */ 3613 1.1 christos /* decNumCompare -- numeric comparison of two decFloats */ 3614 1.1 christos /* */ 3615 1.1 christos /* dfl is the left-hand decFloat, which is not a NaN */ 3616 1.1 christos /* dfr is the right-hand decFloat, which is not a NaN */ 3617 1.1 christos /* tot is 1 for total order compare, 0 for simple numeric */ 3618 1.1 christos /* returns -1, 0, or +1 for dfl<dfr, dfl=dfr, dfl>dfr */ 3619 1.1 christos /* */ 3620 1.1 christos /* No error is possible; status and mode are unchanged. */ 3621 1.1 christos /* ------------------------------------------------------------------ */ 3622 1.1 christos static Int decNumCompare(const decFloat *dfl, const decFloat *dfr, Flag tot) { 3623 1.1 christos Int sigl, sigr; /* LHS and RHS non-0 signums */ 3624 1.1 christos Int shift; /* shift needed to align operands */ 3625 1.1 christos uByte *ub, *uc; /* work */ 3626 1.1 christos uInt uiwork; /* for macros */ 3627 1.1 christos /* buffers +2 if Quad (36 digits), need double plus 4 for safe padding */ 3628 1.1 christos uByte bufl[DECPMAX*2+QUAD*2+4]; /* for LHS coefficient + padding */ 3629 1.1 christos uByte bufr[DECPMAX*2+QUAD*2+4]; /* for RHS coefficient + padding */ 3630 1.1 christos 3631 1.1 christos sigl=1; 3632 1.1 christos if (DFISSIGNED(dfl)) { 3633 1.1 christos if (!DFISSIGNED(dfr)) { /* -LHS +RHS */ 3634 1.1 christos if (DFISZERO(dfl) && DFISZERO(dfr) && !tot) return 0; 3635 1.1 christos return -1; /* RHS wins */ 3636 1.1 christos } 3637 1.1 christos sigl=-1; 3638 1.1 christos } 3639 1.1 christos if (DFISSIGNED(dfr)) { 3640 1.1 christos if (!DFISSIGNED(dfl)) { /* +LHS -RHS */ 3641 1.1 christos if (DFISZERO(dfl) && DFISZERO(dfr) && !tot) return 0; 3642 1.1 christos return +1; /* LHS wins */ 3643 1.1 christos } 3644 1.1 christos } 3645 1.1 christos 3646 1.1 christos /* signs are the same; operand(s) could be zero */ 3647 1.1 christos sigr=-sigl; /* sign to return if abs(RHS) wins */ 3648 1.1 christos 3649 1.1 christos if (DFISINF(dfl)) { 3650 1.1 christos if (DFISINF(dfr)) return 0; /* both infinite & same sign */ 3651 1.1 christos return sigl; /* inf > n */ 3652 1.1 christos } 3653 1.1 christos if (DFISINF(dfr)) return sigr; /* n < inf [dfl is finite] */ 3654 1.1 christos 3655 1.1 christos /* here, both are same sign and finite; calculate their offset */ 3656 1.1 christos shift=GETEXP(dfl)-GETEXP(dfr); /* [0 means aligned] */ 3657 1.1 christos /* [bias can be ignored -- the absolute exponent is not relevant] */ 3658 1.1 christos 3659 1.1 christos if (DFISZERO(dfl)) { 3660 1.1 christos if (!DFISZERO(dfr)) return sigr; /* LHS=0, RHS!=0 */ 3661 1.1 christos /* both are zero, return 0 if both same exponent or numeric compare */ 3662 1.1 christos if (shift==0 || !tot) return 0; 3663 1.1 christos if (shift>0) return sigl; 3664 1.1 christos return sigr; /* [shift<0] */ 3665 1.1 christos } 3666 1.1 christos else { /* LHS!=0 */ 3667 1.1 christos if (DFISZERO(dfr)) return sigl; /* LHS!=0, RHS=0 */ 3668 1.1 christos } 3669 1.1 christos /* both are known to be non-zero at this point */ 3670 1.1 christos 3671 1.1 christos /* if the exponents are so different that the coefficients do not */ 3672 1.1 christos /* overlap (by even one digit) then a full comparison is not needed */ 3673 1.1 christos if (abs(shift)>=DECPMAX) { /* no overlap */ 3674 1.1 christos /* coefficients are known to be non-zero */ 3675 1.1 christos if (shift>0) return sigl; 3676 1.1 christos return sigr; /* [shift<0] */ 3677 1.1 christos } 3678 1.1 christos 3679 1.1 christos /* decode the coefficients */ 3680 1.1 christos /* (shift both right two if Quad to make a multiple of four) */ 3681 1.1 christos #if QUAD 3682 1.1 christos UBFROMUI(bufl, 0); 3683 1.1 christos UBFROMUI(bufr, 0); 3684 1.1 christos #endif 3685 1.1 christos GETCOEFF(dfl, bufl+QUAD*2); /* decode from decFloat */ 3686 1.1 christos GETCOEFF(dfr, bufr+QUAD*2); /* .. */ 3687 1.1 christos if (shift==0) { /* aligned; common and easy */ 3688 1.1 christos /* all multiples of four, here */ 3689 1.1 christos for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) { 3690 1.1 christos uInt ui=UBTOUI(ub); 3691 1.1 christos if (ui==UBTOUI(uc)) continue; /* so far so same */ 3692 1.1 christos /* about to find a winner; go by bytes in case little-endian */ 3693 1.1 christos for (;; ub++, uc++) { 3694 1.1 christos if (*ub>*uc) return sigl; /* difference found */ 3695 1.1 christos if (*ub<*uc) return sigr; /* .. */ 3696 1.1 christos } 3697 1.1 christos } 3698 1.1 christos } /* aligned */ 3699 1.1 christos else if (shift>0) { /* lhs to left */ 3700 1.1 christos ub=bufl; /* RHS pointer */ 3701 1.1 christos /* pad bufl so right-aligned; most shifts will fit in 8 */ 3702 1.1 christos UBFROMUI(bufl+DECPMAX+QUAD*2, 0); /* add eight zeros */ 3703 1.1 christos UBFROMUI(bufl+DECPMAX+QUAD*2+4, 0); /* .. */ 3704 1.1 christos if (shift>8) { 3705 1.1 christos /* more than eight; fill the rest, and also worth doing the */ 3706 1.1 christos /* lead-in by fours */ 3707 1.1 christos uByte *up; /* work */ 3708 1.1 christos uByte *upend=bufl+DECPMAX+QUAD*2+shift; 3709 1.1 christos for (up=bufl+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0); 3710 1.1 christos /* [pads up to 36 in all for Quad] */ 3711 1.1 christos for (;; ub+=4) { 3712 1.1 christos if (UBTOUI(ub)!=0) return sigl; 3713 1.1 christos if (ub+4>bufl+shift-4) break; 3714 1.1 christos } 3715 1.1 christos } 3716 1.1 christos /* check remaining leading digits */ 3717 1.1 christos for (; ub<bufl+shift; ub++) if (*ub!=0) return sigl; 3718 1.1 christos /* now start the overlapped part; bufl has been padded, so the */ 3719 1.1 christos /* comparison can go for the full length of bufr, which is a */ 3720 1.1 christos /* multiple of 4 bytes */ 3721 1.1 christos for (uc=bufr; ; uc+=4, ub+=4) { 3722 1.1 christos uInt ui=UBTOUI(ub); 3723 1.1 christos if (ui!=UBTOUI(uc)) { /* mismatch found */ 3724 1.1 christos for (;; uc++, ub++) { /* check from left [little-endian?] */ 3725 1.1 christos if (*ub>*uc) return sigl; /* difference found */ 3726 1.1 christos if (*ub<*uc) return sigr; /* .. */ 3727 1.1 christos } 3728 1.1 christos } /* mismatch */ 3729 1.1 christos if (uc==bufr+QUAD*2+DECPMAX-4) break; /* all checked */ 3730 1.1 christos } 3731 1.1 christos } /* shift>0 */ 3732 1.1 christos 3733 1.1 christos else { /* shift<0) .. RHS is to left of LHS; mirror shift>0 */ 3734 1.1 christos uc=bufr; /* RHS pointer */ 3735 1.1 christos /* pad bufr so right-aligned; most shifts will fit in 8 */ 3736 1.1 christos UBFROMUI(bufr+DECPMAX+QUAD*2, 0); /* add eight zeros */ 3737 1.1 christos UBFROMUI(bufr+DECPMAX+QUAD*2+4, 0); /* .. */ 3738 1.1 christos if (shift<-8) { 3739 1.1 christos /* more than eight; fill the rest, and also worth doing the */ 3740 1.1 christos /* lead-in by fours */ 3741 1.1 christos uByte *up; /* work */ 3742 1.1 christos uByte *upend=bufr+DECPMAX+QUAD*2-shift; 3743 1.1 christos for (up=bufr+DECPMAX+QUAD*2+8; up<upend; up+=4) UBFROMUI(up, 0); 3744 1.1 christos /* [pads up to 36 in all for Quad] */ 3745 1.1 christos for (;; uc+=4) { 3746 1.1 christos if (UBTOUI(uc)!=0) return sigr; 3747 1.1 christos if (uc+4>bufr-shift-4) break; 3748 1.1 christos } 3749 1.1 christos } 3750 1.1 christos /* check remaining leading digits */ 3751 1.1 christos for (; uc<bufr-shift; uc++) if (*uc!=0) return sigr; 3752 1.1 christos /* now start the overlapped part; bufr has been padded, so the */ 3753 1.1 christos /* comparison can go for the full length of bufl, which is a */ 3754 1.1 christos /* multiple of 4 bytes */ 3755 1.1 christos for (ub=bufl; ; ub+=4, uc+=4) { 3756 1.1 christos uInt ui=UBTOUI(ub); 3757 1.1 christos if (ui!=UBTOUI(uc)) { /* mismatch found */ 3758 1.1 christos for (;; ub++, uc++) { /* check from left [little-endian?] */ 3759 1.1 christos if (*ub>*uc) return sigl; /* difference found */ 3760 1.1 christos if (*ub<*uc) return sigr; /* .. */ 3761 1.1 christos } 3762 1.1 christos } /* mismatch */ 3763 1.1 christos if (ub==bufl+QUAD*2+DECPMAX-4) break; /* all checked */ 3764 1.1 christos } 3765 1.1 christos } /* shift<0 */ 3766 1.1 christos 3767 1.1 christos /* Here when compare equal */ 3768 1.1 christos if (!tot) return 0; /* numerically equal */ 3769 1.1 christos /* total ordering .. exponent matters */ 3770 1.1 christos if (shift>0) return sigl; /* total order by exponent */ 3771 1.1 christos if (shift<0) return sigr; /* .. */ 3772 1.1 christos return 0; 3773 1.1 christos } /* decNumCompare */ 3774 1.1 christos 3775 1.1 christos /* ------------------------------------------------------------------ */ 3776 1.1 christos /* decToInt32 -- local routine to effect ToInteger conversions */ 3777 1.1 christos /* */ 3778 1.1 christos /* df is the decFloat to convert */ 3779 1.1 christos /* set is the context */ 3780 1.1 christos /* rmode is the rounding mode to use */ 3781 1.1 christos /* exact is 1 if Inexact should be signalled */ 3782 1.1 christos /* unsign is 1 if the result a uInt, 0 if an Int (cast to uInt) */ 3783 1.1 christos /* returns 32-bit result as a uInt */ 3784 1.1 christos /* */ 3785 1.1 christos /* Invalid is set is df is a NaN, is infinite, or is out-of-range; in */ 3786 1.1 christos /* these cases 0 is returned. */ 3787 1.1 christos /* ------------------------------------------------------------------ */ 3788 1.1 christos static uInt decToInt32(const decFloat *df, decContext *set, 3789 1.1 christos enum rounding rmode, Flag exact, Flag unsign) { 3790 1.1 christos Int exp; /* exponent */ 3791 1.1 christos uInt sourhi, sourpen, sourlo; /* top word from source decFloat .. */ 3792 1.1 christos uInt hi, lo; /* .. penultimate, least, etc. */ 3793 1.1 christos decFloat zero, result; /* work */ 3794 1.1 christos Int i; /* .. */ 3795 1.1 christos 3796 1.1 christos /* Start decoding the argument */ 3797 1.1 christos sourhi=DFWORD(df, 0); /* top word */ 3798 1.1 christos exp=DECCOMBEXP[sourhi>>26]; /* get exponent high bits (in place) */ 3799 1.1 christos if (EXPISSPECIAL(exp)) { /* is special? */ 3800 1.1 christos set->status|=DEC_Invalid_operation; /* signal */ 3801 1.1 christos return 0; 3802 1.1 christos } 3803 1.1 christos 3804 1.1 christos /* Here when the argument is finite */ 3805 1.1 christos if (GETEXPUN(df)==0) result=*df; /* already a true integer */ 3806 1.1 christos else { /* need to round to integer */ 3807 1.1 christos enum rounding saveround; /* saver */ 3808 1.1 christos uInt savestatus; /* .. */ 3809 1.1 christos saveround=set->round; /* save rounding mode .. */ 3810 1.1 christos savestatus=set->status; /* .. and status */ 3811 1.1 christos set->round=rmode; /* set mode */ 3812 1.1 christos decFloatZero(&zero); /* make 0E+0 */ 3813 1.1 christos set->status=0; /* clear */ 3814 1.1 christos decFloatQuantize(&result, df, &zero, set); /* [this may fail] */ 3815 1.1 christos set->round=saveround; /* restore rounding mode .. */ 3816 1.1 christos if (exact) set->status|=savestatus; /* include Inexact */ 3817 1.1 christos else set->status=savestatus; /* .. or just original status */ 3818 1.1 christos } 3819 1.1 christos 3820 1.1 christos /* only the last four declets of the coefficient can contain */ 3821 1.1 christos /* non-zero; check for others (and also NaN or Infinity from the */ 3822 1.1 christos /* Quantize) first (see DFISZERO for explanation): */ 3823 1.1 christos /* decFloatShow(&result, "sofar"); */ 3824 1.1 christos #if DOUBLE 3825 1.1 christos if ((DFWORD(&result, 0)&0x1c03ff00)!=0 3826 1.1 christos || (DFWORD(&result, 0)&0x60000000)==0x60000000) { 3827 1.1 christos #elif QUAD 3828 1.1 christos if ((DFWORD(&result, 2)&0xffffff00)!=0 3829 1.1 christos || DFWORD(&result, 1)!=0 3830 1.1 christos || (DFWORD(&result, 0)&0x1c003fff)!=0 3831 1.1 christos || (DFWORD(&result, 0)&0x60000000)==0x60000000) { 3832 1.1 christos #endif 3833 1.1 christos set->status|=DEC_Invalid_operation; /* Invalid or out of range */ 3834 1.1 christos return 0; 3835 1.1 christos } 3836 1.1 christos /* get last twelve digits of the coefficent into hi & ho, base */ 3837 1.1 christos /* 10**9 (see GETCOEFFBILL): */ 3838 1.1 christos sourlo=DFWORD(&result, DECWORDS-1); 3839 1.1 christos lo=DPD2BIN0[sourlo&0x3ff] 3840 1.1 christos +DPD2BINK[(sourlo>>10)&0x3ff] 3841 1.1 christos +DPD2BINM[(sourlo>>20)&0x3ff]; 3842 1.1 christos sourpen=DFWORD(&result, DECWORDS-2); 3843 1.1 christos hi=DPD2BIN0[((sourpen<<2) | (sourlo>>30))&0x3ff]; 3844 1.1 christos 3845 1.1 christos /* according to request, check range carefully */ 3846 1.1 christos if (unsign) { 3847 1.1 christos if (hi>4 || (hi==4 && lo>294967295) || (hi+lo!=0 && DFISSIGNED(&result))) { 3848 1.1 christos set->status|=DEC_Invalid_operation; /* out of range */ 3849 1.1 christos return 0; 3850 1.1 christos } 3851 1.1 christos return hi*BILLION+lo; 3852 1.1 christos } 3853 1.1 christos /* signed */ 3854 1.1 christos if (hi>2 || (hi==2 && lo>147483647)) { 3855 1.1 christos /* handle the usual edge case */ 3856 1.1 christos if (lo==147483648 && hi==2 && DFISSIGNED(&result)) return 0x80000000; 3857 1.1 christos set->status|=DEC_Invalid_operation; /* truly out of range */ 3858 1.1 christos return 0; 3859 1.1 christos } 3860 1.1 christos i=hi*BILLION+lo; 3861 1.1 christos if (DFISSIGNED(&result)) i=-i; 3862 1.1 christos return (uInt)i; 3863 1.1 christos } /* decToInt32 */ 3864 1.1 christos 3865 1.1 christos /* ------------------------------------------------------------------ */ 3866 1.1 christos /* decToIntegral -- local routine to effect ToIntegral value */ 3867 1.1 christos /* */ 3868 1.1 christos /* result gets the result */ 3869 1.1 christos /* df is the decFloat to round */ 3870 1.1 christos /* set is the context */ 3871 1.1 christos /* rmode is the rounding mode to use */ 3872 1.1 christos /* exact is 1 if Inexact should be signalled */ 3873 1.1 christos /* returns result */ 3874 1.1 christos /* ------------------------------------------------------------------ */ 3875 1.1 christos static decFloat * decToIntegral(decFloat *result, const decFloat *df, 3876 1.1 christos decContext *set, enum rounding rmode, 3877 1.1 christos Flag exact) { 3878 1.1 christos Int exp; /* exponent */ 3879 1.1 christos uInt sourhi; /* top word from source decFloat */ 3880 1.1 christos enum rounding saveround; /* saver */ 3881 1.1 christos uInt savestatus; /* .. */ 3882 1.1 christos decFloat zero; /* work */ 3883 1.1 christos 3884 1.1 christos /* Start decoding the argument */ 3885 1.1 christos sourhi=DFWORD(df, 0); /* top word */ 3886 1.1 christos exp=DECCOMBEXP[sourhi>>26]; /* get exponent high bits (in place) */ 3887 1.1 christos 3888 1.1 christos if (EXPISSPECIAL(exp)) { /* is special? */ 3889 1.1 christos /* NaNs are handled as usual */ 3890 1.1 christos if (DFISNAN(df)) return decNaNs(result, df, NULL, set); 3891 1.1 christos /* must be infinite; return canonical infinity with sign of df */ 3892 1.1 christos return decInfinity(result, df); 3893 1.1 christos } 3894 1.1 christos 3895 1.1 christos /* Here when the argument is finite */ 3896 1.1 christos /* complete extraction of the exponent */ 3897 1.1 christos exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ 3898 1.1 christos 3899 1.1 christos if (exp>=0) return decCanonical(result, df); /* already integral */ 3900 1.1 christos 3901 1.1 christos saveround=set->round; /* save rounding mode .. */ 3902 1.1 christos savestatus=set->status; /* .. and status */ 3903 1.1 christos set->round=rmode; /* set mode */ 3904 1.1 christos decFloatZero(&zero); /* make 0E+0 */ 3905 1.1 christos decFloatQuantize(result, df, &zero, set); /* 'integrate'; cannot fail */ 3906 1.1 christos set->round=saveround; /* restore rounding mode .. */ 3907 1.1 christos if (!exact) set->status=savestatus; /* .. and status, unless exact */ 3908 1.1 christos return result; 3909 1.1 christos } /* decToIntegral */ 3910