# Boost Users :

Subject: Re: [Boost-users] [units] Conversions from quantities
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2015-08-12 21:17:58

On 13/08/2015 10:39, Michael Powell wrote:
> Just wanted to clarify something. These should convert from given
> quantities to the desired units?
>
> double
> unit_conversion::from_length_to_inches(quantity<length> const & L) {
> const quantity<inch_base_unit::unit_type> result_(L);
> return result_.value();
> }
>
> double unit_conversion::from_mass_to_pounds(quantity<mass>
> const & M) {
> const quantity<ounce_base_unit::unit_type> result_(M);
> return result_.value();
> }
>
> From an earlier post, I think maybe so, but I was interested in expert
> opinions, as well.

Conversion between related dimensions is basically automatic:

typedef inch_base_unit::unit_type inch_unit;
BOOST_UNITS_STATIC_CONSTANT(inches, inch_unit);

You can then express quantities in those types as you'd expect:

quantity<length> a(24.5 * milli * meters);
quantity<inch_unit> b(18.0 * inches);
quantity<inch_unit> c(a);
quantity<length> d(16.5 * inches);

Once you have a quantity<U>, you can use value() to extract the raw
number, as you've done above. Another way to do it (which is a little
more "correct", albeit at times more painful) is to convert it to a
dimensionless value first -- dimensionless values can be implicitly cast
to the base type (typically double). eg:

double to_mm(quantity<length> const& L)
{
const quantity<dimensionless> result(a / milli / meters);
return result;
}

double to_inches(quantity<length> const& L)
{
const quantity<inch_unit> result(L);
return result / inches;
}

to_mm(a);
to_mm(b);
to_mm(0.54 * meters);
to_mm(quantity<length>(51.2 * milli * meters));
to_mm(quantity<length>(16.5 * inches));
to_inches(a);
to_inches(b);
to_inches(0.54 * meters);
to_inches(quantity<length>(16.5 * inches));

Note that due to the scaled units quirks, you do have to have the
intermediate dimensionless variable in to_mm to force it to do the
conversion. If it were to_m instead then you wouldn't.

If you're working with inches/pounds/etc a lot, you might want to
consider making a system for them (similar to SI vs. CGS in the examples).

Regardless, converting to a raw value should be done at the last
possible moment, when you're outputting to some external code that
doesn't understand Boost.Units. Within your own code you should always
keep the unit attached, to reduce errors.