import java.util.*;
import java.math.*;
public class Test {
public static void main(String[] args) {
int cd;
cd=0;
try {
BigDecimal[] a;
a=null;
int n,i1;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
cd=1;
a=new BigDecimal[n];
for(i1=0; n>i1; i1++) {
a[i1]=new BigDecimal(""+sc.nextLine());
}
cd=2;
Comparator cmp = new MyComparator();
Arrays.sort(a, cmp);
for (BigDecimal arr : a) {
System.out.print(arr.toString() + "\n");
}
} catch(Exception e) {
System.out.println(""+e+"\n"+cd);
}
}
}
class MyComparator implements Comparator<BigDecimal> {
@Override
public int compare(BigDecimal o1, BigDecimal o2) {
return o2.compareTo(o1);
}
}
当我在第一行输入3时,为何会报错?
修改如下:
n=sc.nextInt();
sc.nextLine(); // 接收换行
正常是这样用的。你可暂时先使用以下方式:
String s = sc.nextLine();
n = Integer.parseInt(s);
浮点数没有办法用二进制精确表示,因此存在精度丢失的风险。
不过,Java 提供了BigDecimal
来操作浮点数。BigDecimal
的实现利用到了 BigInteger
(用来操作大整数), 所不同的是 BigDecimal
加入了小数位的概念。
答案:
问题的根本原因是浮点数精度问题,在使用 double 或 float 类型进行计算时,结果会出现精度不准确的情况。当使用 double 类型传入 3 时,实际上传入的是一个近似值,而不是精确的值,导致 BigDecimal 对象的值也受到影响。为避免这种情况,应当使用 BigDecimal 的 String 构造函数,或者使用 BigDecimal.valueOf 方法创建对象。
解决方案:
使用 BigDecimal(String val) 构造函数,将需要计算的数值转换成字符串来创建 BigDecimal 对象。例如:
BigDecimal num = new BigDecimal("3");
或者使用 BigDecimal.valueOf 方法创建对象,这个方法会将传入的 double 类型转换为字符串,再创建 BigDecimal 对象。例如:
BigDecimal num = BigDecimal.valueOf(3);
这两种方法都避免了使用浮点数类型导致的精度问题。若使用 new BigDecimal(double val) 创建对象,需要注意传入的参数是一个近似值,而非精确值,容易引发精度问题。
注:当进行 BigDecimal 计算时,应该使用特定的舍入模式,例如 ROUND_HALF_UP,以保证计算结果的精度。