Java 数据格式化&小数点后保留指定位数 您所在的位置:网站首页 javaformat函数 Java 数据格式化&小数点后保留指定位数

Java 数据格式化&小数点后保留指定位数

2023-12-10 10:36| 来源: 网络整理| 查看: 265

小数点后保留指定n位数 DecimalFormatNumberFormatFormatterString.formatprintf()BigDecimal构造方法具体示例注意事项 小数点后保留指定n位数printf()BigDecimal

DecimalFormat

使用 DecimalFormat,但是只能保留指定位数.

DecimalFormat d = new DecimalFormat("0.000"); double x = 3.45125; System.out.println(d.format(x)); // 3.451

参考上篇博客 详解数字格式化

NumberFormat public static String format(double value) { // 获取实例对象 NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(2); /* * setMinimumFractionDigits设置成2 * * 如果不这么做,那么当value的值是100.00的时候返回100 * * 而不是100.00 */ nf.setMinimumFractionDigits(2); nf.setRoundingMode(RoundingMode.HALF_UP); /* * 如果想输出的格式用逗号隔开,可以设置成true */ nf.setGroupingUsed(false); return nf.format(value); } Formatter

java.util.Formatter

public static String format(double value) { /* * %.2f % 表示 小数点前任意位数 2 表示两位小数 格式后的结果为 f 表示浮点型 */ return new Formatter().format("%.2f", value).toString(); } String.format

String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能。

常见使用方式:

public static String format5(double value) { return String.format("%.2f", value).toString(); }

占位符格式为: %[index$][标识]*[最小宽度][.精度]转换符

可用标识符:

-:在最小宽度内左对齐,不可以与0标识一起使用。0:若内容长度不足最小宽度,则在左边用0来填充。#:对8进制和16进制,8进制前添加一个0,16进制前添加0x。+:结果总包含一个+或-号。空格:正数前加空格,负数前加-号。,:只用与十进制,每3位数字间用,分隔。(:若结果为负数,则用括号括住,且不显示符号。

可用转换符:

b,布尔类型,只要实参为非false的布尔类型,均格式化为字符串true,否则为字符串false。 n,平台独立的换行符, 也可通过System.getProperty(“line.separator”)获取。 f,浮点数型(十进制)。显示9位有效数字,且会进行四舍五入。如99.99。 a,浮点数型(十六进制)。 e,指数类型。如 9.38e+5。 g,浮点数型(比%f,%a 长度短些,显示6位有效数字,且会进行四舍五入)

实例展示:

// 测试代码 double num = 123.456789; System.out.print(String.format("%f %n", num)); // %f:默认显示9位有效数字,且会进行四舍五入。%n:默认换行,123.456790 System.out.print(String.format("%a %n", num)); // %a:浮点数型(十六进制),0x1.edd3c0bb46929p6 System.out.print(String.format("%g %n", num)); // %g:浮点数型(比%f,%a长度短些,显示6位有效数字,且会进行四舍五入),123.457 // 保留小数点后位 System.out.println(String.format("%.2f", num)); // 123.46 // 左对齐 int n = 3; // 6位右对齐,不足六位补0 System.out.println(String.format("%06d", n)); // 000003 // 6位右对齐,不足六位补空格 System.out.println(String.format("%6d", n)); // 3 // 6位左对齐,不足六位补空格 System.out.println(String.format("%-6d", n)); // 3

结果如下 在这里插入图片描述

printf()

C语言中 printf 函数使用很方便,很高兴Java中也可以使用 printf 的格式: System.out.printf(); 具体使用格式与 String.format() 方法一样,请参考上面。

double num = 20.45628; // 保留两位小数,%n 换行 System.out.printf("%.2f %n", num); // 20.46 int n = 6; // 右对齐5位 System.out.printf("%5d %n", n); // 左对齐5位 System.out.printf("%-5d %n", n);

在这里插入图片描述

BigDecimal

A BigDecimal由任意精度整数未缩放值和32位整数比例组成。 如果为零或正数,则刻度是小数点右侧的位数。 如果是负数,则数字的非标定值乘以10,以达到等级的否定的幂。 因此, (unscaledValue × 10-scale)代表的BigDecimal值为(unscaledValue × 10-scale) 。 BigDecimal类提供了算术,缩放操作,舍入,比较,散列和格式转换的操作。 toString()方法提供了一个BigDecimal的规范表示。 BigDecimal类使其用户完全控制舍入行为。 如果未指定舍入模式,并且无法表示确切的结果,则抛出异常; 否则,可以通过向操作提供适当的MathContext对象来进行计算,以选择精度和舍入模式。 在这两种情况下,都提供八种舍入方式来控制舍入。 不建议使用此类中的整数字段(如ROUND_HALF_UP )表示舍入模式; 应该使用RoundingMode 枚举的枚举值(如RoundingMode.HALF_UP )。 ---- 官方API

BigDecimal 计算和保留小数位是在Java最常用的,也是在财务或者是数据分析中比较重要的方法。

构造方法 Constructor BigDecimal​(char[] in) 将 BigDecimal的字符数组表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符序列。 BigDecimal​(char[] in, int offset, int len) 将 BigDecimal的字符阵列表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符序列,同时允许指定子数组。 BigDecimal​(char[] in, int offset, int len, MathContext mc) 将 BigDecimal的字符数组表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符序列,同时允许根据上下文设置指定子数组并进行舍入。 BigDecimal​(char[] in, MathContext mc) 将 BigDecimal的字符数组表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符序列,并根据上下文设置进行舍入。 BigDecimal​(double val) 将 double转换为 BigDecimal ,它是 double的二进制浮点值的精确十进制表示。 BigDecimal​(double val, MathContext mc) 将 double转换为 BigDecimal ,根据上下文设置进行舍入。 BigDecimal​(int val) 将 int翻译成 BigDecimal 。 BigDecimal​(int val, MathContext mc) 将 int转换为 BigDecimal ,根据上下文设置进行舍入。 BigDecimal​(long val) 将 long翻译成 BigDecimal 。 BigDecimal​(long val, MathContext mc) 将 long转换为 BigDecimal ,根据上下文设置进行舍入。 BigDecimal​(String val) 将 BigDecimal的字符串表示 BigDecimal转换为 BigDecimal 。 BigDecimal​(String val, MathContext mc) 将 BigDecimal的字符串表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符串,根据上下文设置进行舍入。 BigDecimal​(BigInteger val) 将 BigInteger翻译成 BigDecimal 。 BigDecimal​(BigInteger unscaledVal, int scale) 将 BigInteger值和 int量表翻译成 BigDecimal 。 BigDecimal​(BigInteger unscaledVal, int scale, MathContext mc) 将 BigInteger值和 int标度转换为 BigDecimal ,根据上下文设置进行舍入。 BigDecimal​(BigInteger val, MathContext mc) 根据上下文设置将 BigInteger转换为 BigDecimal舍入。

在这里插入图片描述

舍入方式:

BigDecimal.setScale(int newScale, int roundingMode); // 设置格式化小数位 // 在这个方法中int roundingMode具体的参数如下 BigDecimal.ROUND_UP; //向远离0的方向舍入,进位处理,2.35变为2.4 BigDecimal.ROUND_DOWN; // 向零方向舍入,3.35变为3.3 BigDecimal.ROUND_CEILING; // 向正无穷方向舍入 BigDecimal.ROUND_FLOOR; // 向负无穷方向舍入 BigDecimal.ROUND_HALF_UP; // 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6 BigDecimal.ROUND_HALF_DOWN; // 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5 BigDecimal.ROUND_HALF_EVEN; // 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用 BigDecimal.ROUND_UNNECESSARY; // 计算结果是精确的,不需要舍入模式

上面的BigDecimal.舍入方式已经过时,改为RoundingMode.舍入方式 如下图: 在这里插入图片描述

具体示例 double n = sc.nextDouble(); // 输入一个数 int k = sc.nextInt(); // 保留 k 位小数 double x = 100.0 * n / 7; BigDecimal bd = new BigDecimal(x); // 获取 bd = bd.setScale(k, RoundingMode.HALF_UP); // 设置保留k位,舍入方式 RoundingMode.HALF_UP:四舍五入 注意事项

对于RoundingMode.HALF_UP行为,如果丢弃的分数的左边的数字是奇数的; 像RoundingMode.HALF_DOWN如果它是RoundingMode.HALF_DOWN行为。 请注意,这是舍入模式,统计最小化在一系列计算中重复应用时的累积误差。 有时被称为“银行家四舍五入”,主要用于美国。 这种舍入模式类似于Java中用于float和double算术的舍入策略。

如何理解这句话呢?

有一个规则:

四舍六入五考虑, 五后非零就进一, 五后皆零看奇偶, 五前为偶应舍去, 五前为奇要进一。

就是四舍六入,5单独考虑,如果 5 后面有非0数那就进1,如果5后面全为0,那就看5前的数是奇数还是偶数,奇数就进1,偶数就舍去。

这样舍入模式称作“银行家四舍五入”,感觉像是以前美国的银行家,搞的舍入方式,不然遇到5就进1,若是5后面么有零头,全是零,直接进位就不太好,这样舍入对于偶数,奇数可以均分一下,这样操作可以均衡进位与舍入吧。

小数点后保留指定n位数

上面谈了这么久,下面引入正题 小数点后保留指定n位数。

printf()

经常使用的 System.out.printf(),想着能不能指定保留的位数 k。

比如: 保留2位 printf("%.2f") 能不能这样保留 k 位? printf("%.kf")

System.out.printf("%.(%n)f", k, n); × 发现不可以 o(╥﹏╥)o

后来发现大佬的C语言题解,有一种方法:

#include int main() { #ifdef LOCAL freopen("E:\input.txt", "r", stdin); #endif char s[] = "%.0f%%\n"; int t, n, k; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &k); printf((s[2] = k + '0', s), 100.0 * n / 7); } return 0; }

试着改成Java版:

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); char[] s = {'%', '.', '0', 'f', '%', '%', '\n'}; while (t-- > 0) { int n = sc.nextInt(); int k = sc.nextInt(); s[2] = (char)(k + '0'); // '0' ASCII:48 System.out.printf(new String(s), 100.0 * n / 7); } } }

结果如下:

在这里插入图片描述 在这里插入图片描述

BigDecimal

参考上面介绍: BigDecimal.setScale(int newScale, int roundingMode);

double n = sc.nextDouble(); int k = sc.nextInt(); // 保留 k 位 double x = 100.0 * n / 7; BigDecimal bd = new BigDecimal(x); bd = bd.setScale(k, RoundingMode.HALF_UP); // 设置 保留位数,及舍入方式:四舍五入 System.out.println(bd);

结果如下: 在这里插入图片描述

特别注意 在练习使用过程中,发现一个特殊的地方:

当浮点数位 0 时,保留 k 位小数,输出结果会有变化:

在这里插入图片描述

这算一个特殊的地方,比赛时试了几次,一直错误,罚时++ o(╥﹏╥)o

后来我们对 0 的情况特殊考虑,就 AK 了!

题目大意:

计算 n 门 course 成绩,计算平均成绩,并保留指定位数。

代码如下:

int n = sc.nextInt(); int k = sc.nextInt(); double sum = 0; for (int i = 0; i BigDecimal bd = new BigDecimal(sum); BigDecimal N = new BigDecimal(n); bd = bd.divide(N, k, RoundingMode.FLOOR); // 除 N,保留 k位,舍入方式:下舍入 System.out.println(bd); } else { System.out.print(0+"."); for(int i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有