mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-08 09:03:18 +00:00
[flang] runtime: For Fw.d formatting, don't oscillate forever
The algorithm for Fw.d output will drive binary to decimal conversion for an initial fixed number of digits, then adjust that number based on the result's exposent. For value close to a power of ten, this adjustment process wouldn't terminate; e.g., formatting 9.999 as F10.2 would start with 1e2, boost the digits to 2, get 9.99e1, decrease the digits, and loop. Solve by refusing to boost the digits a second time. Differential Revision: https://reviews.llvm.org/D107490
This commit is contained in:
parent
617be2756f
commit
4876520eef
@ -310,7 +310,6 @@ ConversionToDecimalResult ConvertToDecimal(char *buffer, std::size_t size,
|
||||
more.Next();
|
||||
}
|
||||
number.Minimize(Big{less, rounding}, Big{more, rounding});
|
||||
} else {
|
||||
}
|
||||
return number.ConvertToDecimal(buffer, size, flags, digits);
|
||||
}
|
||||
|
@ -268,6 +268,7 @@ bool RealOutputEditing<binaryPrecision>::EditFOutput(const DataEdit &edit) {
|
||||
// Multiple conversions may be needed to get the right number of
|
||||
// effective rounded fractional digits.
|
||||
int extraDigits{0};
|
||||
bool canIncrease{true};
|
||||
while (true) {
|
||||
decimal::ConversionToDecimalResult converted{
|
||||
Convert(extraDigits + fracDigits, edit, flags)};
|
||||
@ -277,11 +278,12 @@ bool RealOutputEditing<binaryPrecision>::EditFOutput(const DataEdit &edit) {
|
||||
}
|
||||
int scale{IsZero() ? 1 : edit.modes.scale}; // kP
|
||||
int expo{converted.decimalExponent + scale};
|
||||
if (expo > extraDigits && extraDigits >= 0) {
|
||||
if (expo > extraDigits && extraDigits >= 0 && canIncrease) {
|
||||
extraDigits = expo;
|
||||
if (!edit.digits.has_value()) { // F0
|
||||
fracDigits = sizeof buffer_ - extraDigits - 2; // sign & NUL
|
||||
}
|
||||
canIncrease = false; // only once
|
||||
continue;
|
||||
} else if (expo < extraDigits && extraDigits > -fracDigits) {
|
||||
extraDigits = std::max(expo, -fracDigits);
|
||||
|
@ -627,6 +627,20 @@ TEST(IOApiTests, FormatDoubleValues) {
|
||||
{"(F5.3,';')", -0.0025, "-.003;"},
|
||||
{"(F5.3,';')", -0.00025, "-.000;"},
|
||||
{"(F5.3,';')", -0.000025, "-.000;"},
|
||||
{"(F5.3,';')", 99.999, "*****;"},
|
||||
{"(F5.3,';')", 9.9999, "*****;"},
|
||||
{"(F5.3,';')", 0.99999, "1.000;"},
|
||||
{"(F5.3,';')", 0.099999, "0.100;"},
|
||||
{"(F5.3,';')", 0.0099999, "0.010;"},
|
||||
{"(F5.3,';')", 0.00099999, "0.001;"},
|
||||
{"(F5.3,';')", 0.000099999, "0.000;"},
|
||||
{"(F5.3,';')", -99.999, "*****;"},
|
||||
{"(F5.3,';')", -9.9999, "*****;"},
|
||||
{"(F5.3,';')", -0.99999, "*****;"},
|
||||
{"(F5.3,';')", -0.099999, "-.100;"},
|
||||
{"(F5.3,';')", -0.0099999, "-.010;"},
|
||||
{"(F5.3,';')", -0.00099999, "-.001;"},
|
||||
{"(F5.3,';')", -0.000099999, "-.000;"},
|
||||
};
|
||||
|
||||
for (auto const &[format, value, expect] : individualTestCases) {
|
||||
|
Loading…
Reference in New Issue
Block a user