计算一个浮点数的立方根,不使用库函数。
保留一位小数。
数据范围:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double x = in.nextDouble();
double delta = 0.01; // 精度
// 考虑|x|>1的情况和|x|<1的情况,前者立方根比原数小,后者比原数大
double left = x > 0? 0: x < -1? x: -1;
double right = x > 0? x > 1? x: 1: 0;
while (right*right*right-x>delta) {
double mid = (left + right) / 2;
if (mid*mid*mid > x) {
right = mid;
} else if (mid*mid*mid < x) {
left = mid;
}
}
System.out.printf("%.1f", right);
}
}
不用库方法,我用库方法的源码
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static final int B1 = 715094163; /* B1 = (682-0.03306235651)*2**20 */
private static final int B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
private static final double C = 0x1.15f15f15f15f1p-1; // 19/35 ~= 5.42857142857142815906e-01
private static final double D = -0x1.691de2532c834p-1; // -864/1225 ~= 7.05306122448979611050e-01
private static final double E = 0x1.6a0ea0ea0ea0fp0; // 99/70 ~= 1.41428571428571436819e+00
private static final double F = 0x1.9b6db6db6db6ep0; // 45/28 ~= 1.60714285714285720630e+00
private static final double G = 0x1.6db6db6db6db7p-2; // 5/14 ~= 3.57142857142857150787e-01
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double aDouble = scanner.nextDouble();
double compute = compute(aDouble);
double l = Math.round(compute * 10) / 10.0;
Math.cbrt(12);
System.out.println(l);
}
public static double compute(double x) {
double t = 0.0;
double sign;
if (x == 0.0 || !Double.isFinite(x))
return x; // Handles signed zeros properly
sign = (x < 0.0) ? -1.0: 1.0;
x = Math.abs(x); // x <- |x|
// Rough cbrt to 5 bits
if (x < 0x1.0p-1022) { // subnormal number
t = 0x1.0p54; // set t= 2**54
t *= x;
t = __HI(t, __HI(t)/3 + B2);
} else {
int hx = __HI(x); // high word of x
t = __HI(t, hx/3 + B1);
}
// New cbrt to 23 bits, may be implemented in single precision
double r, s, w;
r = t * t/x;
s = C + r*t;
t *= G + F/(s + E + D/s);
// Chopped to 20 bits and make it larger than cbrt(x)
t = __LO(t, 0);
t = __HI(t, __HI(t) + 0x00000001);
// One step newton iteration to 53 bits with error less than 0.667 ulps
s = t * t; // t*t is exact
r = x / s;
w = t + t;
r = (r - t)/(w + r); // r-s is exact
t = t + t*r;
// Restore the original sign bit
return sign * t;
}
private static double __HI(double x, int high) {
long transX = Double.doubleToRawLongBits(x);
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL) |
( ((long)high)) << 32 );
}
private static double __LO(double x, int low) {
long transX = Double.doubleToRawLongBits(x);
return Double.longBitsToDouble((transX & 0xFFFF_FFFF_0000_0000L) |
(low & 0x0000_0000_FFFF_FFFFL));
}
private static int __HI(double x) {
long transducer = Double.doubleToRawLongBits(x);
return (int)(transducer >> 32);
}
}
import java.util.Scanner;
//牛顿迭代,注意while里的条件,是真实值和估计值的差值的绝对值小于误差
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
double n = in.nextDouble();
double error = 0.0000001;
double start = n/3;
double value;
while(start*start*start - n > error || n - start*start*start > error){
start = start - (start*start*start-n)/(start*start*3);
}
System.out.print(String.format("%.1f", start));
}
} import java.util.Scanner;
import java.io.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Double num = Double.parseDouble(br.readLine());
Double k = 1d;
Double num1 = 0d;
if (num == 0 ) {
System.out.println(0);
return;
}
if (num > 0) {
for (Double i = 1d;; i += k) {
if (i * i * i == num) {
System.out.printf("%.1f", i);
return;
} else if (i * i * i > num) {
i = i - k;
k = k / 10;
if (k == 0.0001) {
num1 = i;
break;
}
}
}
}
if (num < 0) {
for (Double i = -1d;; i -= k) {
if (i * i * i == num) {
System.out.printf("%.1f", i);
return;
} else if (i * i * i < num) {
i = i + k;
k = k / 10;
if (k == 0.0001) {
num1 = i;
break;
}
}
}
}
System.out.println(String.format("%.1f", num1));
String str = num1.toString();
}
}求大佬指点
// 穷举,笨人用笨方法
public static double resolve(double value) {
if (value == 0d || value == 1d || value == -1d) {
return value;
}
if (value == 8d || value == -8d) {
return value > 0 ? 2 : -2;
}
boolean positive = true;
if (value < 0) {
positive = false;
value = -value;
}
double c = 1e-3; // 误差
boolean isDecimal = value < 1;
double base = isDecimal ? 1 : 0;
double max = isDecimal ? 1 : value, min = isDecimal ? value : 1;
while (true) {
double cube = base * base * base;
boolean bigger = value > cube;
double sub = bigger ? value - cube : cube - value;
if (sub <= c) {
break;
}
if (bigger) {
min = base;
} else {
max = base;
}
base = (max + min) / 2;
}
return positive ? base : -base;
} import java.util.Scanner;
public class HJ107 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//in.hasNextInt();
double a = in.nextDouble();
search(-20.0, 20, a);
}
public static void search(double l, double r, double t) {
double m = (l + r) / 2.0;
double v = m*m*m;
if (Math.abs(t -v) < 0.0000001) {
System.out.printf("%.1f", m);
} else if (v > t) {
search(l, m, t);
} else {
search(m, r, t);
}
}
}
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
System.out.print(String.format("%.1f",Math.cbrt(in.nextDouble())));
}
} import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double num = in.nextDouble();
//记录是正数还是负数
double sign = 1;
double result = 0;
//不管正负,都取正,以方便运算
if(num<0){
sign = -1;
num *= -1;
}
//由于|val|<=20,所以我们可以知道,它的立方根是在(0,3)
//根据输入值的范围,将情况分为三种
//0<=num<1,在[0,1)范围内找
//1<=num<8, 在[1,2)范围内找
//8<=num<20,在[2,3)范围内找
if(num>=0 && num<1){
result = deCub(num,0);
}else if(num>=1 && num<8){
result = deCub(num,1);
}else{
result = deCub(num,2);
}
//别忘了乘上sign,以及保留一位小数
System.out.println(String.format("%.1f",result*sign));
}
public static double deCub(double num, double low){
//建立一个数组来存储节点值的立方和num之间的差值
double[] distance = new double[10];
//节点值的立方
double cub = 0;
//临时最小值
double temp = num;
//记录差值最小值所对应节点值
int flag = 0;
//从起始值low开始,每次增加0.1,记录差值,并和temp做比较,更新temp值和flag
for(int i=0; i<10; i++){
cub = Math.pow(low+i*0.1,3);
distance[i] = Math.abs(num-cub);
if(distance[i]<temp){
temp = distance[i];
flag = i;
}
}
return low+flag*0.1;
}
} import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 获取输入的实数
String num = in.nextLine();
// 定义一个数表示该立方根的左边和右边无限接近的数,只要右边-左边精度在0.0001,则可求得立方根
double left = 0;
double right;
if (Math.abs(Double.parseDouble(num)) > 1) {
right = Math.abs(Double.parseDouble(num));
} else {
right = 1;
}
// 定义一个立方根
double mid = 0;
while (right - left > 0.0001) {
mid = (right + left) / 2;
if (mid * mid * mid > Math.abs(Double.parseDouble(num))) {
// 立方根较大,右边数降低为mid
right = mid;
} else {
// 立方根较小,左边数升高为mid
left = mid;
}
}
if (num.contains("-")) {
// 输出结果,保留一位小数
System.out.print( "-");
System.out.printf("%.1f", mid);
} else {
// 输出结果,保留一位小数
System.out.printf("%.1f", mid);
}
}
}