
I have a program in which there is the notion of consumption rate such as m^3/sec, gallons/hour, etc. I have consumption_rate unit defined in terms of si units. I read in a quanity in gallons/hour and so far so good. If I display the quantity it is displayed as m^3/sec. This displays the "compound units" as expected - very cool. All this is OK as far as it goes. When I try to display the quantity as gallons/hour again I have a whole host of problems. The attached test fill illustrates the issues. The only way I've been able to do is is by making a complete end run around the units system itself - sort of self defeating. I would appreciate insight anyone might be able to offer into this issue. Robert Ramey begin 666 test_units.cpp M#0HC:6YC;'5D92 \:6]S=')E86T^#0H-"B-I;F-L=61E(#QB;V]S="]U;FET M<R]I;RYH<' ^#0HC:6YC;'5D92 \8F]O<W0O=6YI=',O<&]W+FAP<#X-"B\O M(VEN8VQU9&4@/&)O;W-T+W5N:71S+V1E=&%I;"]U=&EL:71Y+FAP<#X-"B-I M;F-L=61E(#QB;V]S="]U;FET<R]S>7-T96US+V-G<RYH<' ^#0HC:6YC;'5D M92 \8F]O<W0O=6YI=',O<WES=&5M<R]S:2YH<' ^#0HC:6YC;'5D92 \8F]O M<W0O=6YI=',O<WES=&5M<R]S:2]I;RYH<' ^#0H-"B-I;F-L=61E(#QB;V]S M="]U;FET<R]B87-E7W5N:71S+VUE=')I8R]H;W5R+FAP<#X-"@T*=7-I;F<@ M;F%M97-P86-E(&)O;W-T.CIU;FET<SL-"@T*+R\@9&5R:79E('-P96-I86P@ M=6YI=',@=&AA="!W92!U<V4@:6X@;W5R(&%P<&QI8V%T:6]N#0HO+R!D97)I M=F5D(&1I;65N<VEO;B!F;W(@8V]N<W5M<'1I;VY?<F%T92 Z($T@5%XM,0T* M='EP961E9B!B;V]S=#HZ=6YI=',Z.F1E<FEV961?9&EM96YS:6]N/ T*(" @ M(&)O;W-T.CIU;FET<SHZ;&5N9W1H7V)A<V5?9&EM96YS:6]N+#,L#0H@(" @ M8F]O<W0Z.G5N:71S.CIT:6UE7V)A<V5?9&EM96YS:6]N+"TQ#0H^.CIT>7!E M(&-O;G-U;7!T:6]N7W)A=&5?9&EM96YS:6]N.R @(" @(" @(" @(" @(" - M"@T*='EP961E9B!B;V]S=#HZ=6YI=',Z.G5N:70\#0H@(" @8V]N<W5M<'1I M;VY?<F%T95]D:6UE;G-I;VXL#0H@(" @8F]O<W0Z.G5N:71S.CIS:3HZ<WES M=&5M#0H^(&-O;G-U;7!T:6]N7W)A=&5?=6YI=#L-"G1Y<&5D968@8F]O<W0Z M.G5N:71S.CIQ=6%N=&ET>3QC;VYS=6UP=&EO;E]R871E7W5N:70L(&9L;V%T M/B!C;VYS=6UP=&EO;E]R871E.PT*#0HC:6YC;'5D92 \8F]O<W0O=6YI=',O M8F%S95]U;FET<R]U<R]G86QL;VXN:'!P/@T*='EP961E9B!B;V]S=#HZ=6YI M=',Z.G5S.CIG86QL;VY?8F%S95]U;FET.CIU;FET7W1Y<&4@9V%L;&]N7W5N M:70[#0I"3T]35%]53DE44U]35$%424-?0T].4U1!3E0H9V%L;&]N+"!G86QL M;VY?=6YI="D[(" @( T*0D]/4U1?54Y)5%-?4U1!5$E#7T-/3E-404Y4*&=A M;&QO;G,L(&=A;&QO;E]U;FET*3L@(" @#0H-"B-I;F-L=61E(#QB;V]S="]U M;FET<R]B87-E7W5N:71S+VUE=')I8R]H;W5R+FAP<#X-"G1Y<&5D968@8F]O M<W0Z.G5N:71S.CIM971R:6,Z.FAO=7)?8F%S95]U;FET.CIU;FET7W1Y<&4@ M:&]U<E]U;FET.PT*0D]/4U1?54Y)5%-?4U1!5$E#7T-/3E-404Y4*&AO=7)S M+"!H;W5R7W5N:70I.PT*0D]/4U1?54Y)5%-?4U1!5$E#7T-/3E-404Y4*&AO M=7(L(&AO=7)?=6YI="D[(" @( T*#0II;G0@;6%I;B@I#0I[#0H@(" @<75A M;G1I='D\8V]N<W5M<'1I;VY?<F%T95]U;FET/B @0R@Q+C @*B!G86QL;VX@ M+R!H;W5R*3L-"@T*(" @('-T9#HZ8V]U=" \/" Q+C @*B!G86QL;VYS("\@ M:&]U<B \/" B("T@;VL@9&ES<&QA>7,@9V%L+VAO=7(B(#P\('-T9#HZ96YD M;" [#0H@(" @<W1D.CIC;W5T(#P\($,@/#P@(B M(&]K/R!D:7-P;&%Y<R!M M,R]S96,B(#P\('-T9#HZ96YD;" [#0H@(" @<W1D.CIC;W5T(#P\($,@*B!G M86QL;VYS("\@:&]U<B \/" B("T@;F]T(&]K("T@22!M:6=H="!B=7D@=&AI M<R(@/#P@<W1D.CIE;F1L(#L-"B @("!S=&0Z.F-O=70@/#P@0R O("AG86QL M;VYS("\@:&]U<BD@/#P@(B M(&)U="!T:&5N('1H:7,@<VAO=6QD('=O<FLA M(B \/"!S=&0Z.F5N9&P@.PT*#0H@(" @<W1D.CIC;W5T(#P\($,N=F%L=64H M*2 O("AG86QL;VYS("\@:&]U<BD@/#P@(B M(&1I<W!L87ES(&@O9R M3TL_ M(&)U="!U;F5X<&5C=&5D('9A;'5E("$@*&5X<&5C=&5D(#$N,"D@(CP\('-T M9#HZ96YD;" [#0H@(" @+R\@<W1D.CIC;W5T/#P@0RYV86QU92@I("\@*&=A M;&QO;G,@+R!H;W5R*2YV86QU92@I(#P\("(@+2!D:7-P;&%Y<R!H+V<@+4]+ M/R!B=70@=6YE>'!E8W1E9"!V86QU92 A("AE>'!E8W1E9" Q+C I("(\/"!S M=&0Z.F5N9&P@.PT*(" @('-T9#HZ8V]U=" \/"!#+G9A;'5E*"D@+R H*#$N M," J(&=A;&QO;G,I("\@*#$N," J(&AO=7(I*2YV86QU92@I(#P\("(@+2!U M;F5X<&5C=&5D('9A;'5E("$@*&5X<&5C=&5D(#$N,"D@(CP\('-T9#HZ96YD M;" [#0H@(" @<W1D.CIC;W5T(#P\($,N=F%L=64H*2 O("@H,2XP("H@9V%L M;&]N<RDN=F%L=64H*2 O("@Q+C @*B!H;W5R*2YV86QU92@I*2 \/" B("T@ M=6YE>'!E8W1E9"!V86QU92 A("AE>'!E8W1E9" Q+C I("(\/"!S=&0Z.F5N M9&P@.PT*#0H@(" @9FQO870@9R ]("@Q+C @*B!G86QL;VYS*2YV86QU92@I M.PT*(" @('-T9#HZ8V]U=" \/"!G(#P\('-T9#HZ96YD;#L-"B @("!F;&]A M="!H(#T@*#$N," J(&AO=7(I+G9A;'5E*"D[#0H@(" @<W1D.CIC;W5T(#P\ M(&@@/#P@<W1D.CIE;F1L.PT*(" @(&9L;V%T('(@/2!#+G9A;'5E*"D@+R H M9R O(&@I.PT*(" @('-T9#HZ8V]U=" \/"!R("H@9V%L;&]N<R O(&AO=7(@ M/#P@(B M(&9I;F%L;'DA('1H92!C;W)R96-T(')E<W5L="$B(#P\('-T9#HZ M96YD;#L-"@T*(" @('-T9#HZ8V]U=" \/"!S=&0Z.F5N9&P[#0H@(" @#0H@ M(" @<75A;G1I='D\<VDZ.F%R96$^(" @(" @02@Q+C4J<VDZ.FUE=&5R*F-G M<SHZ8V5N=&EM971E<BD[#0H@(" @#0H@(" @<W1D.CIC;W5T(#P\(#$N-2IS M:3HZ;65T97(J8V=S.CIC96YT:6UE=&5R(#P\('-T9#HZ96YD; T*(" @(" @ M(" @(" @(" \/"!!(#P\('-T9#HZ96YD; T*(" @(" @(" @(" @(" \/"!S A=&0Z.F5N9&P[#0H-"B @("!R971U<FX@,#L-"GT-"@T* ` end

