Kotlin:检查Double值是否仅介于0.0到1.0之间,再乘以0.1

时间:2019-06-06 11:15:39

标签: kotlin

检查double值是否仅存在于
的集合中的简单/优雅的解决方案是什么? {.0, .1, .. .9, 1.0} 值。

现在我在做

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

,然后检查Double值是否包含。

是否有更简单/优雅的解决方案?

3 个答案:

答案 0 :(得分:1)

您可以使用sequences来实现。

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)

答案 1 :(得分:1)

由于您只真正担心十位,所以我只需要移动一次并检查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
}

避免完全分配任何集合或范围。如果范围不是动态的,我个人会考虑使用。

答案 2 :(得分:0)

如果您要检查0.1的步长是否为两倍,将执行此操作。 乘以10,检查结果是否为整数。

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

除非您明确只需要0.0-1.0?