使用printf格式化输出
对于一些的题目,我们可以直接使用printf格式化输出。这里写几个例子。
例题一
问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。
public static void main(String[] args) {
for(int i=0;i<32;i++) {
System.out.printf("%05d\n",Integer.parseInt(Integer.toBinaryString(i)));;
}
}
- 这里的%05d意思就是以五位的形式打印,不够的用0填充
- %.2f 浮点型表示保留两位小数并且进行四舍五入的处理
又联想到了String的格式化保存
String用法
使用DecimalFormat
这个功能强大,适合处理比较复杂的位数保留情况。在这里只简单介绍,更复杂一点的东西用到的时候再去搜索用法。
- DecimalFormat df = new DecimalFormat(str)
一个解决所有问题,下面的图片说明也十分清楚。👇
比如下面的例题,就是求圆面积并且保留7位小数。
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n=sc.nextInt();
double s = n*n*Math.PI;
DecimalFormat df = new DecimalFormat("0.0000000");
System.out.println(df.format(s));
sc.close();
}
}
位数问题看似解决了,那么最后一位怎么取舍呢?
尾数的取舍
DecimalFormat四舍五入的坑
有时候我们在处理小数保留几位小数时,想到了DecimalFormat这个类的使用,百度搜一把可能用到以下方式。
public static void main(String[] args) {
String str="3.145";
System.out.println(round1(str));
}
static String round1(String str){
double a=Double.parseDouble(str);
DecimalFormat df=new DecimalFormat("###.00");
return df.format(a);
}
初看好像没什么问题,四舍五入保留两位小数,最后输出3.15。当然精度要求不高,也无需计较。当涉及到精确统计时,这里的坑来了将上面的字符串改为“5”前面为奇数,如“3.155”,就瓜了,输出3.15。显然这里没满足要求,不是我们学校里的四舍五入。再上一段代码。
static String round2(String str){
double a=Double.parseDouble(str);
DecimalFormat df=new DecimalFormat("###.00");
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(a);
}
这里可以看到这个setRoundingMode()方法可以设定四舍五入的模式,原来四舍五入不光有我们学校里学的那种,还有其他模式。DecimalFormat默认情况下,它使用 RoundingMode.HALF_EVEN,此舍入模式也称为“银行家舍入法”,主要在美国使用。RoundingMode.HALF_UP这个模式才是我们学校里学的标准四舍五入模式。但是经过实际操作,看到程序输出的还是错误答案。以上代码虽然舍了学校型模式仍然不准确,应该将double类型改为BigDecimal类型。
RoundingMode说明
为了能更好理解,我们可以画一个XY轴
RoundingMode.CEILING:取右边最近的整数
RoundingMode.DOWN:去掉小数部分取整,也就是正数取左边,负数取右边,相当于向原点靠近的方向取整
RoundingMode.FLOOR:取左边最近的正数
RoundingMode.HALF_DOWN:五舍六入,负数先取绝对值再五舍六入再负数
RoundingMode.HALF_UP:四舍五入,负数原理同上
RoundingMode.HALF_EVEN:这个比较绕,整数位若是奇数则四舍五入,若是偶数则五舍六入
银行家舍入法说明
银行家舍入法是由IEEE 754标准规定的浮点数取整算法 ,大部分的编程软件都使用的是这种方法。 所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。其规则是:当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后不为空且非全0)时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后为空或全0)时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。
简单的说,就是:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一
这样就是对了,但是我们不需要因为一个四舍五入把程序写的这么麻烦。
使用相对简单实用的方法
用String的fomat方法直接格式化
因为这里是直接默认四舍五入,所以简单可以直接使用此方法。
这里%05.2f
中的5表示的是一共多少个字符,比如上面就是有03.12一共五个字符,2是保留几位小数,默认四舍五入。
static String round3(String str){
double d=Double.parseDouble(str);
return String.format("%.2f",d);
}
另外我也总结了String、buffer、builder的方法欢迎学习。
BigDecimal结合DecimalFormat
BigDecimal比较耗性能,数据处理量大不建议使用。
static String round4(String str){
BigDecimal bigDecimal=new BigDecimal(str);
DecimalFormat df=new DecimalFormat("###.00");
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(bigDecimal);
}
BigDecimal单独使用,这个类也自带舍入模式设定方法。
static String round5(String str){
BigDecimal bigDecimal=new BigDecimal(str);
return String.valueOf(bigDecimal.setScale(2,RoundingMode.HALF_UP));
}
BigDecimal的取舍模式
自己写方法
当然了,如果只是简单的四舍五入,也可以自己单独想一个取舍的好方法。比如下题。
蓝桥杯2020Java成绩统计
在这里面我就是自己写了一个四舍五入的方法,没用别的。