```/** * Средняя * * Для заданного x рассчитать...
# russian-kotlinasfirst
a
Copy code
/**
 * Средняя
 *
 * Для заданного x рассчитать с заданной точностью eps
 * sin(x) = x - x^3 / 3! + x^5 / 5! - x^7 / 7! + ...
 * Нужную точность считать достигнутой, если очередной член ряда меньше eps по модулю.
 * Подумайте, как добиться более быстрой сходимости ряда при больших значениях x.
 * Использовать kotlin.math.sin и другие стандартные реализации функции синуса в этой задаче запрещается.
 */
// работает но не доделана - окончат вариант см sin2
fun sin(x: Double, eps: Double): Double {  // pi*100 = 314 Проходит только с БинДесимал - дурдом хотя считает
    print(x)
    var sinx:BigDecimal = x.toBigDecimal()
    var y:BigDecimal = x.toBigDecimal()
    var i = 1
    var iznack = -1
    var fack :BigDecimal = 1.0.toBigDecimal()
    var xpow:BigDecimal = x.toBigDecimal()
    while((y * y) > (eps * eps).toBigDecimal()) {
        fack = fack * (i+1).toBigDecimal() * (i+2).toBigDecimal()
        xpow = xpow * x.toBigDecimal() * x.toBigDecimal()
        y= xpow / fack
        sinx = sinx + iznack.toBigDecimal() * y
        i = i + 2
        iznack = - iznack
        //  println("$y --> $eps  xpow = $xpow  fack = $fack   sinx = $sinx")
        // if (i > 250) break
    }
    println ("   $sinx")
    return sinx.toDouble()
}


fun sin2(x: Double, eps: Double): Double {  // pi*100 = 314 Проходит только с БинДесимал
    print(x)
    var sinx: BigDecimal = x.toBigDecimal()
    var y: BigDecimal = x.toBigDecimal()
    var i = 1
    var iznack = -1

    while ((y * y) > (eps * eps).toBigDecimal()) {
        y = y * (x.toBigDecimal() * x.toBigDecimal()) / ((i + 1).toBigDecimal() * (i + 2).toBigDecimal())
        sinx += iznack.toBigDecimal() * y
        i += 2
        iznack = -iznack
        //  println("$y --> $eps  xpow = $xpow  fack = $fack   sinx = $sinx")
        // if (i > 250) break
    }
    println("   $sinx")
    return sinx.toDouble()
}
m
BigDecimal -- это очень жёсткий способ решить проблемы с погрешностью при больших значениях x. Куда проще привести x к интервалу [0...2*PI] с помощью операции % (остаток от деления)
(y * y) > (eps * eps).toBigDecimal()
-- вместо возведения в квадрат можно было использовать
abs