作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我正在处理的应用程序,我需要取两个整数并使用特定的数学公式将它们相加。这最终看起来像这样:
int16_t add_special(int16_t a, int16_t b) {
float limit = std::numeric_limits<int16_t>::max();//32767 as a floating point value
float a_fl = a, b_fl = b;
float numerator = a_fl + b_fl;
float denominator = 1 + a_fl * b_fl / std::pow(limit, 2);
float final_value = numerator / denominator;
return static_cast<int16_t>(std::round(final_value));
}
任何对物理学有一定了解的读者都会认识到这个公式与用于计算近光速速度总和的公式相同,并且此处的计算有意反射(reflect)了该计算。
编写的代码给出了我需要的结果:对于小数,它们几乎正常相加,但对于大数,它们收敛到最大值 32767,即
add_special(10, 15) == 25
add_special(100, 200) == 300
add_special(1000, 3000) == 3989
add_special(10000, 25000) == 28390
add_special(30000, 30000) == 32640
这一切似乎都是正确的。
然而,问题在于所写的函数涉及首先将数字转换为浮点值,然后再将它们转换回整数。对于我所知道的数字来说,这似乎是一个不必要的弯路,作为其领域的原则,永远不会不是整数。
我正在为 x86-64 构建,使用 MSVC 14.X,尽管也适用于 GCC 的方法会有所帮助。另外,现阶段我对 SSE/SIMD 优化不感兴趣;我主要只是查看对数据执行的基本操作。
最佳答案
您可能会避免使用 float 并以整数类型进行所有计算:
constexpr int16_t add_special(int16_t a, int16_t b) {
std::int64_t limit = std::numeric_limits<int16_t>::max();
std::int64_t a_fl = a;
std::int64_t b_fl = b;
return static_cast<int16_t>(((limit * limit) * (a_fl + b_fl)
+ ((limit * limit + a_fl * b_fl) / 2)) /* Handle round */
/ (limit * limit + a_fl * b_fl));
}
但根据Benchmark ,这些值并不快。
关于c++ - 有没有办法优化这个功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54638737/
我是一名优秀的程序员,十分优秀!