summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2024-03-20 08:48:13 -0700
committerGitHub <noreply@github.com>2024-03-20 08:48:13 -0700
commit6cefb85bc32208fec1524a7d1cf3c20d8ce21c15 (patch)
treea7d7c64d75f586b1f52b5149a7f47c55af15273a
parentf3b1161cb7b7d92d20eb947563a30c155c4c71a7 (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.cpp38
-rw-r--r--tests/bugs/gh-3589.slang4
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