Skip to content

Commit 14e221a

Browse files
authored
[flang][runtime] Correct EXw.0 output editing (#75121)
A zero 'd' digit count in EX output editing has a meaning that's distinct from other numeric output editing descriptors, and I missed this in my initial implementation of the feature. d==0 means that the runtime should emit hexadecimal digits after the (hexa)decimal point until all of the rest of them would be zero.
1 parent 532d484 commit 14e221a

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

flang/include/flang/Decimal/binary-floating-point.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class BinaryFloatingPointNumber : public common::RealDetails<BINARY_PRECISION> {
143143
if (IsNaN() || IsInfinite() || keepBits >= binaryPrecision) {
144144
return true;
145145
}
146-
int lostBits{binaryPrecision - keepBits};
146+
int lostBits{keepBits < binaryPrecision ? binaryPrecision - keepBits : 0};
147147
RawType lostMask{static_cast<RawType>((RawType{1} << lostBits) - 1)};
148148
if (RawType lost{static_cast<RawType>(raw_ & lostMask)}; lost != 0) {
149149
bool increase{false};

flang/runtime/edit-output.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ auto RealOutputEditing<KIND>::ConvertToHexadecimal(
649649
// x_.binaryPrecision is constant, so / can be used for readability.
650650
int shift{x_.binaryPrecision - 4};
651651
typename BinaryFloatingPoint::RawType one{1};
652-
auto remaining{(one << shift) - one};
652+
auto remaining{(one << x_.binaryPrecision) - one};
653653
for (int digits{0}; digits < significantDigits; ++digits) {
654654
if ((flags & decimal::Minimize) && !(fraction & remaining)) {
655655
break;
@@ -682,7 +682,8 @@ bool RealOutputEditing<KIND>::EditEXOutput(const DataEdit &edit) {
682682
flags |= decimal::AlwaysSign;
683683
}
684684
int editWidth{edit.width.value_or(0)}; // 'w' field
685-
if (editWidth == 0 && !edit.digits) { // EX0 (no .d)
685+
if ((editWidth == 0 && !edit.digits) || editDigits == 0) {
686+
// EX0 or EXw.0
686687
flags |= decimal::Minimize;
687688
significantDigits = 28; // enough for 128-bit F.P.
688689
}

flang/unittests/Runtime/NumericalFormatTest.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -654,28 +654,44 @@ TEST(IOApiTests, FormatDoubleValues) {
654654
{"(EX24.13,';')", " 0XF.FFFFFFFFFFFF8P+1020;"},
655655
}},
656656
{// EX rounding
657-
0x3ff1000000000000uLL, // 1.0625
657+
0x3ff0100000000000uLL,
658658
{
659-
{"(F7.4,';')", " 1.0625;"},
660-
{"(EX9.1,';')", " 0X8.8P-3;"},
661-
{"(EX9.0,';')", " 0X8.P-3;"},
662-
{"(RN,EX9.0,';')", " 0X8.P-3;"},
663-
{"(RU,EX9.0,';')", " 0X9.P-3;"},
664-
{"(RD,EX9.0,';')", " 0X8.P-3;"},
665-
{"(RZ,EX9.0,';')", " 0X8.P-3;"},
666-
{"(RC,EX9.0,';')", " 0X9.P-3;"},
659+
{"(F11.8,';')", " 1.00390625;"},
660+
{"(EX10.2,';')", " 0X8.08P-3;"},
661+
{"(EX10.1,';')", " 0X8.0P-3;"},
662+
{"(EX10.0,';')", " 0X8.08P-3;"},
663+
{"(EX0.0,';')", "0X8.08P-3;"},
664+
{"(EX0,';')", "0X8.08P-3;"},
665+
{"(RN,EX10.1,';')", " 0X8.0P-3;"},
666+
{"(RU,EX10.1,';')", " 0X8.1P-3;"},
667+
{"(RD,EX10.1,';')", " 0X8.0P-3;"},
668+
{"(RZ,EX10.1,';')", " 0X8.0P-3;"},
669+
{"(RC,EX10.1,';')", " 0X8.1P-3;"},
670+
{"(RN,EX10.0,';')", " 0X8.08P-3;"},
671+
{"(RU,EX10.0,';')", " 0X8.08P-3;"},
672+
{"(RD,EX10.0,';')", " 0X8.08P-3;"},
673+
{"(RZ,EX10.0,';')", " 0X8.08P-3;"},
674+
{"(RC,EX10.0,';')", " 0X8.08P-3;"},
667675
}},
668676
{// EX rounding
669-
0xbff1000000000000uLL, // -1.0625
677+
0xbff0100000000000uLL,
670678
{
671-
{"(F7.4,';')", "-1.0625;"},
672-
{"(EX9.1,';')", "-0X8.8P-3;"},
673-
{"(EX9.0,';')", " -0X8.P-3;"},
674-
{"(RN,EX9.0,';')", " -0X8.P-3;"},
675-
{"(RU,EX9.0,';')", " -0X8.P-3;"},
676-
{"(RD,EX9.0,';')", " -0X9.P-3;"},
677-
{"(RZ,EX9.0,';')", " -0X8.P-3;"},
678-
{"(RC,EX9.0,';')", " -0X9.P-3;"},
679+
{"(F11.8,';')", "-1.00390625;"},
680+
{"(EX10.2,';')", "-0X8.08P-3;"},
681+
{"(EX10.1,';')", " -0X8.0P-3;"},
682+
{"(EX10.0,';')", "-0X8.08P-3;"},
683+
{"(EX0.0,';')", "-0X8.08P-3;"},
684+
{"(EX0,';')", "-0X8.08P-3;"},
685+
{"(RN,EX10.1,';')", " -0X8.0P-3;"},
686+
{"(RU,EX10.1,';')", " -0X8.0P-3;"},
687+
{"(RD,EX10.1,';')", " -0X8.1P-3;"},
688+
{"(RZ,EX10.1,';')", " -0X8.0P-3;"},
689+
{"(RC,EX10.1,';')", " -0X8.1P-3;"},
690+
{"(RN,EX10.0,';')", "-0X8.08P-3;"},
691+
{"(RU,EX10.0,';')", "-0X8.08P-3;"},
692+
{"(RD,EX10.0,';')", "-0X8.08P-3;"},
693+
{"(RZ,EX10.0,';')", "-0X8.08P-3;"},
694+
{"(RC,EX10.0,';')", "-0X8.08P-3;"},
679695
}},
680696
};
681697

0 commit comments

Comments
 (0)