Почему у Котлина нет Десятичной прогрессии?

Недавно я столкнулся с проблемой, итерируя десятичные числа с десятичным шагом, и мне было интересно, почему у Котлина есть прогрессии только для Int , Long и Char .

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

Q: Итак, почему нет никаких прогрессий для не целочисленных чисел? Спасибо.

PS: Вот пример кода возможной реализации (я взял источники для Int и адаптировался к BigDecimal ):

 /** * Returns a progression that goes over the same range with the given step. */ public infix fun BigDecimalProgression.step(step: BigDecimal): BigDecimalProgression { if (step <= java.math.BigDecimal.ZERO) throw IllegalArgumentException("Step must be positive, was: $step.") return BigDecimalProgression.fromClosedRange(first, last, if (this.step > java.math.BigDecimal.ZERO) step else -step) } /** * A progression of values of type `BigDecimal`. */ public open class BigDecimalProgression internal constructor ( start: BigDecimal, endInclusive: BigDecimal, step: BigDecimal ) : Iterable<BigDecimal> { init { if (step == BigDecimal.ZERO) throw kotlin.IllegalArgumentException("Step must be non-zero") } /** * The first element in the progression. */ public val first: BigDecimal = start /** * The last element in the progression. */ public val last: BigDecimal = getProgressionLastElement(start, endInclusive, step) /** * The step of the progression. */ public val step: BigDecimal = step override fun iterator(): BigDecimalIterator = BigDecimalProgressionIterator(first, last, step) /** Checks if the progression is empty. */ public open fun isEmpty(): Boolean = if (step > BigDecimal.ZERO) first > last else first < last override fun equals(other: Any?): Boolean = other is BigDecimalProgression && (isEmpty() && other.isEmpty() || first == other.first && last == other.last && step == other.step) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * (31 * first.hashCode() + last.hashCode()) + step.hashCode()) override fun toString(): String = if (step > BigDecimal.ZERO) "$first..$last step $step" else "$first downTo $last step ${-step}" companion object { /** * Creates BigDecimalProgression within the specified bounds of a closed range. * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. */ public fun fromClosedRange(rangeStart: BigDecimal, rangeEnd: BigDecimal, step: BigDecimal): BigDecimalProgression = BigDecimalProgression(rangeStart, rangeEnd, step) } } fun getProgressionLastElement(start: BigDecimal, end: BigDecimal, step: BigDecimal): BigDecimal { if (step > BigDecimal.ZERO) { return start + BigDecimal(((end - start) / step).toInt()) * step } else if (step < BigDecimal.ZERO) { return start - BigDecimal(((start - end) / -step).toInt()) * -step } else { throw kotlin.IllegalArgumentException("Step is zero.") } } /** An iterator over a sequence of values of type `BigDecimal`. */ public abstract class BigDecimalIterator : Iterator<BigDecimal> { override final fun next() = nextBigDecimal() /** Returns the next value in the sequence without boxing. */ public abstract fun nextBigDecimal(): BigDecimal } /** * An iterator over a progression of values of type `BigDecimal`. * @property step the number by which the value is incremented on each step. */ internal class BigDecimalProgressionIterator(first: BigDecimal, last: BigDecimal, val step: BigDecimal) : BigDecimalIterator() { private val finalElement = last private var hasNext: Boolean = if (step > BigDecimal.ZERO) first <= last else first >= last private var next = if (hasNext) first else finalElement override fun hasNext(): Boolean = hasNext override fun nextBigDecimal(): BigDecimal { val value = next if (value >= finalElement) { if (!hasNext) throw kotlin.NoSuchElementException() hasNext = false } else { next += step } return value } } 

    Как сказано в документации для диапазонов:

    Числа с плавающей запятой (Double, Float) не определяют их оператор rangeTo, а вместо него используется стандартная библиотека для общих типов Comparable:

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

    Диапазон, возвращаемый этой функцией, не может использоваться для итерации. Вам придется использовать какой-то другой цикл, потому что вы не можете использовать диапазоны.

    Они просто не определяют .