c++11 boost - 数学(1) constants、rational、ratio

2018-07-12 21:34:56

math.constants 库提供了一些数学常数。

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
#include <type_traits>
using namespace std;

#include <boost/math/constants/constants.hpp>
using namespace boost::math;

void case1()
{
    cout << setprecision(64);  //设置显示精度为64位

    auto a = float_constants::pi * 2 * 2;
    cout << "area \t\t= " << a << endl;

    using namespace double_constants;

	cout << "root 2 \t= " << root_two << endl;
	cout << "root 3 \t= " << root_three << endl;
    auto x = root_two * root_three;
    cout << "root 2 * 3 \t= " << x << endl;

	cout << "pi \t= " << pi << endl;
    cout << "root pi \t= " << root_pi << endl;
    cout << "pi pow e \t= " << pi_pow_e << endl;
}

#include <boost/multiprecision/cpp_dec_float.hpp>

void case2()
{
    using namespace constants;

    typedef decltype(pi<float>) pi_t;
    assert(is_function<pi_t>::value);

    assert(pi<float>() == float_constants::pi);
    assert(pi<double>() == double_constants::pi);

    typedef boost::multiprecision::cpp_dec_float_100 float_100;
    cout << setprecision(100)
         << pi<float_100>() << endl;
}

int main()
{
    case1();
    case2();
}
[root@192 c++]# g++ -std=c++11 main.cpp
[root@192 c++]# ./a.out 
area 		= 12.56637096405029296875
root 2 	= 1.4142135623730951454746218587388284504413604736328125
root 3 	= 1.732050807568877193176604123436845839023590087890625
root 2 * 3 	= 2.449489742783178325424842114443890750408172607421875
pi 	= 3.141592653589793115997963468544185161590576171875
root pi 	= 1.7724538509055161039640324815991334617137908935546875
pi pow e 	= 22.459157718361044686616878607310354709625244140625
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068


rational 库实现了有理数即分子分母表示,数字运算时没有精度损失,可以应用于金融财务。

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
#include <type_traits>
using namespace std;

#include <boost/rational.hpp>
using namespace boost;

void case1()
{
    rational<int> a;   //0
    rational<int> b(20);  //20
    rational<int> c(31415, 10000);  //3.1415

    rational<int> r;  //0
    r = 0x31;  //49
    r.assign(7, 8);  //7/8
}

void case2()
{
#if 0
    rational<int> r(1.0);
    cout << r << endl;

    r = 3.14;
    cout << r << endl;

    r.assign(7.23, 100);
    cout << r << endl;
#endif
}

void case3()
{
    rational<int>   a(3),b(65534),c(22,7);

    b += a;
    c -= a;
    if (c >= 0)
    {
        c = c * b;
        ++a;
    }
    assert(a == 4);
}

void case4()
{
    rational<int> r(10);
    if (r)
    {
        r -= 10;
    }
    assert(!r);
}

void case5()
{
    rational<int> r(2718, 1000);
    cout << rational_cast<int>(r) << endl;    //2
    cout << rational_cast<double>(r) << endl; //2.718

    //double x = r;
}

//分子 分母
void case6()
{
    rational<int> r(22,7);
    cout << r.numerator() << ":" << r.denominator()
          << "=" << rational_cast<double>(r);
    cout << endl;
}

void case7()
{
    rational<int> a(-1414,1000), pi(314, 100);

    cout << "abs=" << abs(a) << endl;  //绝对值
    cout << pow(rational_cast<double>(a), 2) << endl;
    cout << cos(rational_cast<double>(pi)) << endl;

}

#include <boost/format.hpp>

//gcd最大公约数
//lcm最小公倍数
void case8()
{
    int a = 37, b = 62;
    format fmt("gcd(%1%, %2%) = %3%. lcm(%1%, %2%) = %4%\n");
    cout << fmt % a % b % gcd(a,b) % lcm(a,b);
}

int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    case8();
}
[root@192 c++]# g++ -std=c++11 main.cpp
[root@192 c++]# ./a.out 
2
2.718
22:7=3.14286
abs=707/500
1.9994
-0.999999
gcd(37, 62) = 1. lcm(37, 62) = 2294


ratio 虽然内部表示也是有理数,但是它表示的是单位。主要成员为 num-分子,den-分母,它们都是静态成员,在编译期进行各种运算。不指定分母默认为1。

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
#include <cassert>
using namespace std;

//#define BOOST_RATIO_EXTENSIONS
#include <boost/ratio.hpp>
using namespace boost;

//////////////////////////////////////////

void case1()
{
    typedef ratio<1, 2> half;

    assert(half::num == 1);
    assert(half::den == 2);

#if 0
    auto v = half::value();
    cout << v << endl;
    assert(v * 2 == 1);

    half frac;
    assert(frac().numerator() == frac.num);

    typedef ratio<2, 4> two_fourth;
    cout << two_fourth()() << endl;
    assert(half::value() == two_fourth::value());
#endif

    typedef ratio<12> dozen;
    assert(2 * dozen::num == 24);
}

typedef ratio<1, 2> half;
typedef ratio<1, 4> quater;

typedef ratio<12, 1> dozen;
typedef ratio<kilo::num*10, 1> cn_wan;  //10000

typedef ratio<                           1024>     kibi;   //KB
typedef ratio<                      1024*1024>  mebi;   //MB
typedef ratio<                 1024*1024*1024>  gibi;   //GB


void case2()
{
    assert(kilo::num < kibi::num);
    cout << kilo::num << endl;
    cout << kibi::num << endl;

#if 0
    assert((quater())()*2 == half()());
    assert((mega())() == cn_wan()()*100);
#endif
    assert(mega::num == cn_wan::num*100);
}

//c++11字面值
boost::intmax_t operator"" _kb(unsigned long long n)
{
    return n * kibi::num;
}

boost::intmax_t operator"" _gb(unsigned long long n)
{
    return n * gibi::num;
}

void case3()
{
    auto x = 2_gb;
    auto y = 10_kb;

    assert(x = 2 * 100 * y);
}

//字符串表示
template<typename R>
using string_out = ratio_string<R, char>;

void case4()
{
    cout << string_out<kilo>::prefix() << endl;
    cout << string_out<kilo>::symbol() << endl;

    cout << string_out<nano>::prefix() << endl;
    cout << string_out<nano>::symbol() << endl;

    cout << string_out<ratio<22, 7>>::prefix() << endl;
}

int main()
{
    case1();
    case2();
    case3();
    case4();
}
[root@192 c++]# g++ -std=c++11 main.cpp
[root@192 c++]# 
[root@192 c++]# 
[root@192 c++]# 
[root@192 c++]# ./a.out 
1000
1024
kilo
k
nano
n
[22/7]


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/ac


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。