Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

User's Guide

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 31. Boost.Ratio 2.1.0

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext
Getting Boost.Ratio

Подъем. Ratio находится в последнем выпуске Boost в папке /boost/ratio. Документация, тесты и примеры папки на boost/libs/ratio/.

Вы также можете получить доступ к последнему (нестабильному?) состоянию из багажника Boost каталогов boost/ratio и libs/ratio.

Просто перейдите к wiki и следуйте инструкциям для анонимного доступа SVN.

Where to install Boost.Ratio?

Простой способ - декомпрессировать (или проверить с SVN) файлы в вашем каталоге BOOST_ROOT.

Building Boost.Ratio

Боост.Ратио является только заголовком библиотеки, поэтому не нужно ничего компилировать, вам просто нужно включить <boost/ratio.hpp>.

Requirements

Boost.Ratio зависит от некоторых библиотек Boost. Для этих конкретных частей вы должны использовать либо версию Boost 1.39.0, либо более позднее (даже более старые версии могут работать).

В частности, Соотношение зависит от:

Boost.Config

для конфигурационных целей...

Boost.Integer

для тонкой конформации и целых черт...

Boost.MPL

для MPL Assert и bool, логично...

Boost.StaticAssert

для STATIC_ASSERT, ...

Boost.TypeTraits

ибо is_base, is_convertible...

Boost.Utility/EnableIf

for enable_if, ...

Building an executable that uses Boost.Ratio

Ссылка не нужна.

Exception safety

Все функции в библиотеке являются нейтральными для исключения, обеспечивая надежную гарантию безопасности исключений.

Thread safety

Все функции в библиотеке небезопасны, за исключением случаев, когда они четко указаны.

Tested compilers

Boost.Ratio должен работать с компилятором C++03. Текущая версия была протестирована на:

Windows

  • MSVC 10.0

MinGW с

  • GCC 4.5.0
  • GCC 4.5.0 -std=c++0x
  • GCC 4.5.2
  • GCC 4.5.2 -std=c++0x
  • GCC 4.6.0
  • GCC 4.6.0 -std=c++0x

Ubuntu с * GCC 4.4.6 * GCC 4.4.6 -std=c++0x * GCC 4.5.4 * GCC 4.5.4 -std=c++0x * GCC 4.6.1 * GCC 4.6.1 -std=c++0x * Intel 12.1.3 * Intel 12.1.3 -std=c++0x

OsX

  • GCC 4.1.2
  • GCC 4.6.2
  • GCC 4.6.2 -std=c++0x
  • GCC 4.7.0
  • GCC 4.7.0 -std=c++0x
  • GCC 4.7.1
  • GCC 4.7.1 -std=c++0x
  • 1,6
  • 2,9
  • 2.9 -std=c++0x
  • кланг 3,0
  • кланг 3.0 -std=c++0x
  • кланг 3.1
  • кланг 3.1 -std=c++0x
  • кланг 3.1 -std=c++0x -stdlib=libc++
  • кланг 3,2
  • clang 3.2 -std=c++11
  • clang 3.2 -std=c++11 -stdlib=libc++
[Note] Note

Пожалуйста, сообщите нам, как это работает на других платформах/компиляторах.

[Note] Note

Пожалуйста, присылайте любые вопросы, комментарии и отчеты об ошибках, чтобы увеличить списки .

Ratio

ratio - это общая цель, вдохновленная Уолтером Брауном, позволяющая легко и безопасно вычислять рациональные ценности в компиляционное время. ratio класс ловит все ошибки (такие как деление на ноль и перегрузка) во время компиляции. Он используется в продолжительности и time_point классы для эффективного создания единиц времени. Он также может быть использован в других библиотеках «количество» или в любом месте есть рациональная константа, которая известна во время компиляции. Использование этой утилиты может значительно снизить шансы переполнения времени, потому что ratio (и любые соотношения в результате ratio арифметика) всегда сводятся к самым низким условиям.

ratio является шаблоном, забирающим два intmax_ts, со вторым по умолчанию до 1. В дополнение к копированию конструкторов и присвоению, он имеет только двух публичных членов, оба из которых являются статичными const intmax_t. Один - числитель ratio, а другой - знаменатель. ratio всегда нормализуется таким образом, что он выражается в самых низких терминах, а знаменатель всегда положительный. Когда числитель 0, знаменатель всегда 1.

