[flang-commits] [flang] 7eb5d4f - [flang][runtime] Round hex REAL input correctly with excess digits (#85587)
via flang-commits
flang-commits at lists.llvm.org
Mon Mar 18 14:13:05 PDT 2024
Author: Peter Klausler
Date: 2024-03-18T14:13:02-07:00
New Revision: 7eb5d4fc129a9b99b4dfe8f84507a08a72b55ecf
URL: https://github.com/llvm/llvm-project/commit/7eb5d4fc129a9b99b4dfe8f84507a08a72b55ecf
DIFF: https://github.com/llvm/llvm-project/commit/7eb5d4fc129a9b99b4dfe8f84507a08a72b55ecf.diff
LOG: [flang][runtime] Round hex REAL input correctly with excess digits (#85587)
Excess hexadecimal digits were too significant for rounding purposes,
leading to inappropriate rounding away from zero for some modes.
Added:
Modified:
flang/runtime/edit-input.cpp
flang/unittests/Runtime/NumericalFormatTest.cpp
Removed:
################################################################################
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index f7cbbc21e5956e..fbeb1a595b327e 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -614,11 +614,23 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
} else {
break;
}
- while (fraction >> binaryPrecision) {
- guardBit |= roundingBit;
- roundingBit = (int)fraction & 1;
- fraction >>= 1;
- ++expo;
+ if (fraction >> binaryPrecision) {
+ while (fraction >> binaryPrecision) {
+ guardBit |= roundingBit;
+ roundingBit = (int)fraction & 1;
+ fraction >>= 1;
+ ++expo;
+ }
+ // Consume excess digits
+ while (*++p) {
+ if (*p == '0') {
+ } else if ((*p >= '1' && *p <= '9') || (*p >= 'A' && *p <= 'F')) {
+ guardBit = 1;
+ } else {
+ break;
+ }
+ }
+ break;
}
}
if (fraction) {
@@ -633,31 +645,32 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
while (expo > 1 && !(fraction >> (binaryPrecision - 1))) {
fraction <<= 1;
--expo;
+ guardBit = roundingBit = 0;
}
- // Rounding
- bool increase{false};
- switch (rounding) {
- case decimal::RoundNearest: // RN & RP
- increase = roundingBit && (guardBit | ((int)fraction & 1));
- break;
- case decimal::RoundUp: // RU
- increase = !isNegative && (roundingBit | guardBit);
- break;
- case decimal::RoundDown: // RD
- increase = isNegative && (roundingBit | guardBit);
- break;
- case decimal::RoundToZero: // RZ
- break;
- case decimal::RoundCompatible: // RC
- increase = roundingBit != 0;
- break;
- }
- if (increase) {
- ++fraction;
- if (fraction >> binaryPrecision) {
- fraction >>= 1;
- ++expo;
- }
+ }
+ // Rounding
+ bool increase{false};
+ switch (rounding) {
+ case decimal::RoundNearest: // RN & RP
+ increase = roundingBit && (guardBit | ((int)fraction & 1));
+ break;
+ case decimal::RoundUp: // RU
+ increase = !isNegative && (roundingBit | guardBit);
+ break;
+ case decimal::RoundDown: // RD
+ increase = isNegative && (roundingBit | guardBit);
+ break;
+ case decimal::RoundToZero: // RZ
+ break;
+ case decimal::RoundCompatible: // RC
+ increase = roundingBit != 0;
+ break;
+ }
+ if (increase) {
+ ++fraction;
+ if (fraction >> binaryPrecision) {
+ fraction >>= 1;
+ ++expo;
}
}
// Package & return result
diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 37eecd7708a1eb..dee4dda4a22869 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -902,6 +902,14 @@ TEST(IOApiTests, EditDoubleInputValues) {
0}, // max finite
{"(EX22.0)", "0X.8P1025 ", 0x7ff0000000000000, ovf}, // +Inf
{"(EX22.0)", "-0X.8P1025 ", 0xfff0000000000000, ovf}, // -Inf
+ {"(RC,EX22.0)", "0X1.0000000000000P0 ", 0x3ff0000000000000, 0},
+ {"(RC,EX22.0)", "0X1.00000000000008P0 ", 0x3ff0000000000001, 0},
+ {"(RC,EX22.0)", "0X1.000000000000008P0 ", 0x3ff0000000000000, 0},
+ {"(RC,EX22.0)", "0X1.00000000000004P0 ", 0x3ff0000000000000, 0},
+ {"(RC,EX22.0)", "0X.80000000000000P1 ", 0x3ff0000000000000, 0},
+ {"(RC,EX22.0)", "0X.80000000000004P1 ", 0x3ff0000000000001, 0},
+ {"(RC,EX22.0)", "0X.800000000000004P1 ", 0x3ff0000000000000, 0},
+ {"(RC,EX22.0)", "0X.80000000000002P1 ", 0x3ff0000000000000, 0},
{"(RZ,F7.0)", " 2.e308", 0x7fefffffffffffff, 0}, // +HUGE()
{"(RD,F7.0)", " 2.e308", 0x7fefffffffffffff, 0}, // +HUGE()
{"(RU,F7.0)", " 2.e308", 0x7ff0000000000000, ovf}, // +Inf
More information about the flang-commits
mailing list