@@ -632,6 +632,31 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
632
632
fraction <<= 1 ;
633
633
--expo;
634
634
}
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
+ }
635
660
}
636
661
// Package & return result
637
662
constexpr RawType significandMask{(one << RealType::significandBits) - 1 };
@@ -642,9 +667,16 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
642
667
expo = 0 ; // subnormal
643
668
flags |= decimal::Underflow;
644
669
} 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
+ }
648
680
} else {
649
681
fraction &= significandMask; // remove explicit normalization unless x87
650
682
}
0 commit comments