将除法的结果四舍五入到最接近的整数非常简单。但我正在尝试对除法的结果进行四舍五入,以便后续操作将给出最佳近似值。最好用一个简单的函数来解释:
const int halfbits = std::numeric_limits<unsigned int>::digits / 2;
unsigned x = foo(); // Likely big.
unsigned x_div = x >> halfbits; // Rounded down
unsigned y = x_div * x_div; // Will fit due to division.
我可以x_div
通过添加四舍五入到最近1<<(halfbits-1)
。但由于 x² 不是线性函数,因此 y 通常没有正确舍入。有(x*x) >> (halfbits*2)
没有不使用更大类型的简单和更准确的计算方法?
我认为添加3<<(halfbits-3)
到 x_div 可以提高舍入,但不能证明这是最好的解决方案。此外,这可以推广到 xⁿ 吗?
编辑:根据大众的要求,我冒昧地用纯算术术语“翻译”这个问题(这些 C 位移都没有......)。
注意:此后的所有除法都是整数除法,例如 13/3 将是 4。
问题:我们无法计算 x^2,因为 x 很大,所以我们想计算 (x^2)/(2^ N)。
为此,我们计算
x_div = x / sqrt(2^N)
然后平方:
y = x_div * x_div
但是,此结果通常缺少 的确切值,(x^2)/(2^N)
并且 OP 建议添加 0.5 * sqrt(2^N) 或 0.375 * sqrt(2^N) 以更好地近似结果...
正如Oli Charlesworth
's answer 所暗示的,有一种更好的方法来获得实际值,将其x^2
视为 (x_hi + x_lo)^2。