ICU-20562 Adding toDecimalNumber method to C++ FormattedNumber.
diff --git a/icu4c/source/i18n/number_decnum.h b/icu4c/source/i18n/number_decnum.h
index a779347..0c7399d 100644
--- a/icu4c/source/i18n/number_decnum.h
+++ b/icu4c/source/i18n/number_decnum.h
@@ -55,6 +55,8 @@
 
     bool isZero() const;
 
+    void toString(ByteSink& output, UErrorCode& status) const;
+
     inline const decNumber* getRawDecNumber() const {
         return fData.getAlias();
     }
diff --git a/icu4c/source/i18n/number_output.cpp b/icu4c/source/i18n/number_output.cpp
index 8804916..e2f0691 100644
--- a/icu4c/source/i18n/number_output.cpp
+++ b/icu4c/source/i18n/number_output.cpp
@@ -9,6 +9,7 @@
 #include "number_utypes.h"
 #include "util.h"
 #include "number_decimalquantity.h"
+#include "number_decnum.h"
 
 U_NAMESPACE_BEGIN
 namespace number {
@@ -28,6 +29,13 @@
     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)
diff --git a/icu4c/source/i18n/number_utils.cpp b/icu4c/source/i18n/number_utils.cpp
index 0983b7b..91d7f33 100644
--- a/icu4c/source/i18n/number_utils.cpp
+++ b/icu4c/source/i18n/number_utils.cpp
@@ -252,4 +252,15 @@
     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 */
diff --git a/icu4c/source/i18n/unicode/numberformatter.h b/icu4c/source/i18n/unicode/numberformatter.h
index e5b85fe..f93627f 100644
--- a/icu4c/source/i18n/unicode/numberformatter.h
+++ b/icu4c/source/i18n/unicode/numberformatter.h
@@ -11,8 +11,9 @@
 #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"
@@ -2520,6 +2521,27 @@
      */
     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
 
     /**
@@ -2553,6 +2575,9 @@
     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;
 
@@ -2560,6 +2585,16 @@
     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.
  *
diff --git a/icu4c/source/i18n/unicode/unumberformatter.h b/icu4c/source/i18n/unicode/unumberformatter.h
index b38763c..080e567 100644
--- a/icu4c/source/i18n/unicode/unumberformatter.h
+++ b/icu4c/source/i18n/unicode/unumberformatter.h
@@ -650,6 +650,13 @@
                                  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().
  *
diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h
index b0e7f9f..7f5bcdf 100644
--- a/icu4c/source/test/intltest/numbertest.h
+++ b/icu4c/source/test/intltest/numbertest.h
@@ -82,6 +82,7 @@
     void copyMove();
     void localPointerCAPI();
     void toObject();
+    void toDecimalNumber();
 
     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
 
diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp
index cfc10ab..57b3079 100644
--- a/icu4c/source/test/intltest/numbertest_api.cpp
+++ b/icu4c/source/test/intltest/numbertest_api.cpp
@@ -104,6 +104,7 @@
         TESTCASE_AUTO(copyMove);
         TESTCASE_AUTO(localPointerCAPI);
         TESTCASE_AUTO(toObject);
+        TESTCASE_AUTO(toDecimalNumber);
     TESTCASE_AUTO_END;
 }
 
@@ -3033,6 +3034,18 @@
     }
 }
 
+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,