整数boost::multiprecision::mpq_rational到最接近的整数



将boost::multiprecision::mpq_rational四舍五入到最接近的整数的最佳方法是什么?

一个丑陋的解决方案是:

#include <boost/multiprecision/gmp.hpp>
using namespace boost::multiprecision;
inline int round_to_int(mpq_rational v)
{
  mpz_int vf_mpz = numerator(v) / denominator(v);
  mpz_t z;
  mpz_init(z);
  mpz_set(z, vf_mpz.backend().data());
  int vf = mpz_get_si(z);
  if (v - vf_mpz < vf_mpz + 1 - v) return vf;
  else return vf + 1;
}

有更好的主意吗?

至少修复负数,因为现在-13/7将四舍五入到-1(当-2更接近时)。

同样,由于范围最终应该映射到int,只需:

template <typename rational>
inline int round_to_int(rational v)
{
    v = v + typename rational::number(v.sign()) / 2;
    return v.template convert_to<int>();
}

这会得到更合理的结果,对于负数:参见Live On Coliru

-2   -2.00      -2
-13/7    -1.86      -2
-12/7    -1.71      -2
-11/7    -1.57      -2
-10/7    -1.43      -1
-9/7     -1.29      -1
-8/7     -1.14      -1
-1   -1.00      -1
-2   -2.00      -2
-13/7    -1.86      -2
-12/7    -1.71      -2
-11/7    -1.57      -2
-10/7    -1.43      -1
-9/7     -1.29      -1
-8/7     -1.14      -1
-1   -1.00      -1
-6/7     -0.86      -1
-5/7     -0.71      -1
-4/7     -0.57      -1
-3/7     -0.43       0
-2/7     -0.29       0
-1/7     -0.14       0
0     0.00       0
1/7   0.14       0
2/7   0.29       0
3/7   0.43       0
4/7   0.57       1
5/7   0.71       1
6/7   0.86       1
1     1.00       1
8/7   1.14       1
9/7   1.29       1
10/7      1.43       1
11/7      1.57       2
12/7      1.71       2
13/7      1.86       2
2     2.00       2
----------------------
-2   -2.00      -2
-3/2     -1.50      -2
-1   -1.00      -1
-1/2     -0.50      -1
0     0.00       0
1/2   0.50       1
1     1.00       1
3/2   1.50       2
2     2.00       2

完整代码:

#include <boost/multiprecision/mpfr.hpp>
#include <boost/multiprecision/number.hpp>
#include <vector>
using boost::multiprecision::mpq_rational;
template <typename rational>
inline int round_to_int(rational v)
{
    v = v + typename rational::number(v.sign()) / 2;
    return v.template convert_to<int>();
}
int main()
{
    auto show = [](mpq_rational a) { 
        std::cout << std::right << a << "t" << std::setw(6) << (double) a << "t" << std::right << std::setw(6) << round_to_int(a) << 'n';
    };
    std::cout << std::fixed << std::setprecision(2);
    for (mpq_rational r(-2); r<=2; r = (r*7+1)/7)
        show(r);
    std::cout << "----------------------n";
    for (mpq_rational r(-2); r<=2; r = (r*2+1)/2)
        show(r);
}

相关内容

  • 没有找到相关文章

最新更新