我试图使用Math.pow(n, 1.0 / 3) % ((int) Math.pow(n, 1.0 / 3))
在java中获得立方根,但因为它除了双精度数,所以它不会返回确切的答案。例如,对于125,这给出了4.9999999999。有解决办法吗?我知道有一个立方根函数,但我想解决这个问题,以便我可以计算更高的根。
我不想舍入,因为我想知道一个数字是否具有整数根,通过这样做:$('.btn').click(function() {
$('.front').addClass('front-flip');
$('.back').addClass('back-flip');
});
。
答案 0 :(得分:6)
由于无法使用double
进行任意精度计算,因此您有三种选择:
double
值是否为整数。double
的舍入值是否正确。BigDecimal
对象执行微积分,它支持任意精度的双精度值。private static boolean isNthRoot(int value, int n, double precision) {
double a = Math.pow(value, 1.0 / n);
return Math.abs(a - Math.round(a)) < precision; // if a and round(a) are "close enough" then we're good
}
这种方法的问题是如何定义&#34;足够接近&#34;。这是一个主观问题,取决于您的要求。
private static boolean isNthRoot(int value, int n) {
double a = Math.pow(value, 1.0 / n);
return Math.pow(Math.round(a), n) == value;
}
此方法的优点是无需定义精度。但是,我们需要执行另一个pow
操作,因此这会影响性能。
没有内置方法来计算BigDecimal的双倍功率。 This question会为您提供有关如何操作的见解。
答案 1 :(得分:5)
Math.round 函数将舍入到最近的长值,该值可以存储为double。您可以比较2个结果以查看该数字是否具有整数立方根。
double dres = Math.pow(125, 1.0 / 3.0);
double ires = Math.round(dres);
double diff = Math.abs(dres - ires);
if (diff < Math.ulp(10.0)) {
// has cubic root
}
如果情况不足,您可以尝试实施this算法,如果结果似乎不是整数,请提前停止。
答案 2 :(得分:1)
我可能会根据this方法实现自己的功能。
答案 3 :(得分:1)
我写了这个方法来计算floor(x^(1/n))
,其中x
是非负BigInteger
而n
是正整数。不久之前,我现在无法解释它为什么会起作用,但我有理由相信,当我写这篇文章时,我很高兴能够合理地快速给出正确答案。
要查看x
是否具有确切的n-th
权限,您可以检查提升到权力n
的结果是否会再次提供x
。
public static BigInteger floorOfNthRoot(BigInteger x, int n) {
int sign = x.signum();
if (n <= 0 || (sign < 0))
throw new IllegalArgumentException();
if (sign == 0)
return BigInteger.ZERO;
if (n == 1)
return x;
BigInteger a;
BigInteger bigN = BigInteger.valueOf(n);
BigInteger bigNMinusOne = BigInteger.valueOf(n - 1);
BigInteger b = BigInteger.ZERO.setBit(1 + x.bitLength() / n);
do {
a = b;
b = a.multiply(bigNMinusOne).add(x.divide(a.pow(n - 1))).divide(bigN);
} while (b.compareTo(a) == -1);
return a;
}
使用它:
System.out.println(floorOfNthRoot(new BigInteger("125"), 3));
修改强> 阅读上面的评论我现在记得这是第n个根的Newton-Raphson方法。 Newton-Raphson方法具有二次收敛性(在日常语言中意味着它很快)。您可以尝试使用具有数十位数字的数字,您应该在几分之一秒内得到答案。
您可以调整该方法以使用其他数字类型,但我认为double
和BigDecimal
不适合此类事件。
答案 4 :(得分:0)
在这种情况下,这是一个很好的选择。 你可以依靠这个 -
System.out.println(" ");
System.out.println(" Enter a base and then nth root");
while(true)
{
a=Double.parseDouble(br.readLine());
b=Double.parseDouble(br.readLine());
double negodd=-(Math.pow((Math.abs(a)),(1.0/b)));
double poseve=Math.pow(a,(1.0/b));
double posodd=Math.pow(a,(1.0/b));
if(a<0 && b%2==0)
{
String io="\u03AF";
double negeve=Math.pow((Math.abs(a)),(1.0/b));
System.out.println(" Root is imaginary and value= "+negeve+" "+io);
}
else if(a<0 && b%2==1)
System.out.println(" Value= "+negodd);
else if(a>0 && b%2==0)
System.out.println(" Value= "+poseve);
else if(a>0 && b%2==1)
System.out.println(" Value= "+posodd);
System.out.println(" ");
System.out.print(" Enter '0' to come back or press any number to continue- ");
con=Integer.parseInt(br.readLine());
if(con==0)
break;
else
{
System.out.println(" Enter a base and then nth root");
continue;
}
}
答案 5 :(得分:0)
这是一个非常丑陋的黑客,但你可以通过缩进来达到其中一些。
System.out.println(Math.sqrt(Math.sqrt(256)));
System.out.println(Math.pow(4, 4));
System.out.println(Math.pow(4, 9));
System.out.println(Math.cbrt(Math.cbrt(262144)));
Result:
4.0
256.0
262144.0
4.0
这将为您提供每n ^ 3个立方体和每个第n ^ 2个根。
答案 6 :(得分:0)
您可以使用一些来自数学领域的技巧来提高准确性。 像这样一个x ^(1 / n)= e ^(lnx / n)。
答案 7 :(得分:0)
这是不使用Java的Math.pow函数的解决方案。 它将使您获得第n个根
public class NthRoot {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int testcases = scanner.nextInt();
while (testcases-- > 0) {
int root = scanner.nextInt();
int number = scanner.nextInt();
double rootValue = compute(number, root) * 1000.0 / 1000.0;
System.out.println((int) rootValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static double compute(int number, int root) {
double xPre = Math.random() % 10;
double error = 0.0000001;
double delX = 2147483647;
double current = 0.0;
while (delX > error) {
current = ((root - 1.0) * xPre + (double) number / Math.pow(xPre, root - 1)) / (double) root;
delX = Math.abs(current - xPre);
xPre = current;
}
return current;
}
答案 8 :(得分:0)
使用二进制搜索方法查找第n个根。 这是根据您的要求以任意精度查找第n个根的方法。
import java.util.Scanner;
public class FindRoot {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int testCase = scanner.nextInt();
while (testCase-- > 0) {
double number = scanner.nextDouble();
int root = scanner.nextInt();
double precision = scanner.nextDouble();
double result = findRoot(number, root, precision);
System.out.println(result);
}
}
}
private static double findRoot(double number, int root, double precision) {
double start = 0;
double end = number / 2;
double mid = end;
while (true) {
if (precision >= diff(number, mid, root)) {
return mid;
}
if (pow(mid, root) > number) {
end = mid;
} else {
start = mid;
}
mid = (start + end) / 2;
}
}
private static double diff(double number, double mid, int n) {
double power = pow(mid, n);
return number > power ? number - power : power - number;
}
private static double pow(double number, int pow) {
double result = number;
while (pow-- > 1) {
result *= number;
}
return result;
}
}
答案 9 :(得分:-1)
int m = 81, n = 4;
Math.pow(m, Math.pow(n, -1));