Пример #1
0
void ribi::DrawCanvas::DrawArc(
  const double left, const double top, const double right, const double bottom,
    const boost::units::quantity<boost::units::si::plane_angle> startAngle,
    const boost::units::quantity<boost::units::si::plane_angle> spanAngle) noexcept
{
  assert(left < right);
  assert(top < bottom);
  const double midx = (left + right) / 2.0;
  const double midy = (top + bottom) / 2.0;
  const double pi = boost::math::constants::pi<double>();
  const double ray_horizontal = (right  - left) / 2.0;
  const double ray_vertical   = (bottom - top ) / 2.0;
  const double average_ray    = (ray_horizontal + ray_vertical) / 2.0;
  const double arclength = average_ray * pi * 2.0 * (spanAngle.value() / (2.0 * pi));
  const int n_steps = std::abs(static_cast<int>(arclength + 0.5));
  if (n_steps == 0) return;
  assert(n_steps > 0);
  double angle { startAngle.value() };
  const double dAngle = spanAngle.value() / static_cast<double>(n_steps);
  for (int i=0; i!=n_steps; ++i)
  {
    double x = midx + (std::sin(angle) * ray_horizontal);
    double y = midy - (std::cos(angle) * ray_vertical);
    DrawDot(x,y);
    angle += dAngle;
  }
  m_signal_changed(this);
}
Пример #2
0
void serialize(OutputArchive& ar, boost::units::quantity<U, T> q)
{
    static_assert(std::is_integral<T>::value,
            "Only integral based quantities are supported");
    auto tmp = hton(q.value());
    ar << tmp;
}
Пример #3
0
int main()
{
  std::cout << std::setprecision(35) << std::fixed;
  for (int i=0; i!=10; ++i)
  {
    const double x = static_cast<double>(i);
    std::cout << std::sqrt(x) << '\t' << CalculateSqrt(x) << '\n';
  }
  std::cout << '\n';
  for (int i=0; i!=10; ++i)
  {
    const boost::units::quantity<boost::units::si::length> x
      = static_cast<double>(i) * boost::units::si::meter;
    std::cout << std::sqrt(x.value()) << '\t' << CalculateSqrt(x) << '\n';
  }
}
Пример #4
0
int main()
{
  //Works as expected
  {
    const boost::units::quantity<boost::units::si::length> a(
      1.23 * boost::units::si::meter);
    const boost::units::quantity<boost::units::si::length> b(
      1.23 * boost::units::si::milli * boost::units::si::meter);

    const double x = a / boost::units::si::meter;
    const double y = b / boost::units::si::meter;
    assert(x != y && "A meter is not a millimeter");

  }
  //Works as expected
  {
    const boost::units::quantity<boost::units::si::length> a(
      1.23 * boost::units::si::meter);
    const boost::units::quantity<boost::units::si::length> b(
      1.23 * boost::units::si::milli * boost::units::si::meter);

    const double x = a.value();
    const double y = b.value();
    assert(x != y && "A meter is not a millimeter");

  }
  //FAILS
  {
    assert( (1.23 * boost::units::si::meter).value()
      != (1.23 * boost::units::si::milli * boost::units::si::meter).value()
      && "A meter is not a millimeter");
  }
  //FAILS
  {
    const double x = (1.23 * boost::units::si::meter).value();
    const double y = (1.23 * boost::units::si::milli * boost::units::si::meter).value();
    assert(x != y && "A meter is not a millimeter");
  }
}
void UpdaterBoostNoUnits::impl_update(boost::units::quantity<boost::units::si::time> dt, std::size_t nbPeriod)
{
    using stepper_type = boost::numeric::odeint::symplectic_rkn_sb3a_mclachlan<container_t, container_t>;

    const auto masses = extractMasses();
    auto p = extractMomentums();
    auto q = extractPositions();

    boost::numeric::odeint::integrate_n_steps(
            stepper_type(),
            std::make_pair(solar_system_coor(masses), solar_system_momentum(masses)),
            std::make_pair(std::ref(q), std::ref(p)),
            0.0, dt.value(), nbPeriod /*, streaming_observer(cout)*/);
}
Пример #6
0
int test_main(int,char *[])
{
    double  inf = std::numeric_limits<double>::infinity(),
            nan = 0.0/zero;
    
    // default constructor
    const bu::quantity<bu::energy>          E1(0.0*bu::joules),
                                            E2(inf*bu::joules),
                                            E3(nan*bu::joules); 
    
    BOOST_CHECK((bu::isfinite)(E1) == true);
    BOOST_CHECK((bu::isfinite)(E2) == false);
    BOOST_CHECK((bu::isfinite)(E3) == false);

    BOOST_CHECK((bu::isinf)(E1) == false);
    BOOST_CHECK((bu::isinf)(E2) == true);
    BOOST_CHECK((bu::isinf)(E3) == false);
    
    BOOST_CHECK((bu::isnan)(E1) == false);
    BOOST_CHECK((bu::isnan)(E2) == false);
    BOOST_CHECK((bu::isnan)(E3) == true);
    
    BOOST_CHECK((bu::isnormal)(E1) == false);
    BOOST_CHECK((bu::isnormal)(E2) == false);
    BOOST_CHECK((bu::isnormal)(E3) == false);

    const bu::quantity<bu::energy>          E4(-2.5*bu::joules),
                                            E5(2.5*bu::joules); 
                                            
    BOOST_CHECK((bu::isgreater)(E4,E5) == false);
    BOOST_CHECK((bu::isgreater)(E5,E4) == true);
    BOOST_CHECK((bu::isgreater)(E4,E4) == false);
    BOOST_CHECK((bu::isgreater)(E3,E4) == false);
    BOOST_CHECK((bu::isgreater)(E4,E3) == false);

    BOOST_CHECK((bu::isgreaterequal)(E4,E5) == false);
    BOOST_CHECK((bu::isgreaterequal)(E5,E4) == true);
    BOOST_CHECK((bu::isgreaterequal)(E4,E4) == true);
    BOOST_CHECK((bu::isgreaterequal)(E3,E4) == false);
    BOOST_CHECK((bu::isgreaterequal)(E4,E3) == false);

    BOOST_CHECK((bu::isless)(E4,E5) == true);
    BOOST_CHECK((bu::isless)(E5,E4) == false);
    BOOST_CHECK((bu::isless)(E4,E4) == false);
    BOOST_CHECK((bu::isless)(E3,E4) == false);
    BOOST_CHECK((bu::isless)(E4,E3) == false);

    BOOST_CHECK((bu::islessequal)(E4,E5) == true);
    BOOST_CHECK((bu::islessequal)(E5,E4) == false);
    BOOST_CHECK((bu::islessequal)(E4,E4) == true);
    BOOST_CHECK((bu::islessequal)(E3,E4) == false);
    BOOST_CHECK((bu::islessequal)(E4,E3) == false);

    BOOST_CHECK((bu::islessgreater)(E4,E5) == true);
    BOOST_CHECK((bu::islessgreater)(E5,E4) == true);
    BOOST_CHECK((bu::islessgreater)(E4,E4) == false);
    BOOST_CHECK((bu::islessgreater)(E3,E4) == false);
    BOOST_CHECK((bu::islessgreater)(E4,E3) == false);

    BOOST_CHECK((bu::isunordered)(E4,E5) == false);
    BOOST_CHECK((bu::isunordered)(E5,E4) == false);
    BOOST_CHECK((bu::isunordered)(E4,E4) == false);
    BOOST_CHECK((bu::isunordered)(E3,E4) == true);
    BOOST_CHECK((bu::isunordered)(E4,E3) == true);

    BOOST_CHECK((bu::abs)(E4) == E5);
    BOOST_CHECK((bu::ceil)(E4) == -2.0*bu::joules);
    BOOST_CHECK((bu::copysign)(E4,E5) == E5);
    BOOST_CHECK((bu::fabs)(E4) == E5);
    BOOST_CHECK((bu::floor)(E4) == -3.0*bu::joules);
    BOOST_CHECK((bu::fdim)(E4,E5) == 0.0*bu::joules);
    BOOST_CHECK((bu::fdim)(E5,E4) == E5-E4);
    
    const bu::quantity<bu::length>  L1(3.0*bu::meters),
                                    L2(4.0*bu::meters);
    const bu::quantity<bu::area>    A1(4.0*bu::square_meters),
                                    A2(L1*L2+A1);

#if 0
    BOOST_CHECK((bu::fma)(L1,L2,A1) == A2);
#endif
       
    BOOST_CHECK((bu::fmax)(E4,E5) == E5);
    BOOST_CHECK((bu::fmin)(E4,E5) == E4);
    
    // need to test fpclassify
    
    BOOST_CHECK(bu::hypot(L1,L2) == 5.0*bu::meters);
    
#if 0

//    BOOST_CHECK(bu::llrint(E4).value() == bu::detail::llrint(E4.value()));
//    BOOST_CHECK(bu::llround(E4).value() == bu::detail::llround(E4.value()));
    BOOST_CHECK((bu::nearbyint)(E4).value() == (bu::detail::nearbyint)(E4.value()));
    BOOST_CHECK((bu::rint)(E4).value() == (bu::detail::rint)(E4.value()));

#endif

#if 0

    BOOST_CHECK((bu::nextafter)(E4,E5).value() == (boost::math::nextafter)(E4.value(),E5.value()));
    BOOST_CHECK((bu::nextafter)(E5,E4).value() == (boost::math::nextafter)(E5.value(),E4.value()));

    BOOST_CHECK((bu::nexttoward)(E4,E5).value() == (boost::math::nextafter)(E4.value(),E5.value()));
    BOOST_CHECK((bu::nexttoward)(E5,E4).value() == (boost::math::nextafter)(E5.value(),E4.value()));


    BOOST_CHECK((bu::round)(E4 - 0.00000000001 * bu::joules) == -3.0*bu::joules);
    BOOST_CHECK((bu::round)(E5 + 0.00000000001 * bu::joules) == 3.0*bu::joules);    
#endif

    BOOST_CHECK((bu::signbit)(E4) == 1);
    BOOST_CHECK((bu::signbit)(E5) == 0);
    BOOST_CHECK((bu::trunc)(E4) == -2.0*bu::joules);
    BOOST_CHECK((bu::trunc)(E5) == 2.0*bu::joules);

    BOOST_CHECK((bu::fmod)(E4,E5) == -0.0*bu::joules);

    bu::quantity<bu::energy>    pint;
    
    BOOST_CHECK((bu::modf)(E4,&pint) == -0.5*bu::joules);
    BOOST_CHECK(pint == -2.0*bu::joules);
    
    int ex;
    const bu::quantity<bu::energy>  E6((bu::frexp)(E4,&ex));
    
    BOOST_CHECK(E6 == -0.625*bu::joules);
    BOOST_CHECK(ex == 2);
    BOOST_CHECK((bu::ldexp)(E6,ex) == E4);
    
    const bu::quantity<bu::dimensionless>   E7(1.0);
    
    BOOST_CHECK(bu::pow(E7,E7) == 1.0*1.0);
    
    const bu::quantity<bu::dimensionless>   E8((bu::exp)(E7));
    
    BOOST_CHECK(std::abs(E8 - std::exp(1.0)) < .000001);
    BOOST_CHECK(bu::log(E8) == E7);
    
    const bu::quantity<bu::dimensionless>   E9(100.0);
    
    BOOST_CHECK(bu::log10(E9) == 2.0);
    
    BOOST_CHECK(bu::sqrt(A1) == 2.0*bu::meters);
    
    return 0;
}
int test_main(int,char *[])
{
    //// si->si always true
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::length_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::mass_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::time_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::current_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::temperature_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::amount_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::luminous_intensity_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::plane_angle_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::solid_angle_base_dimension,bu::si::system_tag,bu::si::system_tag>::value == true));

    //// cgs->cgs always true
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::length_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::mass_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::time_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::current_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::temperature_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::amount_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::luminous_intensity_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::plane_angle_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::solid_angle_base_dimension,bu::cgs::system_tag,bu::cgs::system_tag>::value == true));

    //// si->cgs
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::length_base_dimension,bu::si::system_tag,bu::cgs::system_tag>::value == false));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::mass_base_dimension,bu::si::system_tag,bu::cgs::system_tag>::value == false));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::time_base_dimension,bu::si::system_tag,bu::cgs::system_tag>::value == true));
    
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::length,bu::cgs::length>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::mass,bu::cgs::mass>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::time,bu::cgs::time>::value == true));

    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::acceleration,bu::cgs::acceleration>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::area,bu::cgs::area>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::energy,bu::cgs::energy>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::force,bu::cgs::force>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::frequency,bu::cgs::frequency>::value == true));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::mass_density,bu::cgs::mass_density>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::momentum,bu::cgs::momentum>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::power,bu::cgs::power>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::pressure,bu::cgs::pressure>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::velocity,bu::cgs::velocity>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::si::wavenumber,bu::cgs::wavenumber>::value == false));
    
    //// cgs->si
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::length_base_dimension,bu::cgs::system_tag,bu::si::system_tag>::value == false));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::mass_base_dimension,bu::cgs::system_tag,bu::si::system_tag>::value == false));
    //BOOST_CHECK((bu::base_unit_is_implicitly_convertible<bu::time_base_dimension,bu::cgs::system_tag,bu::si::system_tag>::value == true));
              
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::length,bu::si::length>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::mass,bu::si::mass>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::time,bu::si::time>::value == true));

    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::acceleration,bu::si::acceleration>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::area,bu::si::area>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::energy,bu::si::energy>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::force,bu::si::force>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::frequency,bu::si::frequency>::value == true));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::mass_density,bu::si::mass_density>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::momentum,bu::si::momentum>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::power,bu::si::power>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::pressure,bu::si::pressure>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::velocity,bu::si::velocity>::value == false));
    BOOST_CHECK((bu::is_implicitly_convertible<bu::cgs::wavenumber,bu::si::wavenumber>::value == false));
    
    const bu::quantity<bu::si::time>    S1(2.0*bu::si::seconds);
    const bu::quantity<bu::cgs::time>   S2 = S1;

    BOOST_CHECK((S1.value() == S2.value()));
    
    const bu::quantity<bu::si::catalytic_activity>  S3(2.0*bu::si::catalytic_activity());
    
    
    const bu::quantity<bu::cgs::time>   C1(2.0*bu::cgs::seconds);
    const bu::quantity<bu::si::time>    C2 = C1;

    BOOST_CHECK((C1.value() == C2.value()));

    return 0;
}
Пример #8
0
boost::units::quantity<boost::units::si::length> CalculateSqrt(
  const boost::units::quantity<boost::units::si::length>& x)
{
  return CalculateSqrt(x.value()) * boost::units::si::meter;
}
 static double construct(const boost::units::quantity<Unit, T>& n) { return boost::numeric_cast<double>(n.value()); }