Пример:

typedef ratio<5, 3>   five_thirds;
// five_thirds::num == 5, five_thirds::den == 3
typedef ratio<25, 15> also_five_thirds;
// also_five_thirds::num == 5, also_five_thirds::den == 3
typedef ratio_divide<five_thirds, also_five_thirds>::type one;
// one::num == 1, one::den == 1

Этот объект также включает в себя удобные типы для префиксов SI atto через exa, соответствующие их международно признанным определениям (в терминах ratio<34>). Это огромное синтаксическое удобство. Это предотвратит ошибки при указании констант, поскольку больше не нужно удваивать количество нолей при попытке написать миллионы или миллиарды.

Пример:

typedef ratio_multiply<ratio<5>, giga>::type _5giga;
// _5giga::num == 5000000000, _5giga::den == 1
typedef ratio_multiply<ratio<5>, nano>::type _5nano;
// _5nano::num == 1, _5nano::den == 200000000
Ratio I/O

Для каждого ratio<N, D> существует ratio_string<ratio<N>>><>>>>>>>>>>>>> Для тех ratio, которые соответствуют префиксу SI, соответствует международно признанному префиксу, хранящемуся как basic_string<CharT>>. Например, ratio_string<mega, char>::prefix() возвратит string("mega"). Для тех ratios, которые соответствуют префиксу SI symbol, соответствует международно признанному символу, хранящемуся как basic_string<CharT>>. Например, ratio_string<mega, char>::symbol() возвратит string("M"). Для всех остальных ratios, как префикс() и symbol() возвратить basic_string, содержащий "[ratio::num/ratio>den>>>>.

ratio_string<ratio<N, D>, CharT> определяется только для четырех типов символов:

  • char: UTF-8
  • char16_t: UTF-16
  • char32_t: UTF-32
  • wchar_t: UTF-16 (если wchar_t составляет 16 бит) или UTF-32

Когда персонаж является char, UTF-8 будет использоваться для кодирования имен. Когда персонаж char16_t, UTF-16 будет использоваться для кодирования имен. Когда персонаж char32_t, UTF-32 будет использоваться для кодирования имен. Когда персонаж wchar_t, кодирование будет UTF-16, если wchar_t составляет 16 бит, а в противном случае UTF-32.

символ (Greek mu или μ) для микро определяется по Unicode на U+00B5.

Примеры:

#include <boost/ratio/ratio_io.hpp>
#include <iostream>
int main()
{
    using namespace std;
    using namespace boost;
    cout << "ratio_string<deca, char>::prefix() = "
         <<  ratio_string<deca, char>::prefix() << '\n';
    cout << "ratio_string<deca, char>::symbol() = "
         <<  ratio_string<deca, char>::symbol() << '\n';
    cout << "ratio_string<giga, char>::prefix() = "
         <<  ratio_string<giga, char>::prefix() << '\n';
    cout << "ratio_string<giga, char>::symbol() = "
         <<  ratio_string<giga, char>::symbol() << '\n';
    cout << "ratio_string<ratio<4, 6>, char>::prefix() = "
         <<  ratio_string<ratio<4, 6>, char>::prefix() << '\n';
    cout << "ratio_string<ratio<4, 6>, char>::symbol() = "
         <<  ratio_string<ratio<4, 6>, char>::symbol() << '\n';
}

Выход будет

ratio_string<deca, char>::prefix() = deca
ratio_string<deca, char>::symbol() = da
ratio_string<giga, char>::prefix() = giga
ratio_string<giga, char>::symbol() = G
ratio_string<ratio<4, 6>, char>::prefix() = [2/3]
ratio_string<ratio<4, 6>, char>::symbol() = [2/3]
Ratio MPL Numeric Metafunctions

С точки зрения класса _ratio как Rational Constant мы можем смешивать _ratio<> и Boost.MPL Integral Constants в том же выражении, что и в

typedef mpl::times<int_<5>, giga>::type _5giga;
// _5giga::num == 5000000000, _5giga::den == 1
typedef mpl::times<int_<5>, nano>::type _5nano;
// _5nano::num == 1, _5nano::den == 200000000

Этот пример иллюстрирует использование boost::chrono::duration Типы Boost.Ratio инфраструктура и философия дизайна.

