Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Kotlin没有';你没有十进制级数吗?_Kotlin_Bigdecimal - Fatal编程技术网

为什么Kotlin没有';你没有十进制级数吗?

为什么Kotlin没有';你没有十进制级数吗?,kotlin,bigdecimal,Kotlin,Bigdecimal,最近,我遇到了一个用十进制步长迭代十进制数的问题,我想知道为什么Kotlin只对Int、Long和Char进行累进 我明白,十进制数字可能会有一些警告。但仍然如此。我们只想有一个开始BigDecimalnumber,结束BigDecimalnumber,然后用BigDecimal步骤迭代它们 Q:那么,为什么非整数没有任何级数呢?多谢各位 注意:这里是一个可能实现的示例代码(我获取了Int的源代码,并改编为BigDecimal): /** *返回与给定步骤在相同范围内的级数。 */ 公共中缀fu

最近,我遇到了一个用十进制步长迭代十进制数的问题,我想知道为什么Kotlin只对
Int
Long
Char
进行累进

我明白,十进制数字可能会有一些警告。但仍然如此。我们只想有一个开始
BigDecimal
number,结束
BigDecimal
number,然后用
BigDecimal
步骤迭代它们

Q:那么,为什么非整数没有任何级数呢?多谢各位

注意:这里是一个可能实现的示例代码(我获取了Int的源代码,并改编为
BigDecimal
):

/**
*返回与给定步骤在相同范围内的级数。
*/
公共中缀fun BigDecimalProgression.step(步骤:BigDecimal):BigDecimalProgression{
if(步骤java.math.BigDecimal.ZERO)步骤else-step)
}
/**
*“BigDecimal”类型的值的级数。
*/
公共开放类BigDecimalProgression
内部构造函数
(
开始:BigDecimal,
endInclusive:BigDecimal,
步骤:BigDecimal
):Iterable{
初始化{
if(step==BigDecimal.ZERO)抛出kotlin.IllegalArgumentException(“step必须为非零”)
}
/**
*进程中的第一个元素。
*/
public val first:BigDecimal=start
/**
*进程中的最后一个元素。
*/
public val last:BigDecimal=getProgressionLastElement(开始、结束、结束)
/**
*前进的一步。
*/
公共值步长:BigDecimal=步长
override fun迭代器():BigDecimalIterator=BigDecimalProgressionitor(第一步、最后一步)
/**检查进程是否为空*/
public open fun isEmpty():Boolean=if(step>BigDecimal.ZERO)first>last else firstBigDecimal.ZERO)“$first..$last step$step”else“$first down to$last step${-step}”
伴星{
/**
*在闭合范围的指定边界内创建BigDecimalProgration。
*进程以[rangeStart]值开始,并以指定的[step]向不排除它的[rangeEnd]值前进。
*要倒退,[步数]必须为负值。
*/
ClosedRange的公共乐趣(rangeStart:BigDecimal,rangeEnd:BigDecimal,step:BigDecimal):BigDecimalProgression=BigDecimalProgression(rangeStart,rangeEnd,step)
}
}
有趣的getProgressionLastElement(开始:BigDecimal,结束:BigDecimal,步骤:BigDecimal):BigDecimal{
如果(步骤>BigDecimal.ZERO){
返回start+BigDecimal(((end-start)/step.toInt())*step
}else if(步骤BigDecimal.ZERO)first=last
private var next=if(hasNext)first-else finalElement
override fun hasNext():Boolean=hasNext
重写fun nextBigDecimal():BigDecimal{
val值=下一个
如果(值>=finalElement){
如果(!hasNext)抛出kotlin.NoSuchElementException()
hasNext=false
}
否则{
下一步+=步骤
}
返回值
}
}
正如在for ranges中所述:

浮点数(双精度、浮点)不定义其范围 运算符,以及标准库为通用 相反,使用可比类型:

public operator fun T.rangeTo(即:T):ClosedRange
此函数返回的范围不能用于迭代。你 因为不能使用范围,所以必须使用其他类型的循环


他们只是没有定义

也许你的问题更适合@JoachimRohde谢谢。我将尝试在那里添加它。然而,我认为,不添加这样的功能是有原因的,因此我会指出具体的注意事项,并为我的问题找到另一种解决方案。请记住,浮点算法并不总是那么简单。例如,可以这样构造无限循环。对于单精度,端点至少比步长大2^24倍的任何对象。在这一点上,增加步长将没有任何效果。事实上,双倍运算也会遇到同样的问题(在2^53而不是2^24)。就我所知,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
    }
}
public operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>