【问题标题】:How can I truncate a double to only two decimal places in Java?如何在 Java 中将双精度数截断为仅两位小数?
【发布时间】:2011-10-12 22:46:26
【问题描述】:

例如,我有变量 3.545555555,我想将其截断为 3.54。

【问题讨论】:

  • 这不是重复的。截断和舍入是两个完全不同的东西。
  • 同意,不知道为什么会被标记为重复。

标签: java double truncate decimalformat


【解决方案1】:

如果您希望将其用于显示目的,请使用 java.text.DecimalFormat:

 new DecimalFormat("#.##").format(dblVar);

如果您需要它进行计算,请使用java.lang.Math

 Math.floor(value * 100) / 100;

【讨论】:

  • 这将显示截断的 3.545555555 到 3.54,而是四舍五入到 3.55。 DecimalFormat.setRoundingMode() 需要设置为 RoundingMode.FLOOR;
  • 这对我不起作用 Math.floor(9.62 * 100) / 100 给出 9.61
  • 使用floor 截断仅适用于正值。
  • 第二种方法并不总是有效,检查:Math.floor(2.28 * 100)/100 = 2.27
【解决方案2】:
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

检查可用的RoundingModeDecimalFormat

【讨论】:

  • 未解决要求截断而不是舍入的问题。
  • @BasilBourque RoundingMode.DOWN 是截断。与其他错误地推荐地板函数的答案(地板只截断正数)相比,这对正值和负值都适用。
  • @Dev 我已得到纠正。我现在看到DOWN 确实具有截断正数和负数的效果。如the doc 中的示例表所示。
【解决方案3】:

其他答案均不适用于正值和负值(我的意思是用于计算,只是在不进行舍入的情况下进行“截断”)。并且不转换为字符串。

来自How to round a number to n decimal places in Java 链接

private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
    if ( x > 0) {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
    } else {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
    }
}

这个方法对我很有效。

System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));

结果:

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00

【讨论】:

  • 这是更多测试用例的可扩展性答案
  • return new BigDecimal(x).setScale(numberofDecimals, RoundingMode.DOWN).doubleValue();
  • 似乎向下取整就像你的意思:docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html
  • @ShimonDoodkin String.valueOf(x) 是必需的,否则它会在例如2.28、9.62 或 9411.3
【解决方案4】:

首先请注意,double 是二进制分数,实际上没有 个小数位。

如果您需要小数位,请使用BigDecimal,它有一个setScale() 截断方法,或者使用DecimalFormat 得到一个String

【讨论】:

    【解决方案5】:

    如果出于某种原因不想使用BigDecimal,您可以将double 转换为int 以截断它。

    如果你想截断到 Ones 的地方:

    • 只需转换为int

    十分之一的地方:

    • 乘以十
    • 投到int
    • 转回double
    • 除以十。

    • 乘以除以 100 等。

    例子:

    static double truncateTo( double unroundedNumber, int decimalPlaces ){
        int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
        double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
        return truncatedNumber;
    }
    

    在此示例中,decimalPlaces 将是您想去的地方 PAST 的位置数,因此 1 将四舍五入到 十分位,2 将四舍五入到 百分之一 em>,依此类推(0 舍入到 位,负一到十位,等等)

    【讨论】:

    • 这是一个糟糕的通用解决方案。如果unroundedNumber 足够大,则乘法和强制转换最终都会丢弃数据并产生有效的随机数。它可能适用于问题中的示例,但通用解决方案应该适用于任何double
    • 不能正常工作,例如2.28、9.62 或 9411.3
    【解决方案6】:

    格式化为字符串并转换回双精度我认为会给你想要的结果。

    double 值不会是 round()、floor() 或 ceil()。

    一个快速的解决方法可能是:

     String sValue = (String) String.format("%.2f", oldValue);
     Double newValue = Double.parseDouble(sValue);
    

    您可以使用 sValue 进行显示或使用 newValue 进行计算。

    【讨论】:

    • 它确实对我来说四舍五入到最接近的值。例如:当我这样做时,0.018 被转换为 0.02。
    【解决方案7】:

    您可以使用 NumberFormat 类对象来完成任务。

    // Creating number format object to set 2 places after decimal point
    NumberFormat nf = NumberFormat.getInstance();
    nf.setMaximumFractionDigits(2);            
    nf.setGroupingUsed(false);
    
    System.out.println(nf.format(precision));// Assuming precision is a double type variable
    

    【讨论】:

    • 我还要加nf.setMinimumFractionDigits(2);
    【解决方案8】:

    3.545555555 得到 3.54。 尝试关注这个:

        DecimalFormat df = new DecimalFormat("#.##");
    
        df.setRoundingMode(RoundingMode.FLOOR);
    
        double result = new Double(df.format(3.545555555);
    

    这将给出= 3.54!

    【讨论】:

    • 但是如果我将这个值设置为 3.50123,我会得到 3.5
    • @Cyrus 3.5 是 3.50123 的正确结果。 trunc(2) 之类的函数应该将其截断为 3.50。
    【解决方案9】:

    也许是Math.floor(value * 100) / 100?请注意,3.54 之类的值可能无法用 double 精确表示。

    【讨论】:

    • 不幸的是,有一些反例不起作用:double value = 9411.3; System.out.println(Math.floor(值 * 100) / 100); // 9411.29
    • 不能正常工作,例如2.28、9.62 或 9411.3
    • @DKroot:取决于你所说的“正确”。当你说double value = 2.28;时,你的value实际上是2.279999999999999804600747665972448885440826416015625,所以在截断之后你会得到一个诚实的2.27。在我看来,问题不在于截断,问题在于分配。
    • 我知道二进制精度损失。这就是为什么 trunc() 是一个危险的操作。但是,“正确”是指“从用户/数学角度预期”:例如assert(2.28.trunc(2)) == 2.28 其中trunc(precision) 是一种截断方法。例如,请参阅这篇博文(不是我的):blog.mrhaki.com/2010/01/groovy-goodness-round-and-truncate.html
    • @DKroot:这是行“double d = 2.28;”从天真的用户的角度来看,它的行为是错误的。你一定知道,没有像 2.28 这样的双数,对吧?我的代码将 2.279999... 视为输入,并且它没有任何线索(而且一定没有!)该论点来自不合理的假设,即它实际上必须是 2.28 十进制。代码获取严格小于 2.28 的数字,并产生正确的结果。
    【解决方案10】:

    这是我使用的方法:

    double a=3.545555555; // just assigning your decimal to a variable
    a=a*100;              // this sets a to 354.555555
    a=Math.floor(a);      // this sets a to 354
    a=a/100;              // this sets a to 3.54 and thus removing all your 5's
    

    也可以这样做:

    a=Math.floor(a*100) / 100;
    

    【讨论】:

    • 无法正常工作,例如2.28、9.62 或 9411.3
    【解决方案11】:

    可能如下:

    double roundTwoDecimals(double d) { 
          DecimalFormat twoDForm = new DecimalFormat("#.##"); 
          return Double.valueOf(twoDForm.format(d));
    }  
    

    【讨论】:

    • 查看其他答案。如果答案要用浮点数表示,你就不能可靠地做到这一点。
    【解决方案12】:

    快速检查是使用 Math.floor 方法。我创建了一种方法来检查以下两个或更少小数位的双精度数:

    public boolean checkTwoDecimalPlaces(double valueToCheck) {
    
        // Get two decimal value of input valueToCheck 
        double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;
    
        // Return true if the twoDecimalValue is the same as valueToCheck else return false
        return twoDecimalValue == valueToCheck;
    }
    

    【讨论】:

      【解决方案13】:
            double value = 3.4555;
            String value1 =  String.format("% .3f", value) ;
            String value2 = value1.substring(0, value1.length() - 1);
            System.out.println(value2);         
            double doublevalue= Double.valueOf(value2);
            System.out.println(doublevalue);
      

      【讨论】:

      • 欢迎来到 StackOverflow 并祝贺您的​​第一个答案。虽然您发布的代码可能解决了原始发帖人提出的问题,但您应该添加几句话来解释您的解决方案如何比(许多)其他答案更好或更适合某些特定情况。
      【解决方案14】:

      我使用了 Math.floor() 方法和基本的小数位移动 (100 = 2)。

      //3.545555555 to 3.54 by floor method
      double x = 3.545555555;
      double y = Math.floor(x * 100); //354
      double z = y / 100; //3.54
      

      【讨论】:

        【解决方案15】:

        我有一个稍微修改过的Mani 的版本。

        private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
            return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
        }
        
        public static void main(String[] args) {
            System.out.println(truncateDecimal(0, 2));
            System.out.println(truncateDecimal(9.62, 2));
            System.out.println(truncateDecimal(9.621, 2));
            System.out.println(truncateDecimal(9.629, 2));
            System.out.println(truncateDecimal(9.625, 2));
            System.out.println(truncateDecimal(9.999, 2));
            System.out.println(truncateDecimal(3.545555555, 2));
        
            System.out.println(truncateDecimal(9.0, 2));
            System.out.println(truncateDecimal(-9.62, 2));
            System.out.println(truncateDecimal(-9.621, 2));
            System.out.println(truncateDecimal(-9.629, 2));
            System.out.println(truncateDecimal(-9.625, 2));
            System.out.println(truncateDecimal(-9.999, 2));
            System.out.println(truncateDecimal(-9.0, 2));
            System.out.println(truncateDecimal(-3.545555555, 2));
        
        }
        

        输出:

        0.00
        9.62
        9.62
        9.62
        9.62
        9.99
        9.00
        3.54
        -9.62
        -9.62
        -9.62
        -9.62
        -9.99
        -9.00
        -3.54
        

        【讨论】:

          【解决方案16】:

          这对我有用:

          double input = 104.8695412  //For example
          
          long roundedInt = Math.round(input * 100);
          double result = (double) roundedInt/100;
          
          //result == 104.87
          

          我个人喜欢这个版本,因为它实际上以数字方式执行舍入,而不是通过将其转换为字符串(或类似的)然后对其进行格式化。

          【讨论】:

          • 最初的问题是关于截断,而不是四舍五入。此外,如果 double 足够大,将 double 转换为 long 将根本无法正常工作。
          猜你喜欢
          • 1970-01-01
          • 2012-11-10
          • 2020-10-05
          • 1970-01-01
          • 2017-12-18
          • 1970-01-01
          • 1970-01-01
          • 2011-08-08
          • 2013-08-27
          相关资源
          最近更新 更多