public static double squareRoot(double num) throws IllegalArgumentException
{
if (num < 0.0)
throw new IllegalArgumentException("Number cannot be negative.");
double guess = num / 2.0, pastGuess;
guess = 0.5 * (guess + (num / guess));
do {
pastGuess = guess;
guess = 0.5 * (guess + (num / guess));
} while ((pastGuess / guess) >= 1.01);// run until both numbers are within 1% of each other
return guess; // return square root of num
}
我试图使用巴比伦算法实现一个简单的squareRoot方法。我的问题是,对于小于0.01的数字,结果非常不准确。
我希望循环运行,直到两个数字(pastGuess和guess)相互之间都在1%之内,但是我无法弄清楚它的正确数学。
我想出了:((pastGuess / guess) >= 1.01)
我也尝试过:
((pastGuess / guess) >= 1.01 || (guess / pastGuess ) >= 1.01)
这项工作更好,但有更有效的方法吗?
答案 0 :(得分:4)
猜猜你也想要99%,所以基本上它意味着差异小于1%:
Math.abs((pastGuess - guess) / guess) < 0.01
这应该已经非常稳定了。
干杯!
答案 1 :(得分:4)
double ratio = pastGuess / guess;
(ratio >= 1.01 || ratio <= 0.99)
请注意,我使用0.99
来提高可读性。上述验证的对称正确值将是一个等于(100/101) = 0.99009900...
答案 2 :(得分:2)
float parcent = Math.abs(1f - (pastGuess / guess))
if(parcent <= 0.01f)
:d
答案 3 :(得分:1)
假设这两个数字是'a'和'b'。让我们说一个&lt;湾
'b'的1%= b / 100
'a'的1%= a / 100
如果&gt;那么'a'在'b'的1%范围内。 b-b / 100或(b-a)/ b < 1/100
如果b
因为&lt; b暗示(b-a)/ b < (b-a)/ a
所以如果(b-a)/ a&lt; 1/100表示(b-a)/ b <1。 1/100为(b-a)/ b小于(b-a)/ a。
所以支票可以是:
abs(guess-pastguess)/ ((guess < pastguess) ? guess : pastguess) < 0.01 ;
让我们看一个例子:
如果a = 99.001且b = 100,则b = 100不在a = 99的1%范围内,99.001的1%是.99001,因此b必须小于99.99001
另一方面,b = 99.0001在a = 100的1%范围内,因为100%的1%是0.1。因此任何大于99的数字都在100的1%之内。