1. 题目
读题
考查点
2. 解法
思路
解题思路:
我们可以使用二分法来求解立方根,即在一个区间内不断缩小范围,直到找到一个满足条件的数。
首先,我们确定一个初始区间[0, N],然后计算区间的中点mid = (0 + N) / 2,判断mid的立方是否等于N,如果等于,则直接返回mid;如果小于N,则说明立方根在[mid, N]之间,更新区间为[mid, N];如果大于N,则说明立方根在[0, mid]之间,更新区间为[0, mid]。
重复上述过程,直到区间的长度小于一个很小的值(比如0.001),此时我们可以认为区间的中点就是立方根的近似值,保留一位小数后返回即可。
代码逻辑
具体实现
public class HJ107 {
public static final double EPS = 0.001;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(cubeRoot(Double.parseDouble(sc.nextLine())));
}
public static double cubeRoot(double N) {
double low = 0;
double high = N;
if (N > 0 && N < 1) {
high = 1;
}
if (N < 0 && N > -1) {
low = -1;
high = 0;
}
if (N < -1) {
double temp = low;
low = high;
high = temp;
}
double mid = 0;
while (high - low > EPS) {
mid = (low + high) / 2;
if (mid * mid * mid == N) {
return mid;
} else if (mid * mid * mid < N) {
low = mid;
} else {
high = mid;
}
}
return Math.round(mid * 10) / 10.0;
}
}
3. 总结
使用表格 来 对比一下 floiat ,double ,bigdecimal
float,double 和 bigdecimal 的特点。表格如下:
类型 | 存储空间 | 精度 | 范围 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|---|
float | 32 位 | 7 位小数 | 大约 3.4e38 | 占用空间少,计算速度快 | 精度低,容易产生舍入误差,范围有限 | 科学计算或工程计算 |
double | 64 位 | 15 位小数 | 大约 1.8e308 | 精度高,范围广,通用性强 | 占用空间多,计算速度慢,仍然可能产生舍入误差 | 科学计算或工程计算 |
bigdecimal | 不定,取决于数值大小和精度 | 不定,取决于数值大小和精度 | 不定,取决于内存大小 | 精度任意,不会产生舍入误差,可以进行精确的数值运算 | 占用空间极多,计算速度极慢,编程复杂度高 | 金融计算或需要精确结果的计算 |
float 类型会丢失精度的原因主要有两个:
- 有些十进制的数值在二进制中不能精确地表示,比如 0.1 在二进制中是一个无限循环小数,所以在存储和计算的过程中会产生舍入误差。这个问题不仅存在于 float 类型,也存在于 double 和 bigdecimal 类型,只是后者的精度更高,所以误差更小。
- float 类型的存储空间有限,只有 32 位,其中 1 位表示符号,8 位表示指数,23 位表示尾数。这意味着 float 类型只能表示最多 24 位有效数字(包括整数部分和小数部分),如果超过这个范围,就会丢失最低位的数字。比如,如果你用 float 类型表示 123456789.123456789,那么它会被截断为 123456792.0。