问题
I have a Double variable that is 0.0449999
and I would like to round it to 1 decimal place 0.1
.
I am using Kotlin but the Java solution is also helpful.
val number:Double = 0.0449999
I tried getting 1 decimal place with these two solutions:
val solution = Math.round(number * 10.0) / 10.0
val solution = String.format("%.1f", number)
The problem is that I get 0.0 in both cases because it rounds the number from 0.04
to 0.0
. It doesn't take all decimals and round it.
I would like to obtain 0.1: 0.045 -> 0.05 -> 0.1
回答1:
Finally I did what Andy Turner
suggested, rounded to 3 decimals, then to 2 and then to 1:
Answer 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:
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
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.
回答2:
The BigDecimal rounding 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 setScale as follows:
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.0
and 0.1
to 0.1
(e.g. 0.00001
→ 0.1
).
The .toBigDecimal() extension is available since Kotlin 1.2.
回答3:
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.
If you want the highest value of the 2 digits after decimal uses this.
-import java.math.BigDecimal
-import java.math.RoundingMode
-import java.text.DecimalFormat
here, 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
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
The detailed information is given in docs
回答4:
1. Method (using Noelia's idea):
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)
fun roundToDecimals(number: Double, numDecimalPlaces: Int): Double {
val factor = Math.pow(10.0, numDecimalPlaces.toDouble())
return Math.round(number * factor) / factor
}
来源:https://stackoverflow.com/questions/49011924/round-double-to-1-decimal-place-kotlin-from-0-044999-to-0-1