Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2003-11-06 00:03:04

Hi ,

    In the previous debate about Physical Quantities,
    An interesting question that came up was
 What should the resulting units of a calculation between two different
types of units be?

I came to the conclusion that the best algorithm is the one that preserves

// "add_units_t" a metafunction to
// select the units giving best accuracy in addition...
// in addition both powers are the same
// but units can vary.
// here the most_granular units are selected if Power > 0
// the least granular if Power < 0
// if Power == 0 units are "dont care"

        template<int Power,int UnitA,int UnitB>
        struct add_units_t{
            typedef typename boost::mpl::if_c
            < Power,
                  typename boost::mpl::if_c
                  < ( Power > 0 ),
                       typename most_granular_units_t<UnitA,UnitB> ::type,
                       typename least_granular_units_t<UnitA,UnitB> ::type
> ::type,
> ::type type;

// which gives the following output:

1001 mm
1001 mm
60001 mm.minutes-1
60001 mm.minutes-1

from the code below:

using namespace physical_quantities;
int main()
    pq_length<double>::m L1(1.0L); //metres
    pq_length<double>::mm L2(1.0L); //millimetres

    std::cout << L1 + L2 <<'\n'; // ---> 1001 mm
    std::cout << L2 + L1 <<'\n'; // ---> 1001 mm

    pq_velocity<int>::mm_per_minute V1(1); //millimetres per minute
    pq_velocity<int>::m_per_s V2(1); // metres per second

    std::cout << V1 + V2 <<'\n';
                           //---> 60001 mm.minutes-1 .... Think about it
    std::cout << V2 + V1 <<'\n';
                         //---> .60001 mm.minutes-1
    return 0;

It may not be entirely intuitive but it is the best way to preserve accuracy
especially when using ints as in second example.

Well I better check it runs on Gcc and then hopefully I shall be able to put
what I
have up in the boost "backroom"
within the week

Andy Little

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