这意味着 a 或 a+1 中的一个是与 k√n 最接近的整数。但是,我不确定如何确定它是哪一个而不进行涉及浮点运算的一些计算。ak ≤ n < (a+1)k.
给定 a、n 和 k 的值,是否有一种方法可以确定 k√n 并将其四舍五入到最接近的整数,而不进行任何浮点计算呢?
谢谢!
这意味着 a 或 a+1 中的一个是与 k√n 最接近的整数。但是,我不确定如何确定它是哪一个而不进行涉及浮点运算的一些计算。ak ≤ n < (a+1)k.
2kak < 2kn < (2a+1)k → (除以 2k) ak < n < (a+0.5)k → (取 k 次方根) a < k√n < a+0.5,因此 n 的 k 次方根更接近于 a
而不是 a+1
。请注意,极端情况不会发生;整数的 k 次方根不能是一个整数加上 0.5(a+0.5),因为不是 k 次方的 n 的 k 次方根是无理数,如果 n 是完全 k 次方,那么 k 次方根就是一个整数。
2^k (2a+1)^k
应该只是 (2a+1)^k
,对吗?(顺便说一句,回答得很好)。 - unutbuRamchandra Apte和Lazarus的回答都包含了正确答案的精髓,但对我来说都有点难以理解。让我尝试更清晰地解释一下他们似乎在暗示的技巧:
基本思路是,为了找出a或a+1哪个更接近k√n,我们需要测试k√n<a+½。
为了去掉 ½,我们可以简单地将不等式两边乘以 2,得到 2·k√n < 2a+1,然后将两边都提高到第 k 次幂(并假设它们都是正数),我们得到等价的不等式 2k·n < (2a+1)k。因此,只要 2k·n = n ≪ k 不溢出,我们就可以将其与 (2a+1)k 进行比较以获得答案。int round_root( int k, int n ) {
int b = floor_root( k, n << k );
return (b + 1) / 2;
}
附注:另一种方法是直接使用二项式定理计算一个近似值(a+½)k,如下所示: (a+½)k = ∑i=0..k (k 选择 i) ak−i / 2i ≈ ak + k·ak−1 / 2 + ... 然后将其与n直接比较。但是,至少在朴素情况下,对二项式展开的所有项求和仍需要保留额外的k位精度(或至少k−1位;我认为可以安全地忽略最后一项),因此它可能并不比上述建议的方法更有优势。
计算 (a + 0.5)*10
的立方(或者10a+5
- 不使用浮点运算),然后将其除以1000
。
然后检查该数字在哪一侧。
乘以10的想法是将小数点向右移动一位。然后我们除以1000,因为我们进行了3次乘法(立方操作)。
例如:
Input: 16
a = 2
a+1 = 3
a^3 = 8
(a+1)^3 = 27
10a + 5 = 25
25^3 = 15625
floor(15625 / 1000) = 15
16 > 15, thus 3 is closer.
正如Oli所指出的那样,计算(a + 0.5)*2
(或2a + 1
)的立方,然后将其除以8
也可以行得通。
例如:
2a + 1 = 5
5^3 = 125
floor(125 / 8) = 15
16 > 15, thus 3 is closer.
(a + 0.5)*whatever
不一定是整数。 - Bernhard Barker你可以使用牛顿法来找到a;它在整数上运行得非常好,并且比二分查找更快。然后使用平方-乘幂算法计算ak和(a+1)k。这里是一些代码,使用Scheme编写,因为我碰巧有这个方便:
(define (iroot k n) ; largest integer x such that x ^ k <= n
(let ((k-1 (- k 1)))
(let loop ((u n) (s (+ n 1)))
(if (<= s u) s
(loop (quotient (+ (* k-1 u) (quotient n (expt u k-1))) k) u)))))
(define (ipow b e) ; b^e
(if (= e 0) 1
(let loop ((s b) (i e) (a 1)) ; a * s^i = b^e
(let ((a (if (odd? i) (* a s) a)) (i (quotient i 2)))
(if (zero? i) a (loop (* s s) i a))))))
为了确定哪个更接近根号的值,ak和(a+1)k,您可以使用幂算法计算(a + 1/2)k — 这是一个精确的计算,平方乘操作可以执行 — 然后将结果与n进行比较,并确定哪一侧更接近。
编辑:
很抱歉误解了问题。这里是原问题的一个可能解决方案:
使用牛顿逼近定理:-
here = means (approximately = )
f(b+a) = f(b) + a*f'(b)
a -> 0
f(x) = x^k
f'(x) = k*x^(k-1)
hence using above equation
f(a+0.5) = a^k + 1/2*k*a^(k-1);
need to check n < f(a+0.5)
n < a^k + 1/2*k*a^(k-1)
rearranging (n-a^k)*2 < k*a^(k-1)
注意:您可以使用二项式定理来获得更高的精度。
思考。理想情况下,您可以进行一次二分查找的步骤,以查看根在a+½的哪一侧。也就是说,测试不等式
(a+0.5)k < n
但左边很难精确计算(浮点问题)。因此,请写下一个等价的不等式,其中所有术语都是整数:
(2a+1)k < 2k n
完成。