如何让boost::units的单位转换与运算全程保持单精度float类型?
问题原因
Boost.Units库内置的角度单位转换系数默认定义为double类型,当float类型的单位值参与转换计算时,C++的隐式类型提升规则会先把float值提升为double完成乘法,再转换回float,这就是你观察到cvtss2sd、mulsd、cvtsd2ss指令的原因,和你的别名、转换函数写法无关。
解决方案
要让全程用float计算,只需要让转换系数也用float类型即可,有两种可选方案:
方案1:全局指定转换系数精度
在包含Boost.Units相关头文件之前先定义宏,强制所有单位转换系数使用float类型:
#define BOOST_UNITS_REAL_TYPE float #include <boost/units/systems/si/plane_angle.hpp> #include <boost/units/systems/angle/degrees.hpp> 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); }
这个宏会全局替换库内的转换系数类型为float,之后所有的单位转换都会直接用float运算,不会再触发类型提升。
方案2:自定义float精度转换逻辑(无全局影响)
如果不想修改全局配置影响其他单位的转换精度,可以手动写转换函数,直接用float精度的π值计算,绕过库内置的转换逻辑:
constexpr float PI_F = 3.141592653589793f; degrees_f to_degrees(const radians_f& angle) { return degrees_f(angle.value() * 180.0f / PI_F); } radians_f to_radians(const degrees_f& angle) { return radians_f(angle.value() * PI_F / 180.0f); }
这种方法生成的汇编会直接用mulss指令做单精度乘法,完全没有双精度转换的开销。
内容的提问来源于stack exchange,提问作者CJCombrink
相关产品推荐
相关产品推荐

