Skip to content

Commit

Permalink
GH-36767: [C++][CI] Fix test failure on i386 (#36769)
Browse files Browse the repository at this point in the history
### Rationale for this change

Our nightly build on i386 Debian (a 32-bit x86 build) fails with an error in decimal-to-read tests:
https://github.com/ursacomputing/crossbow/actions/runs/5593823296/jobs/10227952675#step:6:3255

### What changes are included in this PR?

Improve error messages by displaying the actual and expected values.

A side effect of this error message improvement is to... fix the test failure, as storing the computation result in a local variable seems to change the computed absolute difference.

This is probably due to x86 FPU rounding shenanigans, as explained here: https://stackoverflow.com/questions/37626687/c-fundamentals-double-variable-not-equal-to-double-expression

### Are these changes tested?

Yes.

### Are there any user-facing changes?

No.

* Closes: #36767

Authored-by: Antoine Pitrou <antoine@python.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
  • Loading branch information
pitrou authored Jul 19, 2023
1 parent 366e808 commit be2014a
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions cpp/src/arrow/util/decimal_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1046,42 +1046,51 @@ using ToDoubleTestParam = ToRealTestParam<double>;
template <typename Decimal, typename Real>
void CheckDecimalToReal(const std::string& decimal_value, int32_t scale, Real expected) {
Decimal dec(decimal_value);
ASSERT_EQ(dec.template ToReal<Real>(scale), expected)
<< "Decimal value: " << decimal_value << " Scale: " << scale;
Real actual = dec.template ToReal<Real>(scale);
ASSERT_EQ(actual, expected) << "Decimal value: " << decimal_value
<< ", scale: " << scale << ", expected: " << expected
<< ", actual: " << actual;
}

template <typename Decimal, typename Real>
void CheckDecimalToRealWithinOneULP(const std::string& decimal_value, int32_t scale,
Real expected) {
Decimal dec(decimal_value);
auto result = dec.template ToReal<Real>(scale);
ASSERT_TRUE(result == expected || result == std::nextafter(expected, expected + 1) ||
result == std::nextafter(expected, expected - 1))
<< "Decimal value: " << decimal_value << " Scale: " << scale;
Real actual = dec.template ToReal<Real>(scale);
ASSERT_TRUE(actual == expected || actual == std::nextafter(expected, expected + 1) ||
actual == std::nextafter(expected, expected - 1))
<< "Decimal value: " << decimal_value << ", scale: " << scale
<< ", expected: " << expected << ", actual: " << actual;
}

template <typename Decimal, typename Real>
void CheckDecimalToRealWithinEpsilon(const std::string& decimal_value, int32_t scale,
Real epsilon, Real expected) {
Decimal dec(decimal_value);
ASSERT_TRUE(std::abs(dec.template ToReal<Real>(scale) - expected) <= epsilon)
<< "Decimal value: " << decimal_value << " Scale: " << scale;
Real actual = dec.template ToReal<Real>(scale);
ASSERT_LE(std::abs(actual - expected), epsilon)
<< "Decimal value: " << decimal_value << ", scale: " << scale
<< ", expected: " << expected << ", actual: " << actual;
}

template <typename Decimal>
void CheckDecimalToRealApprox(const std::string& decimal_value, int32_t scale,
float expected) {
Decimal dec(decimal_value);
ASSERT_FLOAT_EQ(dec.template ToReal<float>(scale), expected)
<< "Decimal value: " << decimal_value << " Scale: " << scale;
float actual = dec.template ToReal<float>(scale);
ASSERT_FLOAT_EQ(actual, expected)
<< "Decimal value: " << decimal_value << ", scale: " << scale
<< ", expected: " << expected << ", actual: " << actual;
}

template <typename Decimal>
void CheckDecimalToRealApprox(const std::string& decimal_value, int32_t scale,
double expected) {
Decimal dec(decimal_value);
ASSERT_DOUBLE_EQ(dec.template ToReal<double>(scale), expected)
<< "Decimal value: " << decimal_value << " Scale: " << scale;
double actual = dec.template ToReal<double>(scale);
ASSERT_DOUBLE_EQ(actual, expected)
<< "Decimal value: " << decimal_value << ", scale: " << scale
<< ", expected: " << expected << ", actual: " << actual;
}

// Common tests for Decimal128::ToReal<T> and Decimal256::ToReal<T>
Expand Down

0 comments on commit be2014a

Please sign in to comment.