
Hi boost::units developers I am interested in extending the scale system for units. Here I present a short explanation, my initial hack to get this working, and questions on a small re-engineering issue that will crop up if this proposal is accepted. *** WHY *** Existing boost-units code allows scales which have factors as integral powers of a base, b^e, eg. 10^3, 2^10 etc. I'd like to use scales that have factors of the form a*b^e, Examples: (a) electron-Volt (eV) = 1.602*10^{-19} J (b) bohr = 0.528 Angstroms = 5.28*10^{-11} m In quantum chemistry, for example, such an "atomic units system" is typically used. *** HOW *** To achieve this using templates (which don't (yet) recognize floating point constants), I borrowed the idea from the 'dimnum' package. I, (1) added two more parameters of type long to the scale<> template which are the numerator and denominator of the rational approximation to a, (2) added static const value_type factor() member function which returns the value 'a' evaluated as double, (3) modified the value() static member to return factor() * b^e instead of simply b^e --------------- Code snippet (scale.hpp): template<long Base, class Exponent, long FactorNumerator=1L, long FactorDenominator=1L> struct scale { // ... static const double factor() { return double(FactorNumerator)/double(FactorDenominator); } static value_type value() { return(factor() * detail::static_rational_power<Exponent>(static_cast<double>(base))); } // ... }; ---------------- I modified the defintion of the apply<> template class in the boost::mpl::plus_impl, boost::mpl::negate_impl classes in unscale.hpp so that the scale<> return template-type now includes the correct FactorNumerator and FactorDenominator results based on the operands. This seems to be the place where arithmetic on scales is being performed for inter-conversion of quantities. I couldn't modify boost::mpl::times_impl because I'd have to statically exponentiate the numerator/denominator here and this doesn't fit cleanly into the existing mechanism. *** WHAT *** I do have the following questions/observations - please answer/comment. 1. The current implementation assumes that the scales being multiplied have the same base and differ only in the exponent? I just see T0::base being copied as the new base. This can be fixed with the generalized scale approach where if the bases are different (eg. 2 and 10), the resulting base is a default (10?) with exponent=static_rational<0,1> and a new factor f=(2^e1)*(10^e2). Of course, this will work only if there are no overflows. A conceivable use-case for this feature is when calculating, say, price-per-GB that is incurred in setting up a data-center. $<--->c interconversion will require 10^2 scale along the currency dimension while MB<--->GB<--->TB interconversions will require 2^10 scale along the memory dimension (assume they can be created). Here, currency interconversion will necessitate a generalized scale. 2. For simple scales like the existing one, multiplication of scales leads to addition of the exponents and therefore I can understand the static-overload of the plus_impl template to allow MPL to add the exponents. But with generalized scales we will have to switch to a different mechanism. Could you advise me on what all will need to be changed? I have a fair idea and I could use your input to cross-check. 3. When I complete this, can I submit the patch? I would like to add the atomic units system to the existing list of systems http://en.wikipedia.org/wiki/Atomic_units thanks, Manoj