I have aliases for radians and degrees that use float as the storage type.
When I convert between these two units I see the assembly promote the values to doubles and then back to floats when doing conversions.
Q: How can I make sure that all operations and conversions stay in floats?
My Code:
using radians_f = boost::units::quantity<boost::units::si::plane_angle, float>;
using degrees_f = boost::units::quantity<boost::units::degree::plane_angle, float>;
degrees_f to_degrees(const radians_f& angle) { return static_cast<degrees_f>(angle); }
radians_f to_radians(const degrees_f& angle) { return static_cast<radians_f>(angle); }
From compiler explorer I see the following assembly instructions: https://godbolt.org/z/Gnjr54dn6
cvtss2sd - Converts a single-precision floating-point value in the “convert-from” source operand to a double-precision floating-point value in the destination operand.
mulsd - Multiplies the low double-precision floating-point value in the second source operand by the low double-precision floating-point value in the first source operand.
cvtsd2ss - Converts a double-precision floating-point value in the “convert-from” source operand to a single-precision floating-point value
PS: I would not be surprised if I have defined my aliases or/and my conversion functions incorrectly.
I found a hacky workaround (which I'm sure can be "productionized" by making Boost Units compute the 57.x degrees per radian constant) to avoid the conversions to and from
double, but it really highlights the fact that Boost Units is causing another surprising sort of overhead: memory loads and stores which aren't necessary if you usefloatdirectly, or even your own wrapper forfloat.Demo: https://godbolt.org/z/afPE7baxT
So while the above shows one (unrefined) way to force calculations to stay as floats, if your real question is "How do I avoid overhead" you're still a bit far from nirvana.