forked from OSchip/llvm-project
Support: Return scale from ScaledNumbers::matchScales()
This will be convenient when extracting `ScaledNumbers::getSum()`. llvm-svn: 211552
This commit is contained in:
parent
9ea8efaf92
commit
68a5ef1a63
|
@ -271,28 +271,30 @@ int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) {
|
||||||
/// losing precision only when necessary.
|
/// losing precision only when necessary.
|
||||||
///
|
///
|
||||||
/// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of
|
/// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of
|
||||||
/// \c LScale (\c RScale) is unspecified. If both \c LDigits and \c RDigits
|
/// \c LScale (\c RScale) is unspecified.
|
||||||
/// are \c 0, the output value is one of \c LScale and \c RScale; which is
|
///
|
||||||
/// unspecified.
|
/// As a convenience, returns the matching scale. If the output value of one
|
||||||
|
/// number is zero, returns the scale of the other. If both are zero, which
|
||||||
|
/// scale is returned is unspecifed.
|
||||||
template <class DigitsT>
|
template <class DigitsT>
|
||||||
void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
|
int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
|
||||||
int16_t &RScale) {
|
int16_t &RScale) {
|
||||||
static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
|
static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
|
||||||
|
|
||||||
if (LScale < RScale) {
|
if (LScale < RScale)
|
||||||
// Swap arguments.
|
// Swap arguments.
|
||||||
matchScales(RDigits, RScale, LDigits, LScale);
|
return matchScales(RDigits, RScale, LDigits, LScale);
|
||||||
return;
|
if (!LDigits)
|
||||||
}
|
return RScale;
|
||||||
if (!LDigits || !RDigits || LScale == RScale)
|
if (!RDigits || LScale == RScale)
|
||||||
return;
|
return LScale;
|
||||||
|
|
||||||
// Now LScale > RScale. Get the difference.
|
// Now LScale > RScale. Get the difference.
|
||||||
int32_t ScaleDiff = int32_t(LScale) - RScale;
|
int32_t ScaleDiff = int32_t(LScale) - RScale;
|
||||||
if (ScaleDiff >= 2 * getWidth<DigitsT>()) {
|
if (ScaleDiff >= 2 * getWidth<DigitsT>()) {
|
||||||
// Don't bother shifting. RDigits will get zero-ed out anyway.
|
// Don't bother shifting. RDigits will get zero-ed out anyway.
|
||||||
RDigits = 0;
|
RDigits = 0;
|
||||||
return;
|
return LScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift LDigits left as much as possible, then shift RDigits right.
|
// Shift LDigits left as much as possible, then shift RDigits right.
|
||||||
|
@ -303,7 +305,7 @@ void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
|
||||||
if (ShiftR >= getWidth<DigitsT>()) {
|
if (ShiftR >= getWidth<DigitsT>()) {
|
||||||
// Don't bother shifting. RDigits will get zero-ed out anyway.
|
// Don't bother shifting. RDigits will get zero-ed out anyway.
|
||||||
RDigits = 0;
|
RDigits = 0;
|
||||||
return;
|
return LScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
LDigits <<= ShiftL;
|
LDigits <<= ShiftL;
|
||||||
|
@ -312,6 +314,7 @@ void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
|
||||||
LScale -= ShiftL;
|
LScale -= ShiftL;
|
||||||
RScale += ShiftR;
|
RScale += ShiftR;
|
||||||
assert(LScale == RScale && "scales should match");
|
assert(LScale == RScale && "scales should match");
|
||||||
|
return LScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace ScaledNumbers
|
} // end namespace ScaledNumbers
|
||||||
|
|
|
@ -336,7 +336,7 @@ TEST(ScaledNumberHelpersTest, matchScales) {
|
||||||
int16_t RSx = RSIn; \
|
int16_t RSx = RSIn; \
|
||||||
int16_t Sy = SOut; \
|
int16_t Sy = SOut; \
|
||||||
\
|
\
|
||||||
matchScales(LDx, LSx, RDx, RSx); \
|
EXPECT_EQ(SOut, matchScales(LDx, LSx, RDx, RSx)); \
|
||||||
EXPECT_EQ(LDy, LDx); \
|
EXPECT_EQ(LDy, LDx); \
|
||||||
EXPECT_EQ(RDy, RDx); \
|
EXPECT_EQ(RDy, RDx); \
|
||||||
if (LDy) \
|
if (LDy) \
|
||||||
|
|
Loading…
Reference in New Issue