bool isZero() const;
+ void toString(ByteSink& output, UErrorCode& status) const;
+
inline const decNumber* getRawDecNumber() const {
return fData.getAlias();
}
#include "number_utypes.h"
#include "util.h"
#include "number_decimalquantity.h"
+#include "number_decnum.h"
U_NAMESPACE_BEGIN
namespace number {
getAllFieldPositionsImpl(fpih, status);
}
+void FormattedNumber::toDecimalNumber(ByteSink& sink, UErrorCode& status) const {
+ UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
+ impl::DecNum decnum;
+ fData->quantity.toDecNum(decnum, status);
+ decnum.toString(sink, status);
+}
+
void FormattedNumber::getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih,
UErrorCode& status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
return decNumberIsZero(fData.getAlias());
}
+void DecNum::toString(ByteSink& output, UErrorCode& status) const {
+ if (U_FAILURE(status)) {
+ return;
+ }
+ // "string must be at least dn->digits+14 characters long"
+ int32_t minCapacity = fData.getAlias()->digits + 14;
+ MaybeStackArray<char, 30> buffer(minCapacity);
+ uprv_decNumberToString(fData, buffer.getAlias());
+ output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias())));
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
#if !UCONFIG_NO_FORMATTING
#include "unicode/appendable.h"
-#include "unicode/dcfmtsym.h"
+#include "unicode/bytestream.h"
#include "unicode/currunit.h"
+#include "unicode/dcfmtsym.h"
#include "unicode/fieldpos.h"
#include "unicode/formattedvalue.h"
#include "unicode/fpositer.h"
*/
void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const;
+ /**
+ * Export the formatted number as a "numeric string" conforming to the
+ * syntax defined in the Decimal Arithmetic Specification, available at
+ * http://speleotrove.com/decimal
+ *
+ * This endpoint is useful for obtaining the exact number being printed
+ * after scaling and rounding have been applied by the number formatter.
+ *
+ * Example call site:
+ *
+ * auto decimalNumber = fn.toDecimalNumber<std::string>(status);
+ *
+ * @tparam StringClass A string class compatible with StringByteSink;
+ * for example, std::string.
+ * @param status Set if an error occurs.
+ * @return A StringClass containing the numeric string.
+ * @draft ICU 65
+ */
+ template<typename StringClass>
+ inline StringClass toDecimalNumber(UErrorCode& status) const;
+
#ifndef U_HIDE_INTERNAL_API
/**
explicit FormattedNumber(UErrorCode errorCode)
: fData(nullptr), fErrorCode(errorCode) {}
+ // TODO(ICU-20775): Propose this as API.
+ void toDecimalNumber(ByteSink& sink, UErrorCode& status) const;
+
// To give LocalizedNumberFormatter format methods access to this class's constructor:
friend class LocalizedNumberFormatter;
friend struct impl::UFormattedNumberImpl;
};
+#ifndef U_HIDE_DRAFT_API
+template<typename StringClass>
+StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const {
+ StringClass result;
+ StringByteSink<StringClass> sink(&result);
+ toDecimalNumber(sink, status);
+ return result;
+};
+#endif // U_HIDE_DRAFT_API
+
/**
* See the main description in numberformatter.h for documentation and examples.
*
UErrorCode* ec);
+// TODO(ICU-20775): Propose this as API.
+// NOTE: This is not currently implemented.
+// U_DRAFT int32_t U_EXPORT2
+// unumf_resultToDecimalNumber(const UFormattedNumber* uresult, char* buffer, int32_t bufferCapacity,
+// UErrorCode* ec);
+
+
/**
* Releases the UNumberFormatter created by unumf_openForSkeletonAndLocale().
*
void copyMove();
void localPointerCAPI();
void toObject();
+ void toDecimalNumber();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
TESTCASE_AUTO(copyMove);
TESTCASE_AUTO(localPointerCAPI);
TESTCASE_AUTO(toObject);
+ TESTCASE_AUTO(toDecimalNumber);
TESTCASE_AUTO_END;
}
}
}
+void NumberFormatterApiTest::toDecimalNumber() {
+ IcuTestErrorCode status(*this, "toDecimalNumber");
+ FormattedNumber fn = NumberFormatter::withLocale("bn-BD")
+ .scale(Scale::powerOfTen(2))
+ .precision(Precision::maxSignificantDigits(5))
+ .formatDouble(9.87654321e12, status);
+ assertEquals("Should have expected localized string result",
+ u"৯৮,৭৬,৫০,০০,০০,০০,০০০", fn.toString(status));
+ assertEquals(u"Should have expected toDecimalNumber string result",
+ "9.8765E+14", fn.toDecimalNumber<std::string>(status).c_str());
+}
+
void NumberFormatterApiTest::assertFormatDescending(const char16_t* umessage, const char16_t* uskeleton,
const UnlocalizedNumberFormatter& f, Locale locale,