]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/digitlst.cpp
ICU-62107.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / digitlst.cpp
index 4d7c3f4acb78f00c9675f721e7244b8c0f2c3e79..a35b66730b63c966c9e8f5560ff3b8360c51b2c2 100644 (file)
 #include "digitinterval.h" 
 #include "ucln_in.h"
 #include "umutex.h"
+#include "double-conversion.h"
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
 #include <stdio.h>
 #include <limits>
 
+using icu::double_conversion::DoubleToStringConverter;
+
 #if !defined(U_USE_STRTOD_L)
 # if U_PLATFORM_USES_ONLY_WIN32_API
 #   define U_USE_STRTOD_L 1
+#   define U_HAVE_XLOCALE_H 0
 # elif defined(U_HAVE_STRTOD_L)
 #   define U_USE_STRTOD_L U_HAVE_STRTOD_L
 # else
 #endif
 
 #if U_USE_STRTOD_L
-# if U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_CYGWIN
-#   include <locale.h>
-# else
+# if U_HAVE_XLOCALE_H
 #   include <xlocale.h>
+# else
+#   include <locale.h>
 # endif
 #endif
 
@@ -102,6 +106,7 @@ DigitList::DigitList()
     uprv_decNumberZero(fDecNumber);
 
     internalSetDouble(0.0);
+    fFormatFullPrecision = TRUE; // Apple
 }
 
 // -------------------------------------
@@ -149,6 +154,7 @@ DigitList::operator=(const DigitList& other)
             }
             fHave = other.fHave;
         }
+        fFormatFullPrecision = other.fFormatFullPrecision; // Apple
     }
     return *this;
 }
@@ -849,8 +855,55 @@ DigitList::set(double source)
         } else {
             uprv_strcpy(rep,"inf");
         }
+    } else if (uprv_isNaN(source)) {
+        uprv_strcpy(rep, "NaN");
+    } else if (!fFormatFullPrecision) { // Apple
+        sprintf(rep, "%+1.14e", source); // 14 = DBL_DIG - 1
     } else {
-        sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source);
+        bool sign;
+        int32_t length;
+        int32_t point;
+        DoubleToStringConverter::DoubleToAscii(
+            source,
+            DoubleToStringConverter::DtoaMode::SHORTEST,
+            0,
+            rep + 1,
+            sizeof(rep),
+            &sign,
+            &length,
+            &point
+        );
+
+        // Convert the raw buffer into a string for decNumber
+        int32_t power = point - length;
+        if (sign) {
+            rep[0] = '-';
+        } else {
+            rep[0] = '0';
+        }
+        length++;
+        rep[length++] = 'E';
+        if (power < 0) {
+            rep[length++] = '-';
+            power = -power;
+        } else {
+            rep[length++] = '+';
+        }
+        if (power < 10) {
+            rep[length++] = power + '0';
+        } else if (power < 100) {
+            rep[length++] = (power / 10) + '0';
+            rep[length++] = (power % 10) + '0';
+        } else {
+            U_ASSERT(power < 1000);
+            rep[length + 2] = (power % 10) + '0';
+            power /= 10;
+            rep[length + 1] = (power % 10) + '0';
+            power /= 10;
+            rep[length] = power + '0';
+            length += 3;
+        }
+        rep[length++] = 0;
     }
     U_ASSERT(uprv_strlen(rep) < sizeof(rep));