Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

`fmod` of `interval<long double>` can miss the true result

Open Beginner friendly
#67 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp
Domain
databases

Research direction

Read detail/c99sub_rounding_control.hpp, detail/ppc_rounding_control.hpp, and detail/sparc_rounding_control.hpp, then compare their to_int implementations with the Alpha and IA-64 backends mentioned in the issue. Reproduce the fmod example with interval<long double> and check that the result contains 0 after the change.

Written by the indexing model from the issue text.

Description

rounding_control<long double>::to_int calls rint, the double function, in three backends:

  • detail/c99sub_rounding_control.hpp, - Its extern "C" { double rint(double); } is declared inside namespace detail, so the template to_int<T> always finds that one.
  • detail/ppc_rounding_control.hpp
  • detail/sparc_rounding_control.hpp

A long double with more than 53 significant bits is rounded to double before it is rounded to an integer. int_down and int_up then return wrong values, sometimes on the wrong side of the argument, and fmod, which uses int_down, returns an interval that does not contain the true result:

#include <boost/numeric/interval.hpp>
#include <iostream>

int main() {
  typedef boost::numeric::interval<long double> I;
  I r = fmod(I(1152921504606846977.0L), I(1));  // 2^60 + 1
  std::cout << r.lower() << ' ' << r.upper() << '\n';  // must contain 0
}

It print 1 1 : godbolt

Step Expected Actual
x 2^60 + 1 = 1152921504606846977, exact in long double (64-bit significand) same
div_down(x, 1) 1152921504606846977 (exact) same
to_int of that rintl(1152921504606846977) = 1152921504606846977 rint(double(1152921504606846977)): converting to double (53 bits) gives 1152921504606846976 =
2^60
n = int_down(...) 2^60 + 1 2^60
x - n * 1 1152921504606846977 − 1152921504606846977 = 0 1152921504606846977 − 1152921504606846976 = 1
result z [0, 0] [1, 1]

The Alpha and IA-64 backends already declare rintl and use it in to_int(long double); doing the same in these three fixes it.

Dominant language
C++
Stars
31
Forks
49
Avg merge
1d 4h
Merged PRs (30d)
9

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from boostorg/interval

All issues in boostorg/interval

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.