JAVA基础-数字格式化

Java 中的数字格式化

学习Java中不同的数字格式化方法,以及如何实现。

1. 基础方法:String.format

String.format 方法对于格式化数字非常有用。并且不仅仅在格式化数字上有用,更详细的使用可以查看Java基础-格式化输出

String.format官方语法说明。一般、字符和数字类型的格式说明符具有以下语法:

%[argument_index$][flags][width][.precision]conversion

言归正传,下面看看在数字格式化方面能有什么作用吧。可以用来格式化数字的格式化符号有以下几个:

格式化符号 是否常用 用途
d 结果被格式化为十进制整数,用于整数
o 结果被格式化为八进制整数,用于整数
x, X 结果被格式化为十六进制整数,用于整数
e, E 结果被格式化为计算机科学记数法中的十进制数,用于浮点数
f 结果被格式化为十进制数,用于浮点数
g, G 根据四舍五入后的精度和值,使用计算机化的科学记数法或十进制格式对结果进行格式化,用于浮点数
a, A 结果被格式化为带有尾数和指数的十六进制浮点数。 BigDecimal 类型不支持此转换,尽管后者属于浮点参数类别,用于浮点数
% 输出'%'

实例1:格式化正数,左对齐输出

int num = 2022;
int num2 = 22;
System.out.printf("这个一个整数:%4d\n", num);
System.out.printf("这个一个整数:%04d\n", num2);

// 输出
// 这个一个整数:2022
// 这个一个整数:0022

实例2:格式化浮点数

double pi = 3.1415d;
double pi2 = 3.1415926d;
// 如果不指定精度 默认保留6位小数,不足6位的后面补0
System.out.printf("原样输出:%f\n", pi);
System.out.printf("原样输出:%f\n", pi2);

// 四舍五入 保留5位小数
System.out.printf("原样输出:%.5f\n", pi);
System.out.printf("原样输出:%.5f\n", pi2);

// 输出
// 默认输出:3.141500
// 默认输出:3.141593
// 指定精度:3.14150
// 指定精度:3.14159

2. 使用BigDecimal

BigDecimal 类提供用于算术、比例操作、舍入、比较、散列和格式转换的操作。 toString() 方法提供了 BigDecimal 的规范表示。

BigDecimal官方语法说明

在阿里云的开发手册中写道:

【强制】禁止使用构造方法 BigDecimal(double) 的方式把 double 值转化为 BigDecimal 对象。 说明:BigDecimal(double) 存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。

float f1 = 3.141592678F;

// 新建一个BigDecimal对象,位了避免丢失精度,使用根据浮点数的toString()方法
BigDecimal bigDecimal1 = new BigDecimal(Float.toString(f1));
// 四舍五入 保留5位小数 第一格参数指定精度,第二个参数指定舍入模式
bigDecimal1 = bigDecimal1.setScale(5, RoundingMode.HALF_UP);

System.out.println(3.14159 == bigDecimal1.doubleValue());

// 输出
// true

double D = 4.2352989244D;
assertThat(withBigDecimal(D, 2)).isEqualTo(4.24);
assertThat(withBigDecimal(D, 3)).isEqualTo(4.235);

public static double withBigDecimal(double value, int places) {
    BigDecimal bigDecimal = new BigDecimal(value);
    bigDecimal = bigDecimal.setScale(places, RoundingMode.HALF_UP);
    return bigDecimal.doubleValue();
}

3. 使用Math.round

Math.round官方语法说明

使用Math静态方法去格式化浮点数,不是直接的而是通过“乘除法”。

double scale1 = Math.pow(10, 5);
double newPi1 = Math.round(pi2 * scale1) / scale1;
System.out.println("四舍五入 保留5位小数:" + newPi1);

double scale2 = Math.pow(10, 3);
double newPi2 = Math.round(pi2 * scale2) / scale2;
System.out.println("四舍五入 保留3位小数:" + newPi2);

// 输出
// 四舍五入 保留5位小数:3.14159
// 四舍五入 保留3位小数:3.142

这种方法要慎用,如果数值本身就比较大,再进行乘法的话,很容易就溢出了,造成结果错误。

再有就是round,是用来取整的,会对数据进行截断,也会造成数据不是预期。

所以请注意,列出此方法仅用于学习目的。

4. 使用DecimalFormat

DecimalFormat 是 NumberFormat 的具体子类,用于格式化十进制数。它具有多种功能,旨在使在任何区域设置中解析和格式化数字成为可能,包括对西方、阿拉伯和印度数字的支持。它还支持不同类型的数字,包括整数 (123)、定点数 (123.4)、科学记数法 (1.23E4)、百分比 (12%) 和货币金额 ($123)。所有这些都可以本地化。

功能非常强大,DecimalFormat官方语法说明

4.1 用逗号格式化大整数

// 使用默认语言环境的模式。
DecimalFormat decimalFormatDefault = new DecimalFormat();
System.out.println("默认输出:" + decimalFormatDefault.format(123456789L));

// 输出
// 默认输出:123,456,789

4.2 在小数点后面填充“0”

DecimalFormat decimalFormatPattern2 = new DecimalFormat("#.00");
System.out.println("自定义格式:" + decimalFormatPattern2.format(11D));
System.out.println("自定义格式:" + decimalFormatPattern2.format(12.0));

// 输出
// 自定义格式:11.00
// 自定义格式:12.00

5. 百分比格式化

实例1: 使用NumberFormat

NumberFormat 是所有数字格式的抽象基类。此类提供用于格式化和解析数字的接口。 NumberFormat 还提供了一些方法来确定哪些语言环境具有数字格式,以及它们的名称是什么。

// 返回当前默认 FORMAT 语言环境的百分比格式。
NumberFormat numberFormatPercent = NumberFormat.getPercentInstance();
System.out.println("默认环境输出:" + numberFormatPercent.format(0.15));
System.out.println("默认环境输出:" + numberFormatPercent.format(25F / 100F));

// 输出
// 默认环境输出:15%
// 默认环境输出:25%

实例2: 使用String.format

System.out.printf("增加百分号:%d%%", 25);
// 输出
// 增加百分号:25%

可以看到两种方法的区别,NumberFormat格式化之前会先进行计算,String.format只会格式化输出,不会对数字进行计算。

6. 货币数字格式化

// 返回当前默认 FORMAT 语言环境的货币格式。
NumberFormat numberFormatCurrency = NumberFormat.getCurrencyInstance();
System.out.println("默认环境输出:" + numberFormatCurrency.format(123.45D));

NumberFormat numberFormatCurrencyUS = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println("美国环境输出:" + numberFormatCurrencyUS.format(123.45D));

// 输出
// 默认环境输出:¥123.45
// 美国环境输出:$123.45

如果数字比较大,会输出位科学记数法格式。

// 返回当前默认 FORMAT 语言环境的货币格式。
NumberFormat numberFormatCurrency = NumberFormat.getCurrencyInstance();
System.out.println("默认环境输出:" + numberFormatCurrency.format(123456.78D));

NumberFormat numberFormatCurrencyUS = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println("美国环境输出:" + numberFormatCurrencyUS.format(123456.78D));

// 输出
// 默认环境输出:¥123,456.78
// 美国环境输出:$123,456.78

结尾

Java 中数字格式化的不同方式。正如我们所看到的,没有一种最好的方法可以做到这一点。可以使用多种方法,因为每种方法都有自己的特点。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容