Давайте начнем с определения шаблона класса длина, который имитирует boost::chrono::duration, который представляет собой продолжительность времени в различных единицах, но ограничивает представление ДП и использует Boost.Ratio для преобразования единицы длины:

template <class Ratio>
class length {
private:
    double len_;
public:
    typedef Ratio ratio;
    length() : len_(1) {}
    length(const double& len) : len_(len) {}
    template <class R>
    length(const length<R>& d)
            : len_(d.count() * boost::ratio_divide<Ratio, R>::type::den /
                               boost::ratio_divide<Ratio, R>::type::num) {}
    double count() const {return len_;}
    length& operator+=(const length& d) {len_ += d.count(); return *this;}
    length& operator-=(const length& d) {len_ -= d.count(); return *this;}
    length operator+() const {return *this;}
    length operator-() const {return length(-len_);}
    length& operator*=(double rhs) {len_ *= rhs; return *this;}
    length& operator/=(double rhs) {len_ /= rhs; return *this;}
};

Вот небольшая выборка единиц длины:

typedef length<boost::ratio<1> >          meter;        // set meter as "unity"
typedef length<boost::centi>              centimeter;   // 1/100 meter
typedef length<boost::kilo>               kilometer;    // 1000  meters
typedef length<boost::ratio<254, 10000> > inch;         // 254/10000 meters

Обратите внимание, что, поскольку параметр шаблона длина на самом деле является типовым типом соотношения, так что мы можем использовать бустер::ratio, позволяющий более сложные единицы длины:

typedef length<boost::ratio_multiply<boost::ratio<12>, inch::ratio>::type>   foot;  // 12 inchs
typedef length<boost::ratio_multiply<boost::ratio<5280>, foot::ratio>::type> mile;  // 5280 feet

Теперь нам нужно определение секунд на основе плавающей точки:

typedef boost::chrono::duration<double> seconds;                         // unity

Мы даже можем поддерживать продолжительность субнаносекунд:

typedef boost::chrono::duration<double,  boost::pico> picosecond;  // 10^-12 seconds
typedef boost::chrono::duration<double, boost::femto> femtosecond; // 10^-15 seconds
typedef boost::chrono::duration<double,  boost::atto> attosecond;  // 10^-18 seconds

Наконец, мы можем написать доказательство концепции библиотеки SI-подразделений, жестко проводной для метров и плавающих точечных секунд, хотя она примет другие единицы:

template <class R1, class R2>
class quantity
{
    double q_;
public:
    typedef R1 time_dim;
    typedef R2 distance_dim;
    quantity() : q_(1) {}
    double get() const {return q_;}
    void set(double q) {q_ = q;}
};
template <>
class quantity<boost::ratio<1>, boost::ratio<0> >
{
    double q_;
public:
    quantity() : q_(1) {}
    quantity(seconds d) : q_(d.count()) {}  // note:  only User1::seconds needed here
    double get() const {return q_;}
    void set(double q) {q_ = q;}
};
template <>
class quantity<boost::ratio<0>, boost::ratio<1> >
{
    double q_;
public:
    quantity() : q_(1) {}
    quantity(meter d) : q_(d.count()) {}  // note:  only User1::meter needed here
    double get() const {return q_;}
    void set(double q) {q_ = q;}
};
template <>
class quantity<boost::ratio<0>, boost::ratio<0> >
{
    double q_;
public:
    quantity() : q_(1) {}
    quantity(double d) : q_(d) {}
    double get() const {return q_;}
    void set(double q) {q_ = q;}
};

Это позволяет создавать некоторые полезные типы блоков на основе SI:

typedef quantity<boost::ratio<0>, boost::ratio<0> >  Scalar;
typedef quantity<boost::ratio<1>, boost::ratio<0> >  Time;         // second
typedef quantity<boost::ratio<0>, boost::ratio<1> >  Distance;     // meter
typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed;        // meter/second
typedef quantity<boost::ratio<-2>, boost::ratio<1> > Acceleration; // meter/second^2

Чтобы сделать количество полезным, мы должны иметь возможность делать арифметические:

template <class R1, class R2, class R3, class R4>
quantity<typename boost::ratio_subtract<R1, R3>::type,
         typename boost::ratio_subtract<R2, R4>::type>
operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
{
    typedef quantity<typename boost::ratio_subtract<R1, R3>::type,
                    typename boost::ratio_subtract<R2, R4>::type> R;
    R r;
    r.set(x.get() / y.get());
    return r;
}
template <class R1, class R2, class R3, class R4>
quantity<typename boost::ratio_add<R1, R3>::type,
         typename boost::ratio_add<R2, R4>::type>
operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y)
{
    typedef quantity<typename boost::ratio_add<R1, R3>::type,
                    typename boost::ratio_add<R2, R4>::type> R;
    R r;
    r.set(x.get() * y.get());
    return r;
}
template <class R1, class R2>
quantity<R1, R2>
operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
{
    typedef quantity<R1, R2> R;
    R r;
    r.set(x.get() + y.get());
    return r;
}
template <class R1, class R2>
quantity<R1, R2>
operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y)
{
    typedef quantity<R1, R2> R;
    R r;
    r.set(x.get() - y.get());
    return r;
}

Со всеми вышеперечисленными скафлляциями мы теперь можем написать пример функции безопасной физики типа:

Distance
compute_distance(Speed v0, Time t, Acceleration a)
{
    return v0 * t + Scalar(.5) * a * t * t;  // if a units mistake is made here it won't compile
}

Наконец, мы можем использовать то, что мы создали, даже используя продолжительность времени (User1::секунды), а также продолжительность рабочего времени (boost::chrono::часов). Вход может быть произвольным, хотя и безопасным по типу, единицы, выход всегда в единицах SI. (Полная библиотека единиц будет поддерживать другие подразделения, конечно.)

int main()
{
    typedef boost::ratio<8, BOOST_INTMAX_C(0x7FFFFFFFD)> R1;
    typedef boost::ratio<3, BOOST_INTMAX_C(0x7FFFFFFFD)> R2;
    typedef User1::quantity<boost::ratio_subtract<boost::ratio<0>, boost::ratio<1> >::type,
                             boost::ratio_subtract<boost::ratio<1>, boost::ratio<0> >::type > RR;
    typedef boost::ratio_subtract<R1, R2>::type RS;
    std::cout << RS::num << '/' << RS::den << '\n';
    std::cout << "*************\n";
    std::cout << "* testUser1 *\n";
    std::cout << "*************\n";
    User1::Distance d( User1::mile(110) );
    User1::Time t( boost::chrono::hours(2) );
    RR r=d / t;
    //r.set(d.get() / t.get());
    User1::Speed rc= r;
    User1::Speed s = d / t;
    std::cout << "Speed = " << s.get() << " meters/sec\n";
    User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time();
    std::cout << "Acceleration = " << a.get() << " meters/sec^2\n";
    User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a);
    std::cout << "Distance = " << df.get() << " meters\n";
    std::cout << "There are "
        << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter";
    User1::meter mt = 1;
    User1::mile mi = mt;
    std::cout << " which is approximately " << mi.count() << '\n';
    std::cout << "There are "
        << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile";
    mi = 1;
    mt = mi;
    std::cout << " which is approximately " << mt.count() << '\n';
    User1::attosecond as(1);
    User1::seconds sec = as;
    std::cout << "1 attosecond is " << sec.count() << " seconds\n";
    std::cout << "sec = as;  // compiles\n";
    sec = User1::seconds(1);
    as = sec;
    std::cout << "1 second is " << as.count() << " attoseconds\n";
    std::cout << "as = sec;  // compiles\n";
    std::cout << "\n";
    return 0;
}

См. исходный файл example/si_physics.cpp

C++ Standards Committee's current Working Paper

Наиболее авторитетным справочным материалом для библиотеки является текущий рабочий документ Комитета по стандартам C++ (WP). 20.6 Совместное рациональное арифметическое «ратио»

N2661 - A Foundation to Sleep On

От Говарда Э. Хиннанта, Уолтера Э. Брауна, Джеффа Гарланда и Марка Патерно. Является очень информативным и обеспечивает мотивацию ключевых дизайнерских решений

LWG 1281. CopyConstruction and Assignment between ratios having the same normalized form

От Висенте Хуана Бетета Эскриба.


PrevUpHomeNext

Статья User's Guide раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 31. Boost.Ratio 2.1.0 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 31. Boost.Ratio 2.1.0 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:35:38/0.013881206512451/1