diff --git a/icu4c/source/common/unicode/uconfig.h b/icu4c/source/common/unicode/uconfig.h index 878e346bb9e..8d222614add 100644 --- a/icu4c/source/common/unicode/uconfig.h +++ b/icu4c/source/common/unicode/uconfig.h @@ -385,19 +385,6 @@ # define UCONFIG_NO_SERVICE 0 #endif -/** - * \def UCONFIG_INTERNAL_DIGITLIST - * This switch turns on the fast but binary-incompatible Formattable class with an internal DigitList - * - * @internal - */ -#ifndef UCONFIG_INTERNAL_DIGITLIST -# define UCONFIG_INTERNAL_DIGITLIST 0 -#endif - - - - /** * \def UCONFIG_HAVE_PARSEALLINPUT * This switch turns on the "parse all input" attribute. Binary incompatible. @@ -405,7 +392,7 @@ * @internal */ #ifndef UCONFIG_HAVE_PARSEALLINPUT -# define UCONFIG_HAVE_PARSEALLINPUT 0 +# define UCONFIG_HAVE_PARSEALLINPUT 1 #endif @@ -416,7 +403,7 @@ * @internal */ #ifndef UCONFIG_FORMAT_FASTPATHS_49 -# define UCONFIG_FORMAT_FASTPATHS_49 0 +# define UCONFIG_FORMAT_FASTPATHS_49 1 #endif #endif diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index d3b1becc371..bd156918eba 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -187,9 +187,6 @@ U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { U_CDECL_END - -//#define FMT_DEBUG - #ifdef FMT_DEBUG #include static void _debugout(const char *f, int l, const UnicodeString& s) { @@ -1011,9 +1008,12 @@ void DecimalFormat::handleChanged() { data.fFastpathStatus = kFastpathNO; - if (fGroupingSize!=0) { - debug("No fastpath: fGroupingSize!=0"); // TODO: revisit, should handle ex. up to 999 if groupingsize is 3. - } else if(fGroupingSize2!=0) { + if (fGroupingSize!=0 && isGroupingUsed()) { + debug("No fastpath: fGroupingSize!=0 and grouping is used"); +#ifdef FMT_DEBUG + printf("groupingsize=%d\n", fGroupingSize); +#endif + } else if(fGroupingSize2!=0 && isGroupingUsed()) { debug("No fastpath: fGroupingSize2!=0"); } else if(fUseExponentialNotation) { debug("No fastpath: fUseExponentialNotation"); @@ -1109,7 +1109,7 @@ DecimalFormat::_format(int64_t number, // Slide the number to the start of the output str U_ASSERT(destIdx >= 0); int32_t length = MAX_IDX - destIdx -1; - int32_t prefixLen = appendAffix(appendTo, number, handler, number<0, TRUE); + /*int32_t prefixLen = */ appendAffix(appendTo, number, handler, number<0, TRUE); int32_t maxIntDig = getMaximumIntegerDigits(); int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits @@ -1129,7 +1129,7 @@ DecimalFormat::_format(int64_t number, destlength); handler.addAttribute(kIntegerField, intBegin, appendTo.length()); - int32_t suffixLen = appendAffix(appendTo, number, handler, number<0, FALSE); + /*int32_t suffixLen =*/ appendAffix(appendTo, number, handler, number<0, FALSE); //outputStr[length]=0; @@ -1869,11 +1869,7 @@ void DecimalFormat::parse(const UnicodeString& text, // status is used to record whether a number is infinite. UBool status[fgStatusLength]; -#if UCONFIG_INTERNAL_DIGITLIST DigitList *digits = result.getInternalDigitList(); // get one from the stack buffer -#else - DigitList *digits = new DigitList; -#endif if (digits == NULL) { return; // no way to report error from here. } @@ -1881,9 +1877,6 @@ void DecimalFormat::parse(const UnicodeString& text, if (fCurrencySignCount > fgCurrencySignCountZero) { if (!parseForCurrency(text, parsePosition, *digits, status, currency)) { -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif return; } } else { @@ -1894,9 +1887,6 @@ void DecimalFormat::parse(const UnicodeString& text, parsePosition, *digits, status, currency)) { debug("!subparse(...) - rewind"); parsePosition.setIndex(startIdx); -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif return; } } @@ -1905,9 +1895,6 @@ void DecimalFormat::parse(const UnicodeString& text, if (status[fgStatusInfinite]) { double inf = uprv_getInfinity(); result.setDouble(digits->isPositive() ? inf : -inf); -#if !UCONFIG_INTERNAL_DIGITLIST - delete digits; -#endif // TODO: set the dl to infinity, and let it fall into the code below. } @@ -2100,7 +2087,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, DBGAPPD(posPrefix); DBGAPPD(posSuffix); debugout(s); - printf("currencyParsing=%d, fFormatWidth=%d, text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, text.length(), negPrefix!=NULL?negPrefix->length():-1); + printf("currencyParsing=%d, fFormatWidth=%d, isParseIntegerOnly=%c text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, (isParseIntegerOnly())?'Y':'N', text.length(), negPrefix!=NULL?negPrefix->length():-1); #endif UBool fastParseOk = false; /* TRUE iff fast parse is OK */ @@ -2117,7 +2104,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, fFormatWidth==0 && // (negPrefix!=NULL&&negPrefix->isEmpty()) || text.length()>0 && - text.length()<20 && + text.length()<32 && (posPrefix==NULL||posPrefix->isEmpty()) && (posSuffix==NULL||posSuffix->isEmpty()) && // (negPrefix==NULL||negPrefix->isEmpty()) && @@ -2131,9 +2118,11 @@ UBool DecimalFormat::subparse(const UnicodeString& text, UChar32 ch = text.char32At(j); const UnicodeString *decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); UChar32 decimalChar = 0; + UBool intOnly = FALSE; int32_t decimalCount = decimalString->countChar32(0,3); if(isParseIntegerOnly()) { decimalChar = 0; // not allowed + intOnly = TRUE; } else if(decimalCount==1) { decimalChar = decimalString->char32At(0); } else if(decimalCount==0) { @@ -2165,6 +2154,8 @@ UBool DecimalFormat::subparse(const UnicodeString& text, parsedNum.append((char)('.'), err); decimalChar=0; // no more decimals. fastParseHadDecimal=TRUE; + } else if(intOnly && !u_isdigit(ch)) { + break; // hit a non-integer. (fall through if integer, to slow parse) } else { digitCount=-1; // fail break; @@ -2172,7 +2163,9 @@ UBool DecimalFormat::subparse(const UnicodeString& text, j+=U16_LENGTH(ch); ch = text.char32At(j); // for next } - if(j==l && (digitCount>0)) { + if( + ((j==l)||intOnly) + && (digitCount>0)) { #ifdef FMT_DEBUG printf("PP -> %d, good = [%s] digitcount=%d, fGroupingSize=%d fGroupingSize2=%d!\n", j, parsedNum.data(), digitCount, fGroupingSize, fGroupingSize2); #endif @@ -2194,6 +2187,15 @@ UBool DecimalFormat::subparse(const UnicodeString& text, #endif parsedNum.clear(); } + } else { +#ifdef FMT_DEBUG + printf("Could not fastpath parse. "); + printf("fFormatWidth=%d ", fFormatWidth); + printf("text.length()=%d ", text.length()); + printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix); + + printf("\n"); +#endif } if(!fastParseOk @@ -2587,7 +2589,13 @@ printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d return FALSE; } #endif - digits.set(parsedNum.toStringPiece(), err); + // uint32_t bits = (fastParseOk?kFastpathOk:0) | + // (fastParseHadDecimal?0:kNoDecimal); + //printf("FPOK=%d, FPHD=%d, bits=%08X\n", fastParseOk, fastParseHadDecimal, bits); + digits.set(parsedNum.toStringPiece(), + err, + 0//bits + ); if (U_FAILURE(err)) { #ifdef FMT_DEBUG diff --git a/icu4c/source/i18n/digitlst.cpp b/icu4c/source/i18n/digitlst.cpp index 39a30cf9378..592b228259f 100644 --- a/icu4c/source/i18n/digitlst.cpp +++ b/icu4c/source/i18n/digitlst.cpp @@ -732,29 +732,56 @@ DigitList::setInteger(int64_t source) * be acceptable for a public API. */ void -DigitList::set(const StringPiece &source, UErrorCode &status) { +DigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) { if (U_FAILURE(status)) { return; } - // Figure out a max number of digits to use during the conversion, and - // resize the number up if necessary. - int32_t numDigits = source.length(); - if (numDigits > fContext.digits) { +#if 0 + if(fastpathBits==(kFastpathOk|kNoDecimal)) { + int32_t size = source.size(); + const char *data = source.data(); + int64_t r = 0; + int64_t m = 1; + // fast parse + while(size>0) { + char ch = data[--size]; + if(ch=='+') { + break; + } else if(ch=='-') { + r = -r; + break; + } else { + int64_t d = ch-'0'; + //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m); + r+=(d)*m; + m *= 10; + } + } + //printf("R=%d\n", r); + set(r); + } else +#endif + { + // Figure out a max number of digits to use during the conversion, and + // resize the number up if necessary. + int32_t numDigits = source.length(); + if (numDigits > fContext.digits) { // fContext.digits == fStorage.getCapacity() decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity()); if (t == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; + status = U_MEMORY_ALLOCATION_ERROR; + return; } fDecNumber = t; fContext.digits = numDigits; - } + } - fContext.status = 0; - uprv_decNumberFromString(fDecNumber, source.data(), &fContext); - if ((fContext.status & DEC_Conversion_syntax) != 0) { + fContext.status = 0; + uprv_decNumberFromString(fDecNumber, source.data(), &fContext); + if ((fContext.status & DEC_Conversion_syntax) != 0) { status = U_DECIMAL_NUMBER_SYNTAX_ERROR; + } } internalClear(); } diff --git a/icu4c/source/i18n/digitlst.h b/icu4c/source/i18n/digitlst.h index 7234afed05e..aa29a14593c 100644 --- a/icu4c/source/i18n/digitlst.h +++ b/icu4c/source/i18n/digitlst.h @@ -68,6 +68,8 @@ template class U_I18N_API MaybeStackHeaderAndArraystackDecimalNum)) { delete fDecimalNum; } else { fDecimalNum->~DigitList(); // destruct, don't deallocate } -#else - delete fDecimalNum; -#endif fDecimalNum = NULL; } @@ -748,7 +744,6 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) { } -#if UCONFIG_INTERNAL_DIGITLIST DigitList * Formattable::getInternalDigitList() { FmtStackData *stackData = (FmtStackData*)fStackData; @@ -760,7 +755,6 @@ Formattable::getInternalDigitList() { } return fDecimalNum; } -#endif // --------------------------------------- void diff --git a/icu4c/source/i18n/unicode/fmtable.h b/icu4c/source/i18n/unicode/fmtable.h index 694e2793256..845122ed2db 100644 --- a/icu4c/source/i18n/unicode/fmtable.h +++ b/icu4c/source/i18n/unicode/fmtable.h @@ -605,13 +605,10 @@ public: */ DigitList *getDigitList() const { return fDecimalNum;} -#if UCONFIG_INTERNAL_DIGITLIST /** * @internal */ DigitList *getInternalDigitList(); -#endif - /** * Adopt, and set value from, a DigitList @@ -652,9 +649,7 @@ private: DigitList *fDecimalNum; -#if UCONFIG_INTERNAL_DIGITLIST char fStackData[128]; // must be big enough for DigitList -#endif Type fType; UnicodeString fBogus; // Bogus string when it's needed. diff --git a/icu4c/source/samples/date/Makefile.in b/icu4c/source/samples/date/Makefile.in index de16093589e..fd2d6282e98 100644 --- a/icu4c/source/samples/date/Makefile.in +++ b/icu4c/source/samples/date/Makefile.in @@ -1,5 +1,5 @@ ## Makefile.in for ICU - samples/date -## Copyright (c) 1999-2011, International Business Machines Corporation and +## Copyright (c) 1999-2012, International Business Machines Corporation and ## others. All Rights Reserved. ## Source directory information @@ -56,7 +56,7 @@ distclean-local: clean-local $(RMV) Makefile check-local: - -$(INVOKE) ./$(TARGET) + -$(INVOKE) ./$(TARGET) $(ICUDATE_OPTS) Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ diff --git a/icu4c/source/test/perf/howExpensiveIs/Makefile.in b/icu4c/source/test/perf/howExpensiveIs/Makefile.in index 190a0c2fdee..2daea675c24 100644 --- a/icu4c/source/test/perf/howExpensiveIs/Makefile.in +++ b/icu4c/source/test/perf/howExpensiveIs/Makefile.in @@ -1,5 +1,5 @@ ## Makefile.in for ICU - test/perf/howExpensiveIs -## Copyright (c) 2001-2011, International Business Machines Corporation and +## Copyright (c) 2001-2012, International Business Machines Corporation and ## others. All Rights Reserved. ## Source directory information diff --git a/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp index fcfd27b3f64..1d15e04a383 100644 --- a/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp +++ b/icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp @@ -5,11 +5,23 @@ ********************************************************************** */ #include +#include + #include "sieve.h" #include "unicode/utimer.h" #include "udbgutil.h" #include "unicode/ustring.h" #include "unicode/decimfmt.h" +#include "unicode/udat.h" + +#if U_PLATFORM_IMPLEMENTS_POSIX +#include + +static void usage(const char *prog) { + fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog); +} +#endif + void runTests(void); #ifndef ITERATIONS @@ -19,8 +31,24 @@ void runTests(void); FILE *out = NULL; UErrorCode setupStatus = U_ZERO_ERROR; +const char *outName = NULL; +int listmode = 0; +const char *testName = NULL; +const char *progname = NULL; +int errflg = 0; +int testhit = 0; -int main(int argc, const char* argv[]){ +int testMatch(const char *aName) { + if(testName==NULL) return 1; + int len = strlen(testName); + if(testName[len-1]=='*') { + return strncmp(testName,aName,len-1); + } else { + return strcmp(testName,aName); + } +} + +int main(int argc, char * const * argv){ #if U_DEBUG fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]); #endif @@ -32,20 +60,67 @@ int main(int argc, const char* argv[]){ } #endif +#if U_PLATFORM_IMPLEMENTS_POSIX + int c; + extern int optind; + extern char *optarg; + while((c=getopt(argc,argv,"lf:t:")) != EOF) { + switch(c) { + case 'f': + outName = optarg; + break; + case 'l': + listmode++; + break; + case 't': + testName = optarg; + break; + case '?': + errflg++; + } + if(errflg) { + usage(progname); + return 0; + } + } + /* for ( ; optind < argc; optind++) { ... argv[optind] } */ +#else if(argc==2) { - out=fopen(argv[1],"w"); + outName = argv[1]; + } else if(argc>2) { + fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]); + } +#endif + + if(listmode && outName != NULL ) { + fprintf(stderr, "Warning: no output when list mode\n"); + outName=NULL; + } + + if(outName != NULL) { + + + out=fopen(outName,"w"); if(out==NULL) { - fprintf(stderr,"Err: can't open %s for writing.\n", argv[1]); + fprintf(stderr,"Err: can't open %s for writing.\n", outName); return 1; + } else { + fprintf(stderr, "# writing results to %s\n", outName); } fprintf(out, "\n"); fprintf(out, "\n", U_ICU_VERSION); fprintf(out, "\n", U_COPYRIGHT_STRING); - } else if(argc>2) { - fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]); + } else { + fprintf(stderr, "# (no output)\n"); + } + + if(listmode && testName!=NULL) { + fprintf(stderr, "ERR: no -l mode when specific test with -t\n"); + usage(progname); return 1; } + runTests(); @@ -99,7 +174,8 @@ public: fflush(stderr); #endif } - *subTime = uprv_getMeanTime(times,ITERATIONS,marginOfError); + uint32_t iterations = ITERATIONS; + *subTime = uprv_getMeanTime(times,&iterations,marginOfError); return subIterations; } public: @@ -111,7 +187,16 @@ public: void runTestOn(HowExpensiveTest &t) { if(U_FAILURE(setupStatus)) return; // silently - fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName()); + const char *tn = t.getName(); + if(testName!=NULL && testMatch(tn)) return; // skipped. + if(listmode) { + fprintf(stderr, "%s:%d:\t%s\n", t.fFile, t.fLine, t.getName()); + testhit++; + return; + } else { + fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName()); + testhit++; + } double sieveTime = uprv_getSieveTime(NULL); double st; double me; @@ -132,7 +217,7 @@ void runTestOn(HowExpensiveTest &t) { if(out!=NULL) { fprintf(out, " \n", - t.getName(),stn,st,me,iter); + tn,stn,st,me,iter); fflush(out); } } @@ -260,6 +345,34 @@ public: #define DO_AttrNumTest(p,n,x,a,v) { AttrNumTest t(p,n,x,__FILE__,__LINE__,a,v); runTestOn(t); } + +class NOXNumTest : public NumTest +{ +private: + UNumberFormatAttribute fAttr; + int32_t fAttrValue; + char name2[100]; +protected: + virtual const char *getClassName() { + sprintf(name2,"NOXNumTest:%d=%d", fAttr,fAttrValue); + return name2; + } +public: + NOXNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE /*, UNumberFormatAttribute attr, int32_t newValue */) + : NumTest(pat,num,expect,FILE,LINE) /* , + fAttr(attr), + fAttrValue(newValue) */ + { + } + virtual UNumberFormat* initFmt() { + UNumberFormat *fmt = NumTest::initFmt(); + //unum_setAttribute(fmt, fAttr,fAttrValue); + return fmt; + } +}; + +#define DO_NOXNumTest(p,n,x) { NOXNumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } + #define DO_TripleNumTest(p,n,x) DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_YES) \ DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_NO) \ DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE) @@ -485,7 +598,7 @@ public: int32_t run() { int32_t trial; - int i; + int i=0; UnicodeString buf; if(U_SUCCESS(setupStatus)) { for(i=0;i + +QuickTest(RandomTest,{},{timespec ts; ts.tv_sec=rand()%4; int j=U_LOTS_OF_TIMES;while(--j) { ts.tv_nsec=100000+(rand()%10000)*1000000; nanosleep(&ts,NULL); return j;} return U_LOTS_OF_TIMES;},{}) +#endif + OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,"en_US",0,&setupStatus),{}) OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,"en_US",0,&setupStatus),{}) #if !UCONFIG_NO_CONVERSION @@ -533,11 +677,24 @@ void runTests() { SieveTest t; runTestOn(t); } +#if 0 + { + RandomTest t; + runTestOn(t); + } +#endif { NullTest t; runTestOn(t); } +#ifndef SKIP_DATEFMT_TESTS + { + DateFormatTestBasic t; + runTestOn(t); + } +#endif + #ifndef SKIP_NUMPARSE_TESTS { // parse tests @@ -548,8 +705,8 @@ void runTests() { DO_NumTest("#","-2 ",-2); DO_NumTest("+#","+2",2); DO_NumTest("#,###.0","2222.0",2222.0); - DO_NumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0); + DO_NumTest("#","123456",123456); // attr #ifdef HAVE_UNUM_MAYBE @@ -567,7 +724,6 @@ void runTests() { } #endif - #ifndef SKIP_NUMFORMAT_TESTS // format tests { @@ -587,7 +743,6 @@ void runTests() { DO_NumFmtStringPieceTest("#.0000","123.4560",spPI); DO_NumFmtStringPieceTest("#.00","123.46",spPI); -#if 1 DO_NumFmtTest("#","0",0.0); DO_NumFmtTest("#","12345",12345); DO_NumFmtTest("#","-2",-2); @@ -600,24 +755,31 @@ void runTests() { DO_NumFmtInt64Test("#","-2",-2); DO_NumFmtInt64Test("+#","+2",2); } -#endif +#ifndef SKIP_NUM_OPEN_TEST { Test_unum_opendefault t; runTestOn(t); } + { + Test_unum_openpattern t; + runTestOn(t); + } +#endif + +#endif /* skip numformat tests */ #if !UCONFIG_NO_CONVERSION { Test_ucnv_opengb18030 t; runTestOn(t); } #endif - { - Test_unum_openpattern t; - runTestOn(t); - } { Test_ures_openroot t; runTestOn(t); } + + if(testhit==0) { + fprintf(stderr, "ERROR: no tests matched.\n"); + } } diff --git a/icu4c/source/test/perf/howExpensiveIs/sieve.cpp b/icu4c/source/test/perf/howExpensiveIs/sieve.cpp index ce626d7e7e4..0db512181ba 100644 --- a/icu4c/source/test/perf/howExpensiveIs/sieve.cpp +++ b/icu4c/source/test/perf/howExpensiveIs/sieve.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (c) 2011,International Business Machines + * Copyright (c) 2011-2012,International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -108,9 +108,9 @@ double qs(double *times, int n, double *q1, double *q2, double *q3) { return *q3-*q1; } -U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *marginOfError) { +U_CAPI double uprv_getMeanTime(double *times, uint32_t *timeCount, double *marginOfError) { double q1,q2,q3; - int n = timeCount; + int n = *timeCount; /* calculate medians */ qsort(times,n,sizeof(times[0]),comdoub); @@ -126,18 +126,23 @@ U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *margin for(int i=0;irangeMax) { #if U_DEBUG - printf("Knocking out: %.9f from [%.9f:%.9f]\n", times[i], rangeMin, rangeMax); + printf("Removing outlier: %.9f outside [%.9f:%.9f]\n", times[i], rangeMin, rangeMax); #endif times[i--] = times[--newN]; // bring down a new value } } +#if U_DEBUG + UBool didRemove = false; +#endif /* if we removed any outliers, recalculate iqr */ if(newN