boost::rational does not maintain its invariant in case of overflow

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

boost::rational does not maintain its invariant in case of overflow

Boost - Users mailing list
With the program shown below, I obtained the following output:
std::numeric_limits<long>::max() == 9223372036854775807
r == boost::rational<long>(4294967296, 1853020188851841) ==
4294967296/1853020188851841
r * r == 0/8733086111712066817

Clearly there are 2 overflows but this leads to the invariant of the
class not being maintained, i.e. the faction is not simplified to 0/1
(gcd(num, den) != 1).

F

#include <boost/rational.hpp>

#include <iostream>

int main() {
  std::cout << "std::numeric_limits<long>::max() == "
            << std::numeric_limits<long>::max() << '\n';
  boost::rational<long> r(4294967296, 1853020188851841);
  std::cout << "r == boost::rational<long>(4294967296, 1853020188851841) == "
            << r << '\n';
  std::cout << "r * r == " << (r * r) << '\n';
  return 0;
}
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::rational does not maintain its invariant in case of overflow

Boost - Users mailing list
On 4/11/18 6:11 AM, Frédéric via Boost-users wrote:

> With the program shown below, I obtained the following output:
> std::numeric_limits<long>::max() == 9223372036854775807
> r == boost::rational<long>(4294967296, 1853020188851841) ==
> 4294967296/1853020188851841
> r * r == 0/8733086111712066817
>
> Clearly there are 2 overflows but this leads to the invariant of the
> class not being maintained, i.e. the faction is not simplified to 0/1
> (gcd(num, den) != 1).
>
> F
>
> #include <boost/rational.hpp>
>
> #include <iostream>
>
> int main() {
>    std::cout << "std::numeric_limits<long>::max() == "
>              << std::numeric_limits<long>::max() << '\n';
>    boost::rational<long> r(4294967296, 1853020188851841);
>    std::cout << "r == boost::rational<long>(4294967296, 1853020188851841) == "
>              << r << '\n';
>    std::cout << "r * r == " << (r * r) << '\n';
>    return 0;
> }
>

safe_numerics can address this.

Robert Ramey
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::rational does not maintain its invariant in case of overflow

Boost - Users mailing list
> safe_numerics can address this.

Is it part of boost? I see that it was conditionally accepted 1 year
ago but I cannot find it in the documentation. Maybe you did not have
time to address all the comments?

Regards,

F
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users