------------------------------------------------------------------ */ decNumberLog10 -- logarithm in base 10 */ / This computes C = log10(A) */ / res is C, the result. C may be A */ rhs is A */ set is the context; note that rounding mode has no e
| 1382 | /* precision. */ |
| 1383 | /* ------------------------------------------------------------------ */ |
| 1384 | decNumber * decNumberLog10(decNumber *res, const decNumber *rhs, |
| 1385 | decContext *set) { |
| 1386 | uInt status=0, ignore=0; // status accumulators |
| 1387 | uInt needbytes; // for space calculations |
| 1388 | Int p; // working precision |
| 1389 | Int t; // digits in exponent of A |
| 1390 | |
| 1391 | // buffers for a and b working decimals |
| 1392 | // (adjustment calculator, same size) |
| 1393 | decNumber bufa[D2N(DECBUFFER+2)]; |
| 1394 | decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated |
| 1395 | decNumber *a=bufa; // temporary a |
| 1396 | decNumber bufb[D2N(DECBUFFER+2)]; |
| 1397 | decNumber *allocbufb=NULL; // -> allocated bufb, iff allocated |
| 1398 | decNumber *b=bufb; // temporary b |
| 1399 | decNumber bufw[D2N(10)]; // working 2-10 digit number |
| 1400 | decNumber *w=bufw; // .. |
| 1401 | #if DECSUBSET |
| 1402 | decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated |
| 1403 | #endif |
| 1404 | |
| 1405 | decContext aset; // working context |
| 1406 | |
| 1407 | #if DECCHECK |
| 1408 | if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; |
| 1409 | #endif |
| 1410 | |
| 1411 | // Check restrictions; this is a math function; if not violated |
| 1412 | // then carry out the operation. |
| 1413 | if (!decCheckMath(rhs, set, &status)) do { // protect malloc |
| 1414 | #if DECSUBSET |
| 1415 | if (!set->extended) { |
| 1416 | // reduce operand and set lostDigits status, as needed |
| 1417 | if (rhs->digits>set->digits) { |
| 1418 | allocrhs=decRoundOperand(rhs, set, &status); |
| 1419 | if (allocrhs==NULL) break; |
| 1420 | rhs=allocrhs; |
| 1421 | } |
| 1422 | // special check in subset for rhs=0 |
| 1423 | if (ISZERO(rhs)) { // +/- zeros -> error |
| 1424 | status|=DEC_Invalid_operation; |
| 1425 | break;} |
| 1426 | } // extended=0 |
| 1427 | #endif |
| 1428 | |
| 1429 | decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context |
| 1430 | |
| 1431 | // handle exact powers of 10; only check if +ve finite |
| 1432 | if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) { |
| 1433 | Int residue=0; // (no residue) |
| 1434 | uInt copystat=0; // clean status |
| 1435 | |
| 1436 | // round to a single digit... |
| 1437 | aset.digits=1; |
| 1438 | decCopyFit(w, rhs, &aset, &residue, ©stat); // copy & shorten |
| 1439 | // if exact and the digit is 1, rhs is a power of 10 |
| 1440 | if (!(copystat&DEC_Inexact) && w->lsu[0]==1) { |
| 1441 | // the exponent, conveniently, is the power of 10; making |
no test coverage detected