Hi Robert, Robert Ramey wrote:
I have a program in which there is the notion of consumption rate such as m^3/sec, gallons/hour, etc.
I have consumption_rate unit defined in terms of si units. I read in a quanity in gallons/hour and so far so good. If I display the quantity it is displayed as m^3/sec. This displays the "compound units" as expected - very cool. All this is OK as far as it goes. When I try to display the quantity as gallons/hour again I have a whole host of problems. The attached test fill illustrates the issues. The only way I've been able to do is is by making a complete end run around the units system itself - sort of self defeating.
I would appreciate insight anyone might be able to offer into this issue.
It's a little confusing, but it's printing in the si units because consumption_rate_unit is generated from the si::system. You can create your own system with volume and time and create the consumption rate from it. The following shows how: #include <iostream> #include <boost/units/io.hpp> #include <boost/units/pow.hpp> #include <boost/units/systems/cgs.hpp> #include <boost/units/systems/si.hpp> #include <boost/units/systems/si/io.hpp> #include <boost/units/base_units/metric/hour.hpp> #include <boost/units/base_units/us/gallon.hpp> using namespace boost::units; // derive special units that we use in our application // derived dimension for consumption_rate : M T^-1 typedef boost::units::derived_dimension< boost::units::length_base_dimension,3, boost::units::time_base_dimension,-1
::type consumption_rate_dimension;
typedef boost::units::make_system<us::gallon_base_unit, metric::hour_base_unit>::type consumption_system; typedef unit< consumption_rate_dimension, consumption_system
consumption_rate_unit;
typedef quantity<consumption_rate_unit, float> consumption_rate; typedef unit<volume_dimension, consumption_system> gallon_unit; BOOST_UNITS_STATIC_CONSTANT(gallon, gallon_unit); BOOST_UNITS_STATIC_CONSTANT(gallons, gallon_unit); typedef unit<time_dimension, consumption_system> hour_unit; BOOST_UNITS_STATIC_CONSTANT(hours, hour_unit); BOOST_UNITS_STATIC_CONSTANT(hour, hour_unit); int main() { quantity<consumption_rate_unit> C(1.0 * gallon / hour); std::cout << 1.0 * gallons / hour << " - ok displays gal/hour" << std::endl; std::cout << C << " - ok displays gal/hour" << std::endl ; return 0; } HTH, Nate

