要让数字显示不同的格式,比如 指定小数显示的位数。
可以用以下几种方法:
1. 使用 String.format()
String.format()
方法类似于 C 语言中的 printf
,可以用于格式化数字。
String.format("%.2f", 1.2345)
返回的结果是String,内容是1.23, 第一个参数是格式化参数,其中%后面就是指定格式,也就是%开始到d或f等结束, 会当作一个格式化参数,其他的字符会原样输出。
常见格式化参数:
%d
:格式化为整数。%f
:格式化为小数,默认保留 6 位小数。%.nf
:n
表示保留的小数位数, 四舍五入。%,.nf
:n
表示保留的小数位数,并使用千分位分隔符。%e
或%E
:格式化为科学计数法。%g
或%G
:自动选择普通或科学计数法(如果数很大或很小就会用科学计数法)%o
:格式化为八进制整数。%x
或%X
:格式化为十六进制整数。%#x
: 会在前面加0x, 如果是%#o, 会在前面加0
示例代码:
public class StringFormatExample {
public static void main(String[] args) {
double d = 123.45678;
String s = String.format("%.2f", d);
System.out.println(s); // 输出: 123.46
// System.out.printf()可以直接输出格式化的值, 格式化参数和String.format()用法一样
// %n 和 \n都是换行符
System.out.printf("%f%n", d); // 输出: 123.456780
System.out.printf("%,.2f\n", d); // 输出: 12,345.68
System.out.printf("%.0f\n", d); // 输出: 123
System.out.printf("输出结果:%.1f保留一位小数\n", d); // 输出: 输出结果:123.5保留一位小数
System.out.printf("%e\n", d); // 输出: 1.234568e+02
int i = 255;
System.out.printf("%x%n", i); // 输出: ff
System.out.printf("%X%n", i); // 输出: FF
System.out.printf("%#X%n", i); // 输出: 0XFF
System.out.printf("%d%n", 0xFF); // 输出: 255
System.out.printf("%#o%n", 16); // 输出: 020
}
}
格式化参数还有很多其他用法。
如果是控制输出几位小数就推荐用这种方法。
2. 使用 BigDecimal
进行精确控制
用double一般情况下没问题, 如果是float用上面的String.format()很可能会出问题,如:
float f = 123456.6755f;
System.out.println(f); // 输出:123456.67
System.out.printf("%.2f\n", f); // 输出:123456.67 , 正确的应该是123456.68
System.out.printf("%.3f\n", f); // 输出:123456.672
出现这个问题是应为float的有效位数大概7位,所以超过位数后精度不能精确。double也能会出现这个问题,只是它的有效位数多些,一般情况下遇不到。
所以一般在涉及金融计算时,BigDecimal
是最推荐的方式,以避免浮点精度问题。
常见构造方法与参数:
BigDecimal(String val)
: 通过字符串创建BigDecimal
,避免浮点精度问题。setScale(int newScale, RoundingMode roundingMode)
: 设置小数位数,并指定舍入模式。add(BigDecimal augend)
: 加法。subtract(BigDecimal subtrahend)
: 减法。multiply(BigDecimal multiplicand)
: 乘法。divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
: 除法,指定小数位数和舍入模式。
示例代码:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class BigDecimalExample {
public static void main(String[] args) {
BigDecimal number = new BigDecimal("123456.6755");
number = number.setScale(2, RoundingMode.HALF_UP); // HALF_UP 就是四舍五入
System.out.println(number.toString()); // 输出:123456.68
}
}
3. 使用 DecimalFormat
如果不喜欢String.format()的方式, 可以用DecimalFormat
类。
常见构造方法与参数:
DecimalFormat(String pattern)
: 传入格式模式字符串。applyPattern(String pattern)
: 设置新的格式模式。setMaximumFractionDigits(int newValue)
: 设置小数部分的最大位数。setMinimumFractionDigits(int newValue)
: 设置小数部分的最小位数。
格式模式说明:
#
:表示一个可选的数字,占位但不补零。0
:表示一个必须出现的数字,不足时补零。,
:表示千分位分隔符。.
:表示小数点。%
:表示百分比,会自动乘以 100。E
:用于科学计数法。
示例代码:
import java.text.DecimalFormat;
public class DecimalFormatExample {
public static void main(String[] args) {
DecimalFormat df1 = new DecimalFormat("#,###.##");
DecimalFormat df2 = new DecimalFormat("000000.00000");
DecimalFormat df3 = new DecimalFormat("#.##%");
DecimalFormat df4 = new DecimalFormat("0.###E0");
double number = 12345.6789;
System.out.println(df1.format(number)); // 输出: 12,345.68
System.out.println(df2.format(number)); // 输出: 012345.67890
System.out.println(df3.format(0.1234)); // 输出: 12.34%
System.out.println(df4.format(number)); // 输出: 1.235E4
}
}
4. 使用 NumberFormat
NumberFormat
提供了本地化支持,如货币和百分比格式化。比如货币美国显示$, 中国显示¥
常见方法与参数:
getInstance()
:获取默认格式化实例。getCurrencyInstance(Locale locale)
:获取指定地区的货币格式。getPercentInstance(Locale locale)
:获取指定地区的百分比格式。setMaximumFractionDigits(int newValue)
: 设置小数部分的最大位数。setMinimumFractionDigits(int newValue)
: 设置小数部分的最小位数。
示例代码:
import java.text.NumberFormat;
import java.util.Locale;
public class NumberFormatExample {
public static void main(String[] args) {
NumberFormat nf1 = NumberFormat.getCurrencyInstance(); // Locale根据系统确定
NumberFormat nf2 = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat nf3 = NumberFormat.getCurrencyInstance(Locale.CHINA);
double number = 12345.6789;
System.out.println(nf1.format(number)); // 取决于系统
System.out.println(nf2.format(number)); // 输出: $12,345.68
System.out.println(nf3.format(number)); // 输出: ¥12,345.68
}
}
在多线程环境下,如果使用 DecimalFormat
或 NumberFormat
,建议使用 ThreadLocal
变量存储实例,以确保线程安全。
总结
一般应用得多的就是控制小数显示位数,这时数据用double, 显示用String.format(“%.2f”, d)来控制小数的输出位数,如果需要更高的精度,用 BigDecimal。