// Call the slow oracle function (Double.toString in Java, sprintf in C++).
// The <float.h> constant DBL_DIG defines a platform-specific number of digits in a double.
- // However, this tends to be too low (see #11318). Instead, we always use 14 digits.
- char dstr[14 + 8]; // Extra space for '+', '.', e+NNN, and '\0'
- sprintf(dstr, "%+1.14e", n);
+ // However, this tends to be too low (see #11318). Instead, we always use 14 decimal places.
+ static constexpr size_t CAP = 1 + 14 + 8; // Extra space for '+', '.', e+NNN, and '\0'
+ char dstr[CAP];
+ snprintf(dstr, CAP, "%+1.14e", n);
// uprv_decNumberFromString() will parse the string expecting '.' as a
// decimal separator, however sprintf() can use ',' in certain locales.
}
decNumber dn;
- stringToDecNumber(dstr, dn);
+ StringPiece sp(dstr);
+ stringToDecNumber(sp, dn);
_setToDecNumber(&dn);
scale += delta;
return buffer;
}
+UnicodeString
+DoubleToUnicodeString(double num)
+{
+ char buffer[64]; // nos changed from 10 to 64
+ char danger = 'p'; // guard against overrunning the buffer (rtg)
+
+ sprintf(buffer, "%1.14e", num);
+ assert(danger == 'p');
+
+ return buffer;
+}
+
// [LIU] Just to get things working
UnicodeString
operator+(const UnicodeString& left,
//string-concatenation operator (moved from findword test by rtg)
UnicodeString UCharToUnicodeString(UChar c);
UnicodeString Int64ToUnicodeString(int64_t num);
+UnicodeString DoubleToUnicodeString(double num);
//UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type.
UnicodeString operator+(const UnicodeString& left, long num);
UnicodeString operator+(const UnicodeString& left, unsigned long num);
void sign();
void decimal();
void locale();
+ void formatTypes();
void errors();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
private:
- void assertDoubleEquals(const char *message, double a, double b);
+ void assertDoubleEquals(UnicodeString message, double a, double b);
void assertHealth(const DecimalQuantity &fq);
void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected);
void checkDoubleBehavior(double d, bool explicitRequired);
TESTCASE_AUTO(sign);
TESTCASE_AUTO(decimal);
TESTCASE_AUTO(locale);
+ TESTCASE_AUTO(formatTypes);
TESTCASE_AUTO(errors);
TESTCASE_AUTO_END;
}
assertEquals("Locale withLocale()", u"1 234", actual);
}
+void NumberFormatterApiTest::formatTypes() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalizedNumberFormatter formatter = NumberFormatter::withLocale(Locale::getEnglish());
+ const char* str1 = "98765432123456789E1";
+ UnicodeString actual = formatter.formatDecimal(str1, status).toString();
+ assertEquals("Format decNumber", u"987,654,321,234,567,890", actual);
+}
+
void NumberFormatterApiTest::errors() {
LocalizedNumberFormatter lnf = NumberFormatter::withLocale(Locale::getEnglish()).rounding(
Rounder::fixedFraction(
TESTCASE_AUTO_END;
}
-void DecimalQuantityTest::assertDoubleEquals(const char *message, double a, double b) {
+void DecimalQuantityTest::assertDoubleEquals(UnicodeString message, double a, double b) {
if (a == b) {
return;
}
diff = diff < 0 ? -diff : diff;
double bound = a < 0 ? -a * 1e-6 : a * 1e-6;
if (diff > bound) {
- errln(message);
+ errln(message + u": " + DoubleToUnicodeString(a) + u" vs " + DoubleToUnicodeString(b) + u" differ by " + DoubleToUnicodeString(diff));
}
}
if (explicitRequired) {
assertTrue("Should be using approximate double", !fq.isExplicitExactDouble());
}
- assertDoubleEquals("Initial construction from hard double", d, fq.toDouble());
+ UnicodeString baseStr = fq.toString();
+ assertDoubleEquals(
+ UnicodeString(u"Initial construction from hard double: ") + baseStr,
+ d, fq.toDouble());
fq.roundToInfinity();
+ UnicodeString newStr = fq.toString();
if (explicitRequired) {
assertTrue("Should not be using approximate double", fq.isExplicitExactDouble());
}
- assertDoubleEquals("After conversion to exact BCD (double)", d, fq.toDouble());
+ assertDoubleEquals(
+ UnicodeString(u"After conversion to exact BCD (double): ") + baseStr + u" vs " + newStr,
+ d, fq.toDouble());
}
void DecimalQuantityTest::testDecimalQuantityBehaviorStandalone() {
checkDoubleBehavior(d, false);
}
- assertDoubleEquals("NaN check failed", NAN, DecimalQuantity().setToDouble(NAN).toDouble());
+ assertDoubleEquals(u"NaN check failed", NAN, DecimalQuantity().setToDouble(NAN).toDouble());
assertDoubleEquals(
- "Inf check failed", INFINITY, DecimalQuantity().setToDouble(INFINITY).toDouble());
+ u"Inf check failed", INFINITY, DecimalQuantity().setToDouble(INFINITY).toDouble());
assertDoubleEquals(
- "-Inf check failed", -INFINITY, DecimalQuantity().setToDouble(-INFINITY).toDouble());
+ u"-Inf check failed", -INFINITY, DecimalQuantity().setToDouble(-INFINITY).toDouble());
// Generate random doubles
for (int32_t i = 0; i < 10000; i++) {