/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module */
/* ------------------------------------------------------------------ */
-/* Copyright (c) IBM Corporation, 2000-2010. All rights reserved. */
+/* Copyright (c) IBM Corporation, 2000-2012. All rights reserved. */
/* */
/* This software is made available under the terms of the */
/* ICU License -- ICU 1.8.1 and later. */
#include "cmemory.h" /* for uprv_malloc, etc., in ICU */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
+#include "uassert.h"
/* Constants */
/* Public lookup table used by the D2U macro */
-const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
+static const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
#define DECVERB 1 /* set to 1 for verbose DECCHECK */
#define powers DECPOWERS /* old internal name */
#define BIGEVEN (Int)0x80000002
#define BIGODD (Int)0x80000003
-static Unit uarrone[1]={1}; /* Unit array of 1, used for incrementing */
+static const Unit uarrone[1]={1}; /* Unit array of 1, used for incrementing */
+
+/* ------------------------------------------------------------------ */
+/* round-for-reround digits */
+/* ------------------------------------------------------------------ */
+static const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
+
+/* ------------------------------------------------------------------ */
+/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* ------------------------------------------------------------------ */
+static const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
+ 10000000, 100000000, 1000000000};
+
/* Granularity-dependent code */
#if DECDPUN<=4
/* fastpath in decLnOp. The final division is done to the requested */
/* precision. */
/* ------------------------------------------------------------------ */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
U_CAPI decNumber * U_EXPORT2 uprv_decNumberLog10(decNumber *res, const decNumber *rhs,
decContext *set) {
uInt status=0, ignore=0; /* status accumulators */
#endif
return res;
} /* decNumberLog10 */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic pop
+#endif
/* ------------------------------------------------------------------ */
/* decNumberMax -- compare two Numbers and return the maximum */
/* result setexp(approx, e div 2) % fix exponent */
/* end sqrt */
/* ------------------------------------------------------------------ */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
U_CAPI decNumber * U_EXPORT2 uprv_decNumberSquareRoot(decNumber *res, const decNumber *rhs,
decContext *set) {
decContext workset, approxset; /* work contexts */
#endif
return res;
} /* decNumberSquareRoot */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic pop
+#endif
/* ------------------------------------------------------------------ */
/* decNumberSubtract -- subtract two Numbers */
#endif
/* add [A+B*m] or subtract [A+B*(-m)] */
+ U_ASSERT(rhs->digits > 0);
+ U_ASSERT(lhs->digits > 0);
res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
rhs->lsu, D2U(rhs->digits),
rhsshift, acc, mult)
/* (rounded up to a multiple of 8 bytes), and the uLong */
/* accumulator starts offset the appropriate number of units */
/* to the right to avoid overwrite during the unchunking. */
+
+ /* Make sure no signed int overflow below. This is always true */
+ /* if the given numbers have less digits than DEC_MAX_DIGITS. */
+ U_ASSERT(iacc <= INT32_MAX/sizeof(uLong));
needbytes=iacc*sizeof(uLong);
#if DECDPUN==1
zoff=(iacc+7)/8; /* items to offset by */
/* where x is truncated (NB) into the range 10 through 99, */
/* and then c = k>>2 and e = k&3. */
/* ------------------------------------------------------------------ */
-const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208,
+static const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208,
6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
/* 5. The static buffers are larger than might be expected to allow */
/* for calls from decNumberPower. */
/* ------------------------------------------------------------------ */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
decNumber * decLnOp(decNumber *res, const decNumber *rhs,
decContext *set, uInt *status) {
uInt ignore=0; /* working status accumulator */
/* [status is handled by caller] */
return res;
} /* decLnOp */
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
+#pragma GCC diagnostic pop
+#endif
/* ------------------------------------------------------------------ */
/* decQuantizeOp -- force exponent to requested value */
/* If total ordering then handle differing signs 'up front' */
if (op==COMPTOTAL) { /* total ordering */
- if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) {
+ if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {
result=-1;
break;
}
- if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) {
+ if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {
result=+1;
break;
}
if (cut==0) quot=*up; /* is at bottom of unit */
else /* cut>0 */ { /* it's not at bottom of unit */
#if DECDPUN<=4
+ U_ASSERT(/* cut >= 0 &&*/ cut <= 4);
quot=QUOT10(*up, cut);
rem=*up-quot*powers[cut];
#else