У меня есть переменная Double, 0.0449999, и я хотел бы округлить ее до 1 десятичного знака 0.1.

Я использую Kotlin, но решение Java также полезно.

val number:Double = 0.0449999

Я попытался получить 1 десятичное место с этими двумя решениями:

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

Проблема в том, что я получаю 0.0 в обоих случаях, потому что оно округляет число от 0.04 до 0.0. Это не занимает все десятичные дроби и вокруг него.

Я хотел бы получить 0,1: 0.045 -> 0.05 -> 0.1

73
Noelia 27 Фев 2018 в 18:09

6 ответов

Лучший ответ

Наконец, я сделал то, что Andy Turner предложил, округлил до 3 десятичных знаков, затем до 2 и затем до 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()

Ответ 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

< Сильный > Результат :

0,045 → 0,05 → 0,1

Примечание: я знаю, что это не так, как это должно работать, но иногда вам нужно округлить с учетом всех десятичных знаков для некоторых особых случаев, поэтому, возможно, кто-то найдет это полезным.

58
Noelia 10 Апр 2020 в 10:52

Я знаю, что некоторые из вышеперечисленных решений работают отлично, но я хочу добавить другое решение, которое использует концепцию ceil и floor, которое, я думаю, оптимизировано для всех случаев.

Если вы хотите получить наибольшее значение из 2 цифр после десятичного числа, используйте это.

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

Здесь 1,45678 = 1,46

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

Если вы хотите использовать наименьшее значение из 2 цифр после десятичного числа, используйте это .

Здесь 1,45678 = 1,45

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

Есть и другие флаги, как показано ниже < Сильный > < EM> 1.этаж 2.CEILING 3.DOWN 4.HALFDOWN 5.HALFEVEN 6.HALFUP 7.UNNECESSARY 8.UP

Подробная информация приведена в документации.

16
Gaurang Goda 14 Май 2019 в 15:20

Пример функций расширения для 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()
    }
6
Ignacio Garcia 28 Дек 2019 в 17:15

Всегда остерегайтесь локали!

В случае неуказанной локали вы можете получить случайную проблему (например, в локали Португалии), такую как

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

< Сильный > 1 . Решение с использованием подхода DecimalFormat

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

< Сильный > 2 . Решение с использованием строкового формата

fun Float.roundTo(decimalPlaces: Int): Float {
    return "%.${decimalPlaces}f".format(Locale.ENGLISH,this).toFloat()
}
4
kotoMJ 8 Апр 2020 в 08:39

< Сильный > 1 . Метод (используя идею Ноэли):

Вы можете передать количество желаемых десятичных разрядов в строковом шаблоне и сделать переменную точности следующим образом:

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

< Сильный > 2 . Метод (числовой, без преобразования строк)

fun roundToDecimals(number: Double, numDecimalPlaces: Int): Double {
    val factor = Math.pow(10.0, numDecimalPlaces.toDouble())
    return Math.round(number * factor) / factor
}
8
Willi Mentzel 5 Авг 2018 в 08:24

BigDecimal имеет несколько округлений RoundingMode, в том числе округление (от нуля) или к положительной бесконечности. Если это то, что вам нужно, вы можете выполнить округление, вызвав setScale следующим образом:

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

Обратите внимание, однако, что он работает таким образом, что также округляет все между 0.0 и 0.1 до 0.1 (например, 0.000010.1).

Доступно .toBigDecimal() расширение. начиная с Kotlin 1.2.

33
hotkey 27 Фев 2018 в 15:53