Nathan Crookston wrote:
Hi Robert,
It's a little confusing
it refers to my test case or the units library?
but it's printing in the si units because consumption_rate_unit is generated from the si::system. You can create your own system with volume and time and create the consumption rate from it. The following shows how:
... thanks for this i appreciate you'r going to this effort. ...
typedef boost::units::make_system<us::gallon_base_unit, metric::hour_base_unit>::type consumption_system;
I concede that I don't get the "system" concept. It's hardly mentioned in the documentation. I sort of had the feeling that all the units had to be part of the same "system" in order to automatically converted.
typedef unit< consumption_rate_dimension, consumption_system
consumption_rate_unit;
typedef quantity<consumption_rate_unit, float> consumption_rate;
hmmm - so this doesn't use the header ? #include <boost/units/base_units/us/gallon.hpp>
typedef unit<volume_dimension, consumption_system> gallon_unit; BOOST_UNITS_STATIC_CONSTANT(gallon, gallon_unit); BOOST_UNITS_STATIC_CONSTANT(gallons, gallon_unit);
typedef unit<time_dimension, consumption_system> hour_unit; BOOST_UNITS_STATIC_CONSTANT(hours, hour_unit); BOOST_UNITS_STATIC_CONSTANT(hour, hour_unit);
int main() { quantity<consumption_rate_unit> C(1.0 * gallon / hour);
std::cout << 1.0 * gallons / hour << " - ok displays gal/hour" << std::endl; std::cout << C << " - ok displays gal/hour" << std::endl ;
return 0; }
OK - but now how would I output in meters^3/second ? It seems that the output is coupled to the way the unit is setup. I would have expected that the format of the output display could be delayed until the actual output operation is performed - just like i can on input. that is, Since I can do (using si) consumption_rate cr = static_cast<consumption_rate>( 24.0 * gallons / hour) I expect to be able to do some similar operation equivalent to static_cast<gallons/hour>(r) - OK I suppose that some sort of symetical operation is not implementable. But on the other hand, the following does work cout << 24.0 gallons / hour. Thanks for your help. Robert Ramey

On Sun, Sep 22, 2013 at 12:38 AM, Robert Ramey <ramey@rrsd.com> wrote:
Nathan Crookston wrote:
Hi Robert,
It's a little confusing
it refers to my test case or the units library?
"It" being the units library -- specifically how systems relate to the unit and quantity and determines what's printed.
I concede that I don't get the "system" concept. It's hardly mentioned in the documentation. I sort of had the feeling that all the units had to be part of the same "system" in order to automatically converted.
Yeah, I didn't really get it (I still might not completely get it), but generally conversions are defined in terms of base_units. When you want to store a value as a particular type (as opposed to converting to si units, for example), you need to have a system which can represent that particular type.
hmmm - so this doesn't use the header ? #include <boost/units/base_units/us/gallon.hpp>
It does, I just moved it up where it could be used by the make_system metafunction.
OK - but now how would I output in meters^3/second ? It seems that the output is coupled to the way the unit is setup. I would have expected that the format of the output display could be delayed until the actual output operation is performed - just like i can on input.
To display in si, you can do what you did before -- create a consumption_rate_unit based on the si system -- perhaps you could have a us_consumption_rate and an si_consumption_rate_unit. Usage could be something like: cout << static_cast<quantity<si_consumption_rate_unit,float> >(value /* type quantity<us_consumption_rate,float> */); HTH, Nate
participants (2)
-
Nathan Crookston
-
Robert Ramey