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 | |
| 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>
| -rw-r--r-- | source/slang/slang-emit-source-writer.cpp | 38 | ||||
| -rw-r--r-- | tests/bugs/gh-3589.slang | 4 |
2 files changed, 31 insertions, 11 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); } diff --git a/tests/bugs/gh-3589.slang b/tests/bugs/gh-3589.slang index 58bb74f37..4534465d3 100644 --- a/tests/bugs/gh-3589.slang +++ b/tests/bugs/gh-3589.slang @@ -11,8 +11,8 @@ void main(uint id: SV_DispatchThreadID) outputBuffer[0] = i; outputBuffer[1] = m; - // CHECK: -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 + // CHECK: -1.79769313486231571e+308 outputBuffer2[0] = double.minValue; - // CHECK: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 + // CHECK: 1.79769313486231571e+308 outputBuffer2[1] = double.maxValue; }
\ No newline at end of file |
