Boost logo

Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2003-10-26 12:17:12

A couple of other issues that have arisen :

        1) the integer conversion question (I have implemented unit conversion
using the
                left hand rule in my library so LHS op RHS -> LHS. There are two
potential problems
                with this approach : first, if the ultimate unit type desired is that
of the RHS,
                there is the potential for two conversions (from RHS to LHS then back
again), with
                accompanying precision issues (though if you're operating at or near
the precision limit
                you probably will get what you deserve regardless...). Second, the
integer problem
                raised in an earlier post : int(2)*_meters + int(5)*_centimeters
would give 2m while
                the reverse would give 205cm. While there are good reasons to not
allow integers as
                value_type for dimensioned quantities (in conversions between, e.g.
SI and natural units
                there are very large exponents which far exceed the range of any
current or planned integer
                type, it is probably worthwhile considering whether implicit unit
conversion should be
                disallowed. The added ugliness is probably a good thing, as in
C++-style casting :

                        CGS<float>::Length L1 = 5*_centimeters;
                        SI<float>::Length L2 = 2*_meters + SI<float>::Length(L1);

                Expression templates were suggested as a possible solution to this
question. I see two
                problems with this solution : first, it doesn't solve the issue of
limited integer precision
                discussed above. Second, if all internal calculations are forced to
long double, we are
                forcing more precision than may be necessary or desired and at the
same time preventing the
                use of class value_types which have higher precision (like a quad
precision double or BCD value).

        2) comparison operators also may have problems with unit conversions
due to numeric precision issues.
                It is probably best to prohibit implicit unit conversions for this
reason as well.

        As a further demonstration, I've written a quick-n-dirty Measurement
class which encapsulates both
        values and errors, along with standard error propagation for basic
arithmetic operations. Its use
        in conjunction with the units library is shown in in
the files section on yahoo.

> Since the main non-SI requirements are for subatomic particle physics,
> astronomy, and Imperial/US, these would be very useful demos.

        It's just a matter of coming up with the conversion factors between
the relevant units and SI - I guess I'd rather not spend a tremendous
        of time assembling obscure units and unit systems until there's some
clear consensus on the direction, if any, the boost::units library will

> What about radians, and trig functions etc?

        As has been noted (also see, angles and solid angles
are technically dimensionless,
        representing the ratio between a length along a circle and its
perimeter and an area on a sphere and it's total area. It would
        be possible to add two more template parameters to the list of
dimensions in class Dimension to represent these. However, I'm
        concerned that trying to accommodate arbitrary conversions between any
units of measure for anything may become too complex -
        for example, currency conversions would require historical databases
of exchange rates at any instant and would depend on the
        time of the conversion.

        I think the idea of implementing the Dimension class as a some sort of
MPL list is a good one, as it allows extensibility with an arbitrary
        list of tags. I discuss some possibilities in the README included
with my implementation of the library.

> Log scales like dB are also widely used - have you any ideas about
> dealing with
> these, if 'far out'.

        The problem with nonlinear units is that, in order to support them in
a general way you would need to have an arbitrary system of
        arithmetic for the basic operations which depends on the specific
unit. For example, it is unclear how to multiply two dB measurements
        since they are relative power units... What should the result of
10dB*25dB be? 250 dB^2? Again, using an extensible MPL list this
        could be done formally, assuming the library wasn't required to do
anything fancy arithmetically...

        For example,

                struct TV // tagged value
                        typedef Tag tag_type;
                        typedef Value value_type;

                struct length_tag { };
                struct time_tag { };
                struct angle_tag { };

                DimList<TV<length_tag,1>,TV<time_tag,2> > // m s^2 (in SI)
                DimList<TV<time_tag,-1>,TV<angle_tag,1> > // rad s^-1 (in SI)

                // multiplying these two dimensions would give
                DimList<TV<length_tag,1>,TV<time_tag,1>,TV<angle_tag,1> > // m
s rad

        If this was done, there could be a set of seven (or nine) standard
tags :


        reserved for use for physical quantities. Other quantities could be
added by users. Then, the
        unit model could define templates for unit names and conversions
supporting the tag set desired.

                tagSymbol<tag_type> in place of dimensionXSymbol() now used
                tagToBase<tag_type> in place of dimensionXToBase() now used

        It looks to me like we need an MPL guru to volunteer some help here...


Matthias Schabel, Ph.D.
Utah Center for Advanced Imaging Research
729 Arapeen Drive
Salt Lake City, UT 84108
801-587-9413 (work)
801-585-3592 (fax)
801-706-5760 (cell)
801-484-0811 (home)
mschabel at ucair med utah edu

Boost list run by bdawes at, gregod at, cpdaniel at, john at