bool VanishesBeforeMatcher<T>::MatchAndExplain( double const actual, testing::MatchResultListener* listener) const { std::int64_t const distance = ULPDistance(reference_, actual + reference_); bool const matches = min_ulps_ <= distance && distance <= max_ulps_; if (!matches) { *listener << "the numbers are separated by " << distance << " ulps"; } return matches; }
bool VanishesBeforeMatcher<T>::MatchAndExplain( quantities::Quantity<Dimensions> const& actual, testing::MatchResultListener* listener) const { std::int64_t const distance = ULPDistance(DoubleValue(reference_), DoubleValue(actual + reference_)); bool const matches = min_ulps_ <= distance && distance <= max_ulps_; if (!matches) { *listener << "the numbers are separated by " << distance << " ulps"; } return matches; }
inline std::int64_t ULPDistance(double const x, double const y) { if (x == y) { return 0; } double const x_sign = std::copysign(1, x); double const y_sign = std::copysign(1, y); if (x_sign != y_sign) { double const positive = x_sign == 1 ? x : y; double const negative = x_sign == 1 ? y : x; std::int64_t const positive_distance = ULPDistance(positive, +0.0); std::int64_t const negative_distance = ULPDistance(negative, -0.0); if (positive_distance > std::numeric_limits<std::int64_t>::max() - negative_distance) { return std::numeric_limits<std::int64_t>::max(); } else { return positive_distance + negative_distance; } } Qword x_qword; Qword y_qword; x_qword.double_value = x; y_qword.double_value = y; return std::abs(x_qword.long_value - y_qword.long_value); }
SymplecticRungeKuttaNyströmIntegrator<Position, order, time_reversible, evaluations, composition>:: SymplecticRungeKuttaNyströmIntegrator( serialization::FixedStepSizeIntegrator::Kind const kind, FixedVector<double, stages_> const& a, FixedVector<double, stages_> const& b) : FixedStepSizeIntegrator< SpecialSecondOrderDifferentialEquation<Position>>(kind), a_(a), b_(b) { DoublePrecision<double> c_i = 0.0; for (int i = 0; i < stages_; ++i) { c_[i] = c_i.value; c_i.Increment(a_[i]); } CHECK_LE(ULPDistance(1.0, c_i.value), 2); if (composition == kABA) { CHECK_EQ(0.0, b_[0]); } else if (composition == kBAB) { CHECK_EQ(0.0, a_[stages_ - 1]); } if (time_reversible) { switch (composition) { case kABA: for (int i = 0; i < stages_; ++i) { CHECK_EQ(a_[i], a_[stages_ - 1 - i]); } for (int i = 0; i < stages_ - 1; ++i) { CHECK_EQ(b_[i + 1], b_[stages_ - 1 - i]); } break; case kBAB: for (int i = 0; i < stages_ - 1; ++i) { CHECK_EQ(a_[i], a_[stages_ - 2 - i]); } for (int i = 0; i < stages_; ++i) { CHECK_EQ(b_[i], b_[stages_ - 1 - i]); } break; case kBA: LOG(FATAL) << "Time-reversible compositions have the FSAL property"; break; default: LOG(FATAL) << "Invalid CompositionMethod"; } } }