Ranges in Kotlin using data type Double
Asked Answered
A

4

25

If I try to compile this code...

fun main(args: Array<String>) {
    for (i in 1.0..2.0) {
        println(i)
    }
}

... I get the error saying

For-loop range must have an 'iterator()' method

If I add a step...

fun main(args: Array<String>) {
    for (i in 1.0..2.0 step .5) {
        println(i)
    }
}

... then I get a new error instead:

Kotlin: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
public infix fun CharProgression.step(step: Int): CharProgression defined in kotlin.ranges
public infix fun IntProgression.step(step: Int): IntProgression defined in kotlin.ranges
public infix fun LongProgression.step(step: Long): LongProgression defined in kotlin.ranges
public infix fun UIntProgression.step(step: Int): UIntProgression defined in kotlin.ranges
public infix fun ULongProgression.step(step: Long): ULongProgression defined in kotlin.ranges

How then can I use doubles in a range? The post Ranges Reloaded on The Kotlin Blog shows that using Double ranges is fine. I don't know what's wrong with mine.

Annabellannabella answered 1/6, 2017 at 19:49 Comment(4)
Well that's a pretty weird thing to try, what should it even do? Enumerate all 4503599627370496 doubles between 1 and 2? That's a lot.Armstrong
It seems like that functionality has been removed, and you'll have to use a while loop.Thaw
I meant to add step .5 to increment by .5 not every double between the two. Although I guess you can't use doubles in a range according to the documentation :/Annabellannabella
for (i in 2..4) { val j = 2.0 * i; ... }Zarzuela
B
23

As of Kotlin 1.1, a ClosedRange<Double> "cannot be used for iteration" (rangeTo() - Utility functions - Ranges - Kotlin Programming Language).

You can, however, define your own step extension function for this. e.g.:

infix fun ClosedRange<Double>.step(step: Double): Iterable<Double> {
    require(start.isFinite())
    require(endInclusive.isFinite())
    require(step > 0.0) { "Step must be positive, was: $step." }
    val sequence = generateSequence(start) { previous ->
        if (previous == Double.POSITIVE_INFINITY) return@generateSequence null
        val next = previous + step
        if (next > endInclusive) null else next
    }
    return sequence.asIterable()
}

Although you can do this if you are working with money you shouldn't really be using Double (or Float). See Java Practices -> Representing money.

Bombe answered 2/6, 2017 at 15:10 Comment(0)
S
4

In some cases you can use repeat loop. For example in this situation you can count how many time this the loop will repeat. so...

fun main() {
    var startNum = 1.0
    repeat(4) {
        startNum += 0.5
        //TODO something else
    }
}
Standardize answered 25/10, 2020 at 19:5 Comment(0)
C
3

According to the documentation for ranges:

Floating point numbers (Double, Float) do not define their rangeTo operator, and the one provided by the standard library for generic Comparable types is used instead:

public operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>

The range returned by this function cannot be used for iteration.

You will have to use some other kind of loop since you can't use ranges.

Corrosive answered 1/6, 2017 at 19:57 Comment(0)
U
-2
for(i in 0..2){
    var j=i.toFloat()*0.5+1.0f
    print(i)
}
Unsaddle answered 15/3, 2024 at 7:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.