Kotlin: проверьте, чтобы значение Double было только от 0,0 до 1,0 с шагом 0,1 - PullRequest
0 голосов
/ 06 июня 2019

Каково было бы простое / элегантное решение для проверки, если двойное значение есть только в наборе
{.0, .1, .. .9, 1.0} значения.

Прямо сейчас я делаю

setOf(.0, .1, .2, .3, .4, .5, .6, .7, .8, .9, 1.0)

и проверьте, содержит ли значение Double.

Есть ли более простое / элегантное решение?

Ответы [ 3 ]

1 голос
/ 06 июня 2019

Так как вы действительно беспокоитесь о позиции десятков, я просто сдвинул ее один раз и проверил на 0..10:

fun Double.isSpecial() = (this * 10.0) in (0..10).map(Int::toDouble)

Тестирование с play.kotlinlang.org:

fun main() {
  listOf(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0).forEach(::checkSpecial)
  listOf(0.01, 0.11, 0.22, 1.01).forEach(::checkSpecial)
}

fun checkSpecial(value: Double) {
  println("$value isSpecial = ${value.isSpecial()}")
}

Выходы:

0.0 isSpecial = true
0.1 isSpecial = true
0.2 isSpecial = true
0.3 isSpecial = true
0.4 isSpecial = true
0.5 isSpecial = true
0.6 isSpecial = true
0.7 isSpecial = true
0.8 isSpecial = true
0.9 isSpecial = true
1.0 isSpecial = true
0.01 isSpecial = false
0.11 isSpecial = false
0.22 isSpecial = false
1.01 isSpecial = false

Если вы меньше беспокоитесь об элегантности и больше о производительности, вы можете просто сделать:

fun Double.isSpecial() = when (this) {
    0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 -> true
    else -> false
}

, что позволяет избежать выделения каких-либо наборов иливарьируется целиком.Если диапазон не является динамическим, я бы просто пошел с этим лично.

1 голос
/ 06 июня 2019

Вы можете сделать это с последовательностями .

fun contains(d: Double) = d in generateSequence(0.0) { it + 0.1 }.takeWhile { it <= 1.0 }

Если вы хотите сделать его короче, добавьте функцию step, как если бы она была для Int последовательностей.

infix fun ClosedRange<Double>.step(step: Double): Sequence<Double> = 
    generateSequence(start) { it + step }.takeWhile { it <= endInclusive }

fun contains(d: Double) = d in 0.0..1.0 step 0.1

Редактировать

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

val acceptableAccuracy = 1e-15
infix fun Double.nearlyIn(sequence: Sequence<Double>) = 
    sequence.any { this in (it - acceptableAccuracy..it + acceptableAccuracy) }

Тогда вам нужно несколько изменений в коде выше:

fun contains(d: Double) = d nearlyIn (0.0..1.0 step 0.1)
0 голосов
/ 07 июня 2019

Это будет сделано, если вы хотите проверить шаги 0,1 для любого двойника. Умножьте на 10, проверьте, является ли результат целым числом.

fun isSpecial(v:Double) : Boolean {
    val y = v*10
    return y == y.toInt().toDouble()
}

Если вы явно не хотите только 0.0-1.0?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...