[units] Dimensionless? expecting length+length

Hello,
I am working on some trajectory calculations, and having a strange
compiler error. First, great that I should get a compiler error at
all! Second, what am I missing?
quantity<acceleration> g() {
static const auto gValue = static_cast<double>(9.812);
static const auto metersPerSecondPerSecond = meters / second / second;
static const quantity<acceleration> g = gValue*metersPerSecondPerSecond;
return g;
}
double Class1::CalculateZeta(double timeMilliseconds, double heightMeters) {
static const auto two = static_cast<double>(2);
static const auto milliseconds = milli*seconds;
const auto t = timeMilliseconds*milliseconds;
const auto h = heightMeters*meters;
const auto g_ = g();
auto result = -(g_ / two)*(t*t) + h;
return result.value();
}
Just if I did the dimensional analysis, I might expect the time
components (i.e. T^2) to cancel themselves out, which should leave me
with length+length, no?
This is exposed via a C++ CLR (VS2013), but the Boost.Units are done internally.
What am I missing here? I need to normalize the units, say to meters, etc?
Best regards,
Michael Powell
Errors:
Error 4 error C2676: binary '+' :
'boost::units::quantity

On 9/08/2015 10:27, Michael Powell wrote:
I believe this is the "problem" here -- there's a scale of 10^-6 applied, presumably as a result of multiplying with milliseconds twice. I've encountered issues before where some of the operators don't play nicely with scaled units. Try normalising the milliseconds to seconds before putting them in the rest of the formula. You should be able to do this simply by assigning them to a seconds quantity type instead of using "auto".

On Sun, Aug 9, 2015 at 7:40 PM, Gavin Lambert
Sure.
I'm not sure what you mean, "seconds quantity type"? There would be quantity<time> ? Which one can assign from (time_value * seconds), to arrive at seconds? It is possible to build up a milliseconds unit, or possible a milliseconds_to_seconds "conversion factor" ?

On 11/08/2015 01:43, Michael Powell wrote:
Yes. I have this: typedef quantity<time> Time; And explicitly use "Time" as the type for all time-related results instead of using "auto".
You can, but it's not necessary. Simply assign value * milli * seconds to a variable of quantity<time> (aka Time) and it automatically converts everything to seconds (since that's the base unit of "time"). This prevents other operations getting confused by scaled units, which happens when you use "auto" because it skips this conversion.

On 11/08/2015 14:12, Michael wrote:
I'm not sure about "prevailing wisdom". I don't use auto anywhere with Boost.Units (I use explicit types as mentioned above instead). But then, most of my usage of Boost.Units was written in the dark ages (C++03 compiler). TBH your code seems a little too auto-happy to me -- I wouldn't have defined things like "two" or "milliseconds" or "gValue" or the static_casts and would have just written the values inline instead, as I think it's sufficiently clear that way. But that's just a coding style thing (the compiler should be smart enough to generate the same code either way) and if you think that makes it clearer for you then go for it. That's probably a more reasonable place to use "auto", for things that aren't quantities.

On Mon, Aug 10, 2015 at 10:50 PM, Gavin Lambert
No problem. Thanks for the critique anyhow. It's an early prototype, just pulling some concepts together. I'll likely rewrite it 2-3 times anyway, before it's all said and done. I'm already capturing "calculator" concerns such as "e" and "g" as true-quantity constants in a calculator structure, for example. I'm finding that helps add clarity to the code, as well. Still, I like auto when it makes sense; kind of like C# var.
participants (3)
-
Gavin Lambert
-
Michael
-
Michael Powell