MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decUnitCompare

Function decUnitCompare

extern/decNumber/decNumber.c:6231–6286  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decUnitCompare -- compare two >=0 integers in Unit arrays */ / This routine compares A ? B*10**E where A and B are unit arrays */ A is a plain integer */ B has an exponent of E (which must be non-negative) */ / Arg1 is A first Unit (lsu)

Source from the content-addressed store, hash-verified

6229/* only occur if E!=0) */
6230/* ------------------------------------------------------------------ */
6231static Int decUnitCompare(const Unit *a, Int alength,
6232 const Unit *b, Int blength, Int exp) {
6233 Unit *acc; // accumulator for result
6234 Unit accbuff[SD2U(DECBUFFER*2+1)]; // local buffer
6235 Unit *allocacc=NULL; // -> allocated acc buffer, iff allocated
6236 Int accunits, need; // units in use or needed for acc
6237 const Unit *l, *r, *u; // work
6238 Int expunits, exprem, result; // ..
6239
6240 if (exp==0) { // aligned; fastpath
6241 if (alength>blength) return 1;
6242 if (alength<blength) return -1;
6243 // same number of units in both -- need unit-by-unit compare
6244 l=a+alength-1;
6245 r=b+alength-1;
6246 for (;l>=a; l--, r--) {
6247 if (*l>*r) return 1;
6248 if (*l<*r) return -1;
6249 }
6250 return 0; // all units match
6251 } // aligned
6252
6253 // Unaligned. If one is >1 unit longer than the other, padded
6254 // approximately, then can return easily
6255 if (alength>blength+(Int)D2U(exp)) return 1;
6256 if (alength+1<blength+(Int)D2U(exp)) return -1;
6257
6258 // Need to do a real subtract. For this, a result buffer is needed
6259 // even though only the sign is of interest. Its length needs
6260 // to be the larger of alength and padded blength, +2
6261 need=blength+D2U(exp); // maximum real length of B
6262 if (need<alength) need=alength;
6263 need+=2;
6264 acc=accbuff; // assume use local buffer
6265 if (need*sizeof(Unit)>sizeof(accbuff)) {
6266 allocacc=(Unit *)malloc(need*sizeof(Unit));
6267 if (allocacc==NULL) return BADINT; // hopeless -- abandon
6268 acc=allocacc;
6269 }
6270 // Calculate units and remainder from exponent.
6271 expunits=exp/DECDPUN;
6272 exprem=exp%DECDPUN;
6273 // subtract [A+B*(-m)]
6274 accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
6275 -(Int)powers[exprem]);
6276 // [UnitAddSub result may have leading zeros, even on zero]
6277 if (accunits<0) result=-1; // negative result
6278 else { // non-negative result
6279 // check units of the result before freeing any storage
6280 for (u=acc; u<acc+accunits-1 && *u==0;) u++;
6281 result=(*u==0 ? 0 : +1);
6282 }
6283 // clean up and return the result
6284 if (allocacc!=NULL) free(allocacc); // drop any storage used
6285 return result;
6286 } // decUnitCompare
6287
6288/* ------------------------------------------------------------------ */

Callers 3

decNumber.cFile · 0.85
decCompareOpFunction · 0.85
decCompareFunction · 0.85

Calls 1

decUnitAddSubFunction · 0.85

Tested by

no test coverage detected