Skip to content

Commit

Permalink
adding fmod/remainder regression test for quad-double
Browse files Browse the repository at this point in the history
  • Loading branch information
Ravenwater committed Aug 15, 2024
1 parent 990db42 commit 3e9eb00
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 3 deletions.
4 changes: 2 additions & 2 deletions include/universal/number/qd/math/fractional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
namespace sw { namespace universal {

// fmod retuns x - n*y where n = x/y with the fractional part truncated
qd fmod(qd x, qd y) {
qd fmod(const qd& x, const qd& y) {
return qd(std::fmod(double(x), double(y)));
}

// shim to stdlib
qd remainder(qd x, qd y) {
qd remainder(const qd& x, const qd& y) {
return qd(std::remainder(double(x), double(y)));
}

Expand Down
2 changes: 1 addition & 1 deletion include/universal/number/qd/mathlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//#include <universal/number/qd/math/complex.hpp>
#include <universal/number/qd/math/error_and_gamma.hpp>
#include <universal/number/qd/math/exponent.hpp>
//#include <universal/number/qd/math/fractional.hpp>
#include <universal/number/qd/math/fractional.hpp>
//#include <universal/number/qd/math/hyperbolic.hpp>
//#include <universal/number/qd/math/hypot.hpp>
//#include <universal/number/qd/math/logarithm.hpp>
Expand Down
106 changes: 106 additions & 0 deletions static/qd/math/fractional.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// fractional.cpp: test suite runner for fractional functions for quad-double (qd) floating-point
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <universal/utility/directives.hpp>
#include <numbers>
#include <universal/number/qd/qd.hpp>
#include <universal/verification/test_suite.hpp>

namespace sw {
namespace universal {

template<typename Ty>
void GenerateTestCase(Ty fa, Ty fb) {
unsigned precision = 25;
unsigned width = 30;
Ty fref;
sw::universal::qd a, b, ref, v;
a = fa;
b = fb;
fref = std::remainder(fa, fb);
ref = fref;
v = sw::universal::remainder(a, b);
auto oldPrec = std::cout.precision();
std::cout << std::setprecision(precision);
std::cout << " -> remainder(" << fa << "," << fb << ") = " << std::setw(width) << fref << std::endl;
std::cout << " -> remainder( " << a << "," << b << ") = " << v << '\n' << to_binary(v) << '\n';
std::cout << to_binary(ref) << "\n -> reference\n";
std::cout << (ref == v ? "PASS" : "FAIL") << std::endl << std::endl;
std::cout << std::setprecision(oldPrec);
}
}
}


// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
#define MANUAL_TESTING 1
// REGRESSION_LEVEL_OVERRIDE is set by the cmake file to drive a specific regression intensity
// It is the responsibility of the regression test to organize the tests in a quartile progression.
//#undef REGRESSION_LEVEL_OVERRIDE
#ifndef REGRESSION_LEVEL_OVERRIDE
#undef REGRESSION_LEVEL_1
#undef REGRESSION_LEVEL_2
#undef REGRESSION_LEVEL_3
#undef REGRESSION_LEVEL_4
#define REGRESSION_LEVEL_1 1
#define REGRESSION_LEVEL_2 1
#define REGRESSION_LEVEL_3 1
#define REGRESSION_LEVEL_4 1
#endif

int main()
try {
using namespace sw::universal;
using std::fmod;

std::string test_suite = "quad-double mathlib fractional function validation";
std::string test_tag = "fmod/remainder";
bool reportTestCases = false;
int nrOfFailedTestCases = 0;

ReportTestSuiteHeader(test_suite, reportTestCases);

#if MANUAL_TESTING

double a{ 1.5 }, b{ 1.25 };
qd da(a), db(b);

std::cout << "fmod( " << a << ", " << b << ") = " << fmod(a, b) << '\n';
std::cout << "fmod( " << da << ", " << db << ") = " << fmod(da, db) << '\n';

std::cout << "remainder( " << a << ", " << b << ") = " << remainder(a, b) << '\n';
std::cout << "remainder( " << da << ", " << db << ") = " << remainder(da, db) << '\n';

ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
return EXIT_SUCCESS; // ignore errors
#else


ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);

#endif // MANUAL_TESTING
}
catch (char const* msg) {
std::cerr << "Caught ad-hoc exception: " << msg << std::endl;
return EXIT_FAILURE;
}
catch (const sw::universal::universal_arithmetic_exception& err) {
std::cerr << "Caught unexpected universal arithmetic exception : " << err.what() << std::endl;
return EXIT_FAILURE;
}
catch (const sw::universal::universal_internal_exception& err) {
std::cerr << "Caught unexpected universal internal exception: " << err.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::runtime_error& err) {
std::cerr << "Caught runtime exception: " << err.what() << std::endl;
return EXIT_FAILURE;
}
catch (...) {
std::cerr << "Caught unknown exception" << std::endl;
return EXIT_FAILURE;
}

0 comments on commit 3e9eb00

Please sign in to comment.