diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2024-03-20 08:48:13 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-20 08:48:13 -0700 |
| commit | 6cefb85bc32208fec1524a7d1cf3c20d8ce21c15 (patch) | |
| tree | a7d7c64d75f586b1f52b5149a7f47c55af15273a /source | |
| parent | f3b1161cb7b7d92d20eb947563a30c155c4c71a7 (diff) | |
Change representation of float literal in language translation (#3798)
* Change representation of float literal in language translation
Fix the issue (#3490).
Previous implementation could zero out the very small float literal.
We now use scientific notation instead to represent the float numbers
whose exponential part are larger than a threshold. In other cases, keep
using fixed notation.
---------
Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-source-writer.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp index fa362d874..d8364d5c3 100644 --- a/source/slang/slang-emit-source-writer.cpp +++ b/source/slang/slang-emit-source-writer.cpp @@ -250,23 +250,43 @@ void SourceWriter::emit(double value) std::ostringstream stream; stream.imbue(std::locale::classic()); - stream.setf(std::ios::fixed, std::ios::floatfield); - stream.precision(20); + + int expBase2; + std::frexp(value, &expBase2); + // 2^17 = 131072 which is close to 10^5, so in that case we will + // change to use scientific representation. + std::ios::fmtflags flags = (std::abs(expBase2) >= 17) ? + std::ios::scientific : std::ios::fixed; + + stream.setf(flags, std::ios::floatfield); + stream.precision(std::numeric_limits<double>::max_digits10); stream << value; auto str = stream.str(); - auto slice = UnownedStringSlice(str.c_str()); + + std::size_t found = str.find_last_of("e"); + found = (found == std::string::npos) ? str.length() : found; + + // separate the mantissa and exponent part, as we want to remove the + // trailing 0s from the mantissa part. If we selected the fixed format + // above, the 'exponentStr' will be empty. + std::string mantissaStr = str.substr(0, found); + std::string exponentStr = str.substr(found, str.length()); + // Remove redundant trailing 0s. - if (slice.end() > slice.begin()) + if (mantissaStr.end() > mantissaStr.begin()) { - auto lastChar = slice.end() - 1; - while (lastChar > slice.begin() && *lastChar == '0') + auto lastChar = mantissaStr.end() - 1; + while (lastChar > mantissaStr.begin() && *lastChar == '0') lastChar--; if (*lastChar == '.') lastChar++; - if (lastChar > slice.end() - 1) - lastChar = slice.end() - 1; - slice = slice.subString(0, lastChar - slice.begin() + 1); + if (lastChar > mantissaStr.end() - 1) + lastChar = mantissaStr.end() - 1; + mantissaStr = mantissaStr.substr(0, lastChar - mantissaStr.begin() + 1); } + + auto finalStr = mantissaStr + exponentStr; + auto slice = UnownedStringSlice(finalStr.c_str()); emit(slice); } |
