@@ -632,6 +632,31 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
632632 fraction <<= 1 ;
633633 --expo;
634634 }
635+ // Rounding
636+ bool increase{false };
637+ switch (rounding) {
638+ case decimal::RoundNearest: // RN & RP
639+ increase = roundingBit && (guardBit | ((int )fraction & 1 ));
640+ break ;
641+ case decimal::RoundUp: // RU
642+ increase = !isNegative && (roundingBit | guardBit);
643+ break ;
644+ case decimal::RoundDown: // RD
645+ increase = isNegative && (roundingBit | guardBit);
646+ break ;
647+ case decimal::RoundToZero: // RZ
648+ break ;
649+ case decimal::RoundCompatible: // RC
650+ increase = roundingBit != 0 ;
651+ break ;
652+ }
653+ if (increase) {
654+ ++fraction;
655+ if (fraction >> binaryPrecision) {
656+ fraction >>= 1 ;
657+ ++expo;
658+ }
659+ }
635660 }
636661 // Package & return result
637662 constexpr RawType significandMask{(one << RealType::significandBits) - 1 };
@@ -642,9 +667,16 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
642667 expo = 0 ; // subnormal
643668 flags |= decimal::Underflow;
644669 } else if (expo >= RealType::maxExponent) {
645- expo = RealType::maxExponent; // +/-Inf
646- fraction = 0 ;
647- flags |= decimal::Overflow;
670+ if (rounding == decimal::RoundToZero ||
671+ (rounding == decimal::RoundDown && !isNegative) ||
672+ (rounding == decimal::RoundUp && isNegative)) {
673+ expo = RealType::maxExponent - 1 ; // +/-HUGE()
674+ fraction = significandMask;
675+ } else {
676+ expo = RealType::maxExponent; // +/-Inf
677+ fraction = 0 ;
678+ flags |= decimal::Overflow;
679+ }
648680 } else {
649681 fraction &= significandMask; // remove explicit normalization unless x87
650682 }
0 commit comments