|
Boost : |
From: Andy Little (andy_at_[hidden])
Date: 2006-06-22 19:59:24
"Beth Jacobson" wrote
[...]
> Under/overflow will certainly be an issue for some people if they can't
> specify their own base units, but I don't know if a tight coupling
> between units and dimensions is the best solution. Could there be
> some sort of global setting (a facet, maybe?) where we could specify
> units for base dimensions for the entire application?
The quantity containers and unit typedefs can be easily customised by the user
to whatever they prefer:
namespace my{
typedef boost::pqs::length::mm distance;
typedef boost::pqs::time::s time;
typedef boost::pqs::velocity::mm_div_s velocity;
}
void f()
{
my:::velocity v = my::distance(1) / my_time(1);
}
[...]
> Another example would be something like this (excuse the psuedo-pqs):
No problem..... ;-)
> pqs::pressure::psi WaterPressure(pqs::length::feet depth)
> {
> const pqs::length_per_pressure::foot_per_psi pressureRatio(2.31);
> return depth/pressureRatio;
> }
>
> If units weren't specified in the function declaration, it could be
> called with the wrong ones, and its return value would be garbage.
>
> Both your example and mine have a common element though. They both
> involve moving between numeric values and dimensions. I can't think of
> an instance where units would be useful when that isn't the case. If
> that's true, then it seems like overkill to require bound units
> throughout the program. A simpler solution would be to prohibit
> dimension variables from being assigned or returning "raw" numbers. The
> only way to get or set a value would be through unit functions like this.
PQS quantities can't be converted to raw numbers.
double val = pqs::length::m(1) ;// Error
but a function is provided to get the numeric_value:
double val = pqs::length::m(1).numeric_value() ;// Ok
Its name is quite long so it's easy to spot in code.
> pqs::energy energyVal = pqs::kcal(value);
>
> My water pressure example would look like this
>
> pqs::pressure WaterPressure(pqs::length depth)
> {
> const pqs::length_per_pressure ratio(pqs::foot_per_psi(2.31));
> return depth/ratio;
> }
>
> The value, 2.31, would be converted to the global units, whatever they
> happened to be, so the function would work with any unit system. Since
> units would be specified at the point of conversion, this method might
> even be a little safer. In pqs, you might do something like this
>
> pqs::length::m depth;
>
> // lots of code
Its not possible to initialise a double from a quantity in PQS:
> double depthAsDouble(depth);
so the the above will not compile.
> SetFieldValue("DepthInFt", depthAsDouble);
>
> cout << "Enter new depth (in feet): "
> cin >> depth;
>
> Because depth is declared far from where it's output and reassigned,
> these mistakes would be easy to miss.
Not so for the above reason!
In PQS the units are part of the type. IOW the numeric value and its unit are
always tightly coupled in code. That is a powerful feature. Once the numeric
part of a quantity is disassociated from its unit then manual checking and
external documentation is required, which is often the current situation
wherever doubles are used to represent quantities. Manual checking doesnt always
work as well as intended... That of course is why the Mars lander crashed!
regards
Andy Little
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk