// Return a random double from 0.01 to 1, inclusive double IntlTestDateFormat::randDouble() { // Assume 8-bit (or larger) rand values. Also assume // that the system rand() function is very poor, which it always is. double d=0.0; uint32_t i; char* poke = (char*)&d; do { do { for (i=0; i < sizeof(double); ++i) { poke[i] = (char)(rand() & 0xFF); } } while (uprv_isNaN(d) || uprv_isInfinite(d)); if (d < 0.0) d = -d; if (d > 0.0) { double e = uprv_floor(log10(d)); if (e < -2.0) d *= uprv_pow10((int32_t)(-e-2)); else if (e > -1.0) d /= uprv_pow10((int32_t)(e+1)); } // While this is not a real normalized number make another one. } while (uprv_isNaN(d) || uprv_isInfinite(d) || !((-DBL_MAX < d && d < DBL_MAX) || (d < -DBL_MIN && DBL_MIN < d))); return d; }
void PUtilTest::maxMinTest(double a, double b, double exp, UBool max) { double result = 0.0; if(max) result = uprv_fmax(a, b); else result = uprv_fmin(a, b); UBool nanResultOK = (uprv_isNaN(a) || uprv_isNaN(b)); if(uprv_isNaN(result) && ! nanResultOK) { errln(UnicodeString("FAIL: got NaN as result without NaN as argument")); if(max) errln(UnicodeString(" max(") + a + ", " + b + ") is " + result + ", expected " + exp); else errln(UnicodeString(" min(") + a + ", " + b + ") is " + result + ", expected " + exp); } else if(result != exp && ! (uprv_isNaN(result) || uprv_isNaN(exp))) if(max) errln(UnicodeString("FAIL: max(") + a + ", " + b + ") is " + result + ", expected " + exp); else errln(UnicodeString("FAIL: min(") + a + ", " + b + ") is " + result + ", expected " + exp); else { if (verbose) { if(max) logln(UnicodeString("OK: max(") + a + ", " + b + ") is " + result); else logln(UnicodeString("OK: min(") + a + ", " + b + ") is " + result); } } }
static UBool compareWithNAN(double x, double y) { if( uprv_isNaN(x) || uprv_isNaN(y) ) { if(!uprv_isNaN(x) || !uprv_isNaN(y) ) { return FALSE; } } else if (y != x) { /* no NaN's involved */ return FALSE; } return TRUE; }
void PUtilTest::remainderTest(double x, double y, double exp) { double result = uprv_IEEEremainder(x,y); if( uprv_isNaN(result) && ! ( uprv_isNaN(x) || uprv_isNaN(y))) { errln(UnicodeString("FAIL: got NaN as result without NaN as argument")); errln(UnicodeString(" IEEEremainder(") + x + ", " + y + ") is " + result + ", expected " + exp); } else if(result != exp) errln(UnicodeString("FAIL: IEEEremainder(") + x + ", " + y + ") is " + result + ", expected " + exp); else logln(UnicodeString("OK: IEEEremainder(") + x + ", " + y + ") is " + result); }
int64_t util64_fromDouble(double d) { int64_t result = 0; if (!uprv_isNaN(d)) { double mant = uprv_maxMantissa(); if (d < -mant) { d = -mant; } else if (d > mant) { d = mant; } UBool neg = d < 0; if (neg) { d = -d; } result = (int64_t)uprv_floor(d); if (neg) { result = -result; } } return result; }
static void remainderTest(double x, double y, double exp) { double result = uprv_IEEEremainder(x,y); if( uprv_isNaN(result) && ! ( uprv_isNaN(x) || uprv_isNaN(y))) { log_err("FAIL: got NaN as result without NaN as argument"); log_err(" IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp); } else if(!compareWithNAN(result, exp)) { log_err("FAIL: IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp); } else{ log_verbose("OK: IEEEremainder(%f, %f) is %f\n", x, y, result); } }
const NFRule* NFRuleSet::findDoubleRule(double number) const { // if this is a fraction rule set, use findFractionRuleSetRule() if (isFractionRuleSet()) { return findFractionRuleSetRule(number); } if (uprv_isNaN(number)) { const NFRule *rule = nonNumericalRules[NAN_RULE_INDEX]; if (!rule) { rule = owner->getDefaultNaNRule(); } return rule; } // if the number is negative, return the negative number rule // (if there isn't a negative-number rule, we pretend it's a // positive number) if (number < 0) { if (nonNumericalRules[NEGATIVE_RULE_INDEX]) { return nonNumericalRules[NEGATIVE_RULE_INDEX]; } else { number = -number; } } if (uprv_isInfinite(number)) { const NFRule *rule = nonNumericalRules[INFINITY_RULE_INDEX]; if (!rule) { rule = owner->getDefaultInfinityRule(); } return rule; } // if the number isn't an integer, we use one of the fraction rules... if (number != uprv_floor(number)) { // if the number is between 0 and 1, return the proper // fraction rule if (number < 1 && nonNumericalRules[PROPER_FRACTION_RULE_INDEX]) { return nonNumericalRules[PROPER_FRACTION_RULE_INDEX]; } // otherwise, return the improper fraction rule else if (nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]) { return nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]; } } // if there's a master rule, use it to format the number if (nonNumericalRules[MASTER_RULE_INDEX]) { return nonNumericalRules[MASTER_RULE_INDEX]; } // and if we haven't yet returned a rule, use findNormalRule() // to find the applicable rule int64_t r = util64_fromDouble(number + 0.5); return findNormalRule(r); }
VisibleDigits & FixedPrecision::initVisibleDigits( double value, VisibleDigits &digits, UErrorCode &status) const { if (U_FAILURE(status)) { return digits; } digits.clear(); if (uprv_isNaN(value)) { digits.setNaN(); return digits; } if (uprv_isPositiveInfinity(value)) { digits.setInfinite(); return digits; } if (uprv_isNegativeInfinity(value)) { digits.setInfinite(); digits.setNegative(); return digits; } if (!fRoundingIncrement.isZero()) { // If we have round increment, use digit list. DigitList digitList; digitList.set(value); return initVisibleDigits(digitList, digits, status); } // Try to find n such that value * 10^n is an integer int32_t n = -1; double scaled; for (int32_t i = 0; i < UPRV_LENGTHOF(gPower10); ++i) { scaled = value * gPower10[i]; if (scaled > MAX_INT64_IN_DOUBLE || scaled < -MAX_INT64_IN_DOUBLE) { break; } if (scaled == floor(scaled)) { n = i; break; } } // Try fast path if (n >= 0 && initVisibleDigits(scaled, -n, digits, status)) { digits.fAbsDoubleValue = fabs(value); digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits(); // Adjust for negative 0 becuase when we cast to an int64, // negative 0 becomes positive 0. if (scaled == 0.0 && uprv_isNegative(scaled)) { digits.setNegative(); } return digits; } // Oops have to use digit list DigitList digitList; digitList.set(value); return initVisibleDigits(digitList, digits, status); }
U_CAPI double U_EXPORT2 uprv_fmin(double x, double y) { #if IEEE_754 int32_t lowBits; /* first handle NaN*/ if(uprv_isNaN(x) || uprv_isNaN(y)) return uprv_getNaN(); /* check for -0 and 0*/ lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&y, sizeof(uint32_t)); if(x == 0.0 && y == 0.0 && (lowBits & SIGN)) return y; #endif /* this should work for all flt point w/o NaN and Inf special cases */ return (x > y ? y : x); }
void PUtilTest::testIsNaN(void) { double pinf = uprv_getInfinity(); double ninf = -uprv_getInfinity(); double nan = uprv_getNaN(); double ten = 10.0; if(uprv_isNaN(nan) == FALSE) { errln("FAIL: isNaN() returned FALSE for NaN."); } if(uprv_isNaN(pinf) == TRUE) { errln("FAIL: isNaN() returned TRUE for +Infinity."); } if(uprv_isNaN(ninf) == TRUE) { errln("FAIL: isNaN() returned TRUE for -Infinity."); } if(uprv_isNaN(ten) == TRUE) { errln("FAIL: isNaN() returned TRUE for 10.0."); } }
UnicodeString& RuleBasedNumberFormat::format(double number, UnicodeString& toAppendTo, FieldPosition& /* pos */) const { // Special case for NaN; adapted from what DecimalFormat::_format( double number,...) does. if (uprv_isNaN(number)) { DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBasedNumberFormat internal if (decFmtSyms) { toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNSymbol); } } else if (defaultRuleSet) { defaultRuleSet->format(number, toAppendTo, toAppendTo.length()); } return toAppendTo; }
void MessageFormatRegressionTest::Test4052223() { ParsePosition pos(0); if (pos.getErrorIndex() != -1) { errln("ParsePosition.getErrorIndex initialization failed."); } UErrorCode status = U_ZERO_ERROR; MessageFormat *fmt = new MessageFormat("There are {0} apples growing on the {1} tree.", status); failure(status, "new MessageFormat"); UnicodeString str("There is one apple growing on the peach tree."); int32_t count = 0; fmt->parse(str, pos, count); logln(UnicodeString("unparsable string , should fail at ") + pos.getErrorIndex()); if (pos.getErrorIndex() == -1) errln("Bug 4052223 failed : parsing string " + str); pos.setErrorIndex(4); if (pos.getErrorIndex() != 4) errln(UnicodeString("setErrorIndex failed, got ") + pos.getErrorIndex() + " instead of 4"); ChoiceFormat *f = new ChoiceFormat( "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.", status); failure(status, "new ChoiceFormat"); pos.setIndex(0); pos.setErrorIndex(-1); Formattable obj; f->parse("are negative", obj, pos); if (pos.getErrorIndex() != -1 && obj.getDouble() == -1.0) errln(UnicodeString("Parse with \"are negative\" failed, at ") + pos.getErrorIndex()); pos.setIndex(0); pos.setErrorIndex(-1); f->parse("are no or fraction ", obj, pos); if (pos.getErrorIndex() != -1 && obj.getDouble() == 0.0) errln(UnicodeString("Parse with \"are no or fraction\" failed, at ") + pos.getErrorIndex()); pos.setIndex(0); pos.setErrorIndex(-1); f->parse("go postal", obj, pos); if (pos.getErrorIndex() == -1 && ! uprv_isNaN(obj.getDouble())) errln(UnicodeString("Parse with \"go postal\" failed, at ") + pos.getErrorIndex()); delete fmt; delete f; }
double IntlTestNumberFormat::randDouble() { // Assume 8-bit (or larger) rand values. Also assume // that the system rand() function is very poor, which it always is. // Call srand(currentTime) in intltest to make it truly random. double d; uint32_t i; char* poke = (char*)&d; do { for (i=0; i < sizeof(double); ++i) { poke[i] = (char)(rand() & 0xFF); } } while (uprv_isNaN(d) || uprv_isInfinite(d) || !((-DBL_MAX < d && d < DBL_MAX) || (d < -DBL_MIN && DBL_MIN < d))); return d; }
/** * Truncates the given double. * trunc(3.3) = 3.0, trunc (-3.3) = -3.0 * This is different than calling floor() or ceil(): * floor(3.3) = 3, floor(-3.3) = -4 * ceil(3.3) = 4, ceil(-3.3) = -3 */ U_CAPI double U_EXPORT2 uprv_trunc(double d) { #if IEEE_754 int32_t lowBits; /* handle error cases*/ if(uprv_isNaN(d)) return uprv_getNaN(); if(uprv_isInfinite(d)) return uprv_getInfinity(); lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&d, sizeof(uint32_t)); if( (d == 0.0 && (lowBits & SIGN)) || d < 0) return ceil(d); else return floor(d); #else return d >= 0 ? floor(d) : ceil(d); #endif }