将除法结果四舍五入到最接近的整数是相当简单的。但我正在尝试将除法结果四舍五入,以便随后的操作能够得到最佳近似值。这可以通过一个简单的函数来解释:
我可以通过添加
我认为将
编辑:应广大要求,我在纯算术术语中“翻译”了问题(没有C位移操作...)。注意:此后所有除法都是整数除法,例如13/3将是4。问题:我们无法计算x²,因为x很大,所以我们想计算(x²)/(2^N)。为此,我们计算x_div = x / sqrt(2^N),然后将其平方:y = x_div * x_div。
然而,这个结果通常比
正如 Oli Charlesworth 的回答所建议的那样,有一种更好的方法可以得到实际值,即将
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.
我可以通过添加
1<<(halfbits-1)
来将x_div
四舍五入到最近的值。但由于x²不是线性函数,通常情况下y无法正确舍入。有没有一种简单而更准确的方法来计算(x*x) >> (halfbits*2)
,而不使用更大的类型?我认为将
3<<(halfbits-3)
添加到x_div会改善舍入,但无法证明这是最佳解决方案。此外,这可以推广到xⁿ吗?编辑:应广大要求,我在纯算术术语中“翻译”了问题(没有C位移操作...)。注意:此后所有除法都是整数除法,例如13/3将是4。问题:我们无法计算x²,因为x很大,所以我们想计算(x²)/(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 的回答所建议的那样,有一种更好的方法可以得到实际值,即将
x^2
视为 (x_hi + x_lo)^2。
x_div_down*x_div_up
,x_div_near*x_div_near
。如果你愿意花时间,你可以计算(x_div*x_rest)>>(halfbit-1)
并根据结果进行修正。 - Marc Glisse(x*x) >> (halfbits*2)
暗示了您实际上想要那个 非舍入 的位精确结果吗?或者您想要正确舍入的数学结果? - hyde(x*x) >> (halfbits*2)
不就是(x*x) >> bits
吗?你的意思是要计算x^2 / 2^ceil(log2(x))
吗? - user541686x*x/UINT_MAX
。 - MSalters