Пример #10
0
 static T value( const boost::units::quantity< Unit , T> &t )
 {
     return t.value();
 }
int test_main(int,char *[])
{
    // default constructor
    const bu::quantity<bu::dimensionless>           E1; 
    BOOST_CHECK(E1.value() == double());
    
    // value_type constructor
    const bu::quantity<bu::dimensionless>           E2(E_);
    BOOST_CHECK(E2.value() == E_);

    // copy constructor
    const bu::quantity<bu::dimensionless>           E3(E2);
    BOOST_CHECK(E3.value() == E_);

    // operator=
    const bu::quantity<bu::dimensionless>           E4 = E2;
    BOOST_CHECK(E4.value() == E_);

    // implicit copy constructor value_type conversion
    const bu::quantity<bu::dimensionless,float>     E5(E2);
    BOOST_UNITS_CHECK_CLOSE(E5.value(), float(E_));

    const bu::quantity<bu::dimensionless,long>      E6(E2);
    BOOST_CHECK(E6.value() == long(E_));

    // implicit operator= value_type conversion
    // narrowing conversion disallowed
//    const bu::quantity<bu::dimensionless,float>     E7 = E2;
//    BOOST_UNITS_CHECK_CLOSE(E7.value(),float(E_));
    
    // narrowing conversion disallowed
//    const bu::quantity<bu::dimensionless,long>      E8 = E2;
//    BOOST_CHECK(E8.value() == long(E_));
    
    // const construction
    bu::quantity<bu::dimensionless>                 E9(E2); 
    BOOST_CHECK(E9.value() == E_);
    
//    // value assignment
//    E9.value() = 1.5*bu::dimensionless();
//    BOOST_CHECK(E9.value() == 1.5);
//    
//    // value assignment with implicit conversion
//    E9.value() = 1.5;
//    BOOST_CHECK(E9.value() == 1.5);
//    
//    // value assignment with implicit value_type conversion
//    E9.value() = 2*bu::dimensionless();
//    BOOST_CHECK(E9.value() == double(2));
//
//    // value assignment with implicit value_type conversion
//    E9.value() = 2;
//    BOOST_CHECK(E9.value() == double(2));
    
    // operator+=(this_type)
    E9 = 2.0;
    E9 += E9;
    BOOST_CHECK(E9.value() == 4.0);
    
    // operator-=(this_type)
    E9 = 2.0;
    E9 -= E9;
    BOOST_CHECK(E9.value() == 0.0);
    
    // operator*=(value_type)
    E9 = 2.0;
    E9 *= 2.0;
    BOOST_CHECK(E9.value() == 4.0);
    
    // operator/=(value_type)
    E9 = 2.0;
    E9 /= 2.0;
    BOOST_CHECK(E9.value() == 1.0);
    
    // static construct quantity from value_type
    const bu::quantity<bu::dimensionless>           E(bu::quantity<bu::dimensionless>::from_value(2.5));
    BOOST_CHECK(E.value() == 2.5);
    
    // implicit conversion to value_type
    const double    V1(E9);
    BOOST_CHECK(V1 == E9.value());
    
    const double    V2 = E9;
    BOOST_CHECK(V2 == E9.value());
            
    // unit * scalar
    BOOST_CHECK(bu::dimensionless()*2.0 == bu::quantity<bu::dimensionless>::from_value(2.0));
    
    // unit / scalar
    BOOST_CHECK(bu::dimensionless()/2.0 == bu::quantity<bu::dimensionless>::from_value(0.5));
    
    // scalar * unit
    BOOST_CHECK(2.0*bu::dimensionless() == bu::quantity<bu::dimensionless>::from_value(2.0));
    
    // scalar / unit
    BOOST_CHECK(2.0/bu::dimensionless() == bu::quantity<bu::dimensionless>::from_value(2.0));

    //  quantity * scalar
    BOOST_CHECK(E*2.0 == bu::quantity<bu::dimensionless>::from_value(5.0));

    //  quantity / scalar
    BOOST_CHECK(E/2.0 == bu::quantity<bu::dimensionless>::from_value(1.25));
    
    // scalar * quantity
    BOOST_CHECK(2.0*E == bu::quantity<bu::dimensionless>::from_value(5.0));

    // scalar / quantity
    BOOST_CHECK(2.0/E == bu::quantity<bu::dimensionless>::from_value(0.8));

    const bu::quantity<bu::dimensionless>       D1(1.0),
                                                D2(2.0);
    
    // unit * quantity
    BOOST_CHECK(bu::dimensionless()*D1 == D1);
    
    // unit / quantity
    BOOST_CHECK(bu::dimensionless()/D1 == D1);
    
    // quantity * unit
    BOOST_CHECK(D1*bu::dimensionless() == D1);
    
    // quantity / unit
    BOOST_CHECK(D1*bu::dimensionless() == D1);
    
    // +quantity
    BOOST_CHECK(+D1 == 1.0*bu::dimensionless());
    
    // -quantity
    BOOST_CHECK(-D1 == -1.0*bu::dimensionless());
    
    // quantity + quantity
    BOOST_CHECK(D2+D1 == 3.0*bu::dimensionless());
    
    // quantity - quantity
    BOOST_CHECK(D2-D1 == 1.0*bu::dimensionless());
    
    // quantity * quantity
    BOOST_CHECK(D1*D2 == 2.0*bu::dimensionless());
    
    // quantity / quantity
    BOOST_CHECK(D2/D1 == 2.0*bu::dimensionless());
    
    // integer power of quantity
    BOOST_CHECK(2.0*bu::pow<2>(D2) == 2.0*std::pow(2.0,2.0)*bu::dimensionless());
    
    // rational power of quantity
    BOOST_CHECK((2.0*bu::pow< bu::static_rational<2,3> >(D2) == 2.0*std::pow(2.0,2.0/3.0)*bu::dimensionless()));
    
    // integer root of quantity
    BOOST_CHECK(2.0*bu::root<2>(D2) == 2.0*std::pow(2.0,1.0/2.0)*bu::dimensionless());
    
    // rational root of quantity
    BOOST_CHECK((2.0*bu::root< bu::static_rational<3,2> >(D2) == 2.0*std::pow(2.0,2.0/3.0)*bu::dimensionless()));
    
    const bu::quantity<bu::dimensionless>   A1(0.0),
                                            A2(0.0),
                                            A3(1.0),
                                            A4(-1.0);
                                    
    // operator==
    BOOST_CHECK((A1 == A2) == true);
    BOOST_CHECK((A1 == A3) == false);
    
    // operator!=
    BOOST_CHECK((A1 != A2) == false);
    BOOST_CHECK((A1 != A3) == true);
    
    // operator<
    BOOST_CHECK((A1 < A2) == false);
    BOOST_CHECK((A1 < A3) == true);
    
    // operator<=
    BOOST_CHECK((A1 <= A2) == true);
    BOOST_CHECK((A1 <= A3) == true);
    
    // operator>
    BOOST_CHECK((A1 > A2) == false);
    BOOST_CHECK((A1 > A4) == true);
    
    // operator>=
    BOOST_CHECK((A1 >= A2) == true);
    BOOST_CHECK((A1 >= A4) == true);
    
    return 0;
}