Java 将双精度舍入到小数点后 1 位 kotlin:从 0.044999 到 0.1

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49011924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:56:43  来源:igfitidea点击:

Round Double to 1 decimal place kotlin: from 0.044999 to 0.1

javaandroidkotlinrounding

提问by Noelia

I have a Double variable that is 0.0449999and I would like to round it to 1 decimal place 0.1.

我有一个 Double 变量,0.0449999我想将它四舍五入到小数点后一位0.1

I am using Kotlin but the Java solution is also helpful.

我正在使用 Kotlin,但 Java 解决方案也很有帮助。

val number:Double = 0.0449999

val number:Double = 0.0449999

I tried getting 1 decimal place with these two solutions:

我尝试使用这两种解决方案获得 1 个小数位:

  1. val solution = Math.round(number * 10.0) / 10.0
  2. val solution = String.format("%.1f", number)
  1. val solution = Math.round(number * 10.0) / 10.0
  2. val solution = String.format("%.1f", number)

The problem is that I get 0.0 in both cases because it rounds the number from 0.04to 0.0. It doesn't take all decimals and round it.

问题是我在这两种情况下都得到 0.0,因为它将数字从0.040.0。它不会取所有小数并四舍五入。

I would like to obtain 0.1: 0.045 -> 0.05 -> 0.1

我想获得 0.1: 0.045 -> 0.05 -> 0.1

采纳答案by Noelia

Finally I did what Andy Turnersuggested, rounded to 3 decimals, then to 2 and then to 1:

最后我做了什么Andy Turner建议,四舍五入到 3 位小数,然后到 2,然后到 1:

Answer 1:

答案 1:

val number:Double = 0.0449999
val number3digits:Double = String.format("%.3f", number).toDouble()
val number2digits:Double = String.format("%.2f", number3digits).toDouble()
val solution:Double = String.format("%.1f", number2digits).toDouble()

Answer 2:

答案 2:

val number:Double = 0.0449999
val number3digits:Double = Math.round(number * 1000.0) / 1000.0
val number2digits:Double = Math.round(number3digits * 100.0) / 100.0
val solution:Double = Math.round(number2digits * 10.0) / 10.0

Result:

结果

0.045 → 0.05 → 0.1

0.045 → 0.05 → 0.1

Note: I know it is not how it should work but sometimes you need to round up taking into account all decimals for some special cases so maybe someone finds this useful.

注意:我知道这不是它应该如何工作,但有时您需要考虑到某些特殊情况下的所有小数,所以也许有人会觉得这很有用。

回答by hotkey

The BigDecimalrounding features several RoundingModes, including those rounding up (away from zero) or towards positive infinity. If that's what you need, you can perform rounding by calling setScaleas follows:

所述BigDecimal舍入具有几个RoundingModeS,包括那些围捕(远离零)或朝向正无穷大。如果这就是您所需要的,您可以通过setScale如下调用来执行舍入:

val number = 0.0449999
val rounded = number.toBigDecimal().setScale(1, RoundingMode.UP).toDouble()
println(rounded) // 0.1

Note, however, that it works in a way that will also round anything between 0.0and 0.1to 0.1(e.g. 0.000010.1).

但是请注意,它的工作原理的方式,之间也将圆东西0.0,并0.10.1(例如0.000010.1)。

The .toBigDecimal()extension is available since Kotlin 1.2.

.toBigDecimal()扩展从 Kotlin 1.2 开始可用。

回答by Willi Mentzel

1. Method (using Noelia's idea):

1.方法(使用Noelia的想法):

You can pass the number of desired decimal places in a string template and make the precision variable this way:

您可以在字符串模板中传递所需的小数位数,并以这种方式设置精度变量:

fun Number.roundTo(numFractionDigits: Int) 
 = String.format("%.${numFractionDigits}f", toDouble()).toDouble()

2. Method (numeric, no string conversion)

2.方法(数字,无字符串转换)

fun roundToDecimals(number: Double, numDecimalPlaces: Int): Double {
    val factor = Math.pow(10.0, numDecimalPlaces.toDouble())
    return Math.round(number * factor) / factor
}

回答by Gaurang Goda

I know some of the above solutions works perfectly but I want to add another solution which uses ceil and floor concept, which I think is optimized for all the cases.

我知道上述一些解决方案非常有效,但我想添加另一个使用 ceil 和 floor 概念的解决方案,我认为它已针对所有情况进行了优化。

If you want the highest value of the 2 digits after decimal uses this.

如果您想要小数点后 2 位数字的最高值,请使用此值。

 -import java.math.BigDecimal 
 -import java.math.RoundingMode
 -import java.text.DecimalFormat

here, 1.45678 = 1.46

这里,1.45678 = 1.46

fun roundOffDecimal(number: Double): Double? {
        val df = DecimalFormat("#.##")
        df.roundingMode = RoundingMode.CEILING
        return df.format(number).toDouble()
    }

If you want the lowest value of the 2 digits after decimal uses this.

如果您想要小数点后两位数的最小值,请使用此值。

here, 1.45678 = 1.45

这里,1.45678 = 1.45

fun roundOffDecimal(number: Double): Double? {
        val df = DecimalFormat("#.##")
        df.roundingMode = RoundingMode.FLOOR
        return df.format(number).toDouble()
    }

There are also other Flags like below 1.FLOOR 2.CEILING 3.DOWN 4.HALFDOWN 5.HALFEVEN 6.HALFUP 7.UNNECESSARY 8.UP

还有其他标志如下 1.FLOOR 2.CEILING 3.DOWN 4.HALFDOWN 5.HALFEVEN 6.HALFUP 7.UNNECESSARY 8.UP

The detailed information is given in docs

详细信息在文档中给出

回答by Ignacio Garcia

An example of extension functions for Float and Double, round to n decimal positions.

Float 和 Double 的扩展函数示例,四舍五入到 n 个小数位。

    fun Float.roundTo(n : Int) : Float {
      return "%.${n}f".format(this).toFloat()
    }
    fun Double.roundTo(n : Int) : Double {
      return "%.${n}f".format(this).toDouble()
    }

回答by kotoMJ

Always beware of Locale!

始终提防语言环境!

With unspecified locale you can get occasional issue (e.g. with Portugies locale) such as

使用未指定的语言环境,您可能会偶尔遇到问题(例如葡萄牙语言环境),例如

Fatal Exception: java.lang.NumberFormatException
For input string: "0,1"

1. Solution using DecimalFormat approach

1.使用DecimalFormat方法的解决方案

fun Float.roundToOneDecimalPlace(): Float {
    val df = DecimalFormat("#.#", DecimalFormatSymbols(Locale.ENGLISH)).apply {
        roundingMode = RoundingMode.HALF_UP
    }
    return df.format(this).toFloat()
}

2. Solution using string format approach

2. 使用字符串格式方法的解决方案

fun Float.roundTo(decimalPlaces: Int): Float {
    return "%.${decimalPlaces}f".format(Locale.ENGLISH,this).toFloat()
}