前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何取一个数字到N位小数点

如何取一个数字到N位小数点

作者头像
索码理
发布2022-12-28 14:54:50
8980
发布2022-12-28 14:54:50
举报
文章被收录于专栏:索码理

Java提供了两种数据类型存储小数:doublefloatdouble是默认的小数类型,比如:

代码语言:javascript
复制
double PI = 3.1415;

如果想使用float则需要在小数后面加上f,否则会报错

代码语言:javascript
复制
float f = 3.14159f;

然而,当使用精确数值的时候这两种类型都不能使用,例如金钱和四舍五入。此时我们可以使用java.math.BigDecimal类。

如果取一个数字到N位小数点,要怎么做呢?

这里总结有两种方式:格式化和四舍五入。

格式化

如果只是想打印n位小数,可以使用字符串格式化进行打印:

代码语言:javascript
复制
System.out.printf("格式化成小数点后3位: %.3f %n", PI);
//打印结果:格式化成小数点后3位: 3.142

如果想要格式化成某个值,可以使用java.text.DecimalFormat类,比如:

代码语言:javascript
复制
 public static void bigDecimalFormatting(double PI){
    DecimalFormat df = new DecimalFormat("###.###");
    System.out.println(df.format(PI));
}
//打印结果:3.142

DecimalFormat允许显式地设置舍入行为,比上面使用的String.format()提供更多的输出控制。

四舍五入

使用BigDecimal四舍五入

可以写一个工具方法使用BigDecimal四舍五入double类型数值

代码语言:javascript
复制
private static double round(double value, int places) {
    if (places < 0) {
        throw new IllegalArgumentException();
    }

    BigDecimal bd = new BigDecimal(Double.toString(value));
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    double doubleValue = bd.doubleValue();
    System.out.println( doubleValue);
    return doubleValue;
}
代码语言:javascript
复制
public static void main(String[] args) {
    double PI = 3.141592;
    round(PI , 3);
}
// 输出:3.142

使用BigDecimal时,重要的一点要「特别注意」「当使用BigDecimal的构造方法时,一定要使用BigDecimal(String)构造方法」,要不然可能会精度问题出现,得不到想要的结果。

除了写工具类之外,也可以引入Apache Commons Math 依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-math3</artifactId>
    <version>3.6.1</version>
</dependency>

引入依赖之后可以使用Precision.round()方法,它也是对BigDecimal的封装

代码语言:javascript
复制
double value = Precision.round(PI, 3);
System.out.println(value);
//打印结果:3.142

默认情况下,Precision.round()方法是BigDecimal.ROUND_HALF_UP舍入方式的,和上面写的round()方法一样,所以结果也是一样的。

使用DoubleRounder四舍五入

DoubleRounder是decimal4j库中的一个工具类,它提供了从0到18位小数点快速且使用Garbage-free思想(避免或减少对象的创建)的四舍五入方法。

依赖如下:

代码语言:javascript
复制
<dependency>
    <groupId>org.decimal4j</groupId>
    <artifactId>decimal4j</artifactId>
    <version>1.0.3</version>
</dependency>

简单使用一下:

代码语言:javascript
复制
public static void doubleRounder(double PI){
    double round = DoubleRounder.round(PI, 3);
    System.out.println(round);
}
// 打印结果:3.142

但是,某些场景下DoubleRounder会出现精度问题,比如:

代码语言:javascript
复制
System.out.println(DoubleRounder.round(256.025d, 2));

本来应该打印的是256.03结果打印的却是256.03

Math.round()方法

另一种对小数进行舍入的方法是Math.round()方法。

在这种情况下,我们可以通过乘和除以10^n来控制小数点后n位:

代码语言:javascript
复制
public static double roundAvoid(double value, int places) {
    double scale = Math.pow(10, places);
    double v = Math.round(value * scale) / scale;
    System.out.println(v);
    return v;
}
//打印结果:3.142

这个方法列出来只用于学习的目的,「不建议使用此方法,因为它会截断值」。在很多情况下舍入的值都是不正确的。

代码语言:javascript
复制
roundAvoid(1000.0d, 17);
// 打印结果: 92.23372036854776
roundAvoid(260.775d, 2);
// 打印的是 260.77 而不是预想的 260.78

总结

本篇文章介绍了不同的方式取一个数字到N位小数点,我们可以在不改变值的情况下进行格式化输入,也可以通过四舍五入的方式进行取值,同时也列举出几个类库来解决四舍五入的问题。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 索码理 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 格式化
  • 四舍五入
    • 使用BigDecimal四舍五入
      • 使用DoubleRounder四舍五入
        • Math.round()方法
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档