Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace numeric {
namespace interval_lib {
namespace detail {

extern "C" { double rint(double); }
extern "C" { double rint(double); long double rintl(long double); }

struct c99_rounding_control
{
Expand All @@ -33,6 +33,7 @@ struct c99_rounding_control

template<class T>
static T to_int(const T& r) { return rint(r); }
static long double to_int(const long double& r) { return rintl(r); }
};

} // namespace detail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct ppc_rounding_control
extern "C" {
float rintf(float);
double rint(double);
long double rintl(long double);
}
#endif

Expand Down Expand Up @@ -114,7 +115,7 @@ struct rounding_control<long double>:
#endif
return r_;
}
static long double to_int(const long double& r) { return rint(r); }
static long double to_int(const long double& r) { return rintl(r); }
};

} // namespace interval_lib
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct sparc_rounding_control
extern "C" {
float rintf(float);
double rint(double);
long double rintl(long double);
}

template<>
Expand All @@ -100,7 +101,7 @@ struct rounding_control<long double>:
detail::sparc_rounding_control
{
static const long double& force_rounding(const long double& x) { return x; }
static long double to_int(const long double& x) { return rint(x); }
static long double to_int(const long double& x) { return rintl(x); }
};

} // namespace interval_lib
Expand Down
12 changes: 12 additions & 0 deletions test/fmod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <boost/numeric/interval/utility.hpp>
#include <boost/numeric/interval/checking.hpp>
#include <boost/numeric/interval/rounding.hpp>
#include <boost/numeric/interval/hw_rounding.hpp>
#include <boost/core/lightweight_test.hpp>
#include "bugs.hpp"

Expand All @@ -35,6 +36,15 @@ using namespace interval_lib;

typedef change_rounding<interval<int>, save_state_nothing<my_rounded_arith> >::type I;

// to_int must round a long double with rintl: rint converts it to double
// first, and fmod(2^60 + 1, 1) then misses 0.
void test_long_double() {
typedef interval<long double> L;
if (std::numeric_limits<long double>::digits < 62) return;
long double big = 1152921504606846977.0L, one = 1; // 2^60 + 1
BOOST_TEST(in_zero(fmod(L(big), L(one))));
}

int main() {

BOOST_TEST(equal(fmod(I(6,9), 7), I(6,9)));
Expand All @@ -49,5 +59,7 @@ int main() {
BOOST_TEST(equal(fmod(-17, I(7,8)), I(4,7)));
BOOST_TEST(equal(fmod(I(-17,-13), I(7,8)), I(4,11)));

test_long_double();

return boost::report_errors();
}
Loading