[KT-76905] feat(kotlin.math): add annotations and examples for functions
diff --git a/libraries/stdlib/common/src/kotlin/MathH.kt b/libraries/stdlib/common/src/kotlin/MathH.kt index cbd584b..a233316 100644 --- a/libraries/stdlib/common/src/kotlin/MathH.kt +++ b/libraries/stdlib/common/src/kotlin/MathH.kt
@@ -26,6 +26,8 @@ * * Special cases: * - `sin(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Doubles.sin */ @SinceKotlin("1.2") public expect fun sin(x: Double): Double @@ -34,6 +36,8 @@ * * Special cases: * - `cos(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Doubles.cos */ @SinceKotlin("1.2") public expect fun cos(x: Double): Double @@ -42,6 +46,8 @@ * * Special cases: * - `tan(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Doubles.tan */ @SinceKotlin("1.2") public expect fun tan(x: Double): Double @@ -182,6 +188,8 @@ * * Special cases: * - `sqrt(x)` is `NaN` when `x < 0` or `x` is `NaN` + * + * @sample samples.math.MathSamples.Doubles.sqrt */ @SinceKotlin("1.2") public expect fun sqrt(x: Double): Double @@ -193,6 +201,8 @@ * - `exp(NaN)` is `NaN` * - `exp(+Inf)` is `+Inf` * - `exp(-Inf)` is `0.0` + * + * @sample samples.math.MathSamples.Doubles.exp */ @SinceKotlin("1.2") public expect fun exp(x: Double): Double @@ -235,6 +245,8 @@ * - `ln(x)` is `NaN` when `x < 0.0` * - `ln(+Inf)` is `+Inf` * - `ln(0.0)` is `-Inf` + * + * @sample samples.math.MathSamples.Doubles.ln */ @SinceKotlin("1.2") public expect fun ln(x: Double): Double @@ -333,6 +345,7 @@ * - `abs(NaN)` is `NaN` * * @see absoluteValue extension property for [Double] + * @sample samples.math.MathSamples.Doubles.abs */ @SinceKotlin("1.2") public expect fun abs(x: Double): Double @@ -357,6 +370,8 @@ * Returns the smaller of two values. * * If either value is `NaN`, then the result is `NaN`. + * + * @sample samples.math.MathSamples.Doubles.min */ @SinceKotlin("1.2") public expect fun min(a: Double, b: Double): Double @@ -365,6 +380,8 @@ * Returns the greater of two values. * * If either value is `NaN`, then the result is `NaN`. + * + * @sample samples.math.MathSamples.Doubles.max */ @SinceKotlin("1.2") public expect fun max(a: Double, b: Double): Double @@ -397,6 +414,8 @@ * - `NaN.pow(x)` is `NaN` for `x != 0.0` * - `b.pow(Inf)` is `NaN` for `abs(b) == 1.0` * - `b.pow(x)` is `NaN` for `b < 0` and `x` is finite and not an integer + * + * @sample samples.math.MathSamples.Doubles.pow */ @SinceKotlin("1.2") public expect fun Double.pow(x: Double): Double @@ -523,6 +542,8 @@ * * Special cases: * - `sin(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Floats.sin */ @SinceKotlin("1.2") public expect fun sin(x: Float): Float @@ -531,6 +552,8 @@ * * Special cases: * - `cos(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Floats.cos */ @SinceKotlin("1.2") public expect fun cos(x: Float): Float @@ -539,6 +562,8 @@ * * Special cases: * - `tan(NaN|+Inf|-Inf)` is `NaN` + * + * @sample samples.math.MathSamples.Floats.tan */ @SinceKotlin("1.2") public expect fun tan(x: Float): Float @@ -679,6 +704,8 @@ * * Special cases: * - `sqrt(x)` is `NaN` when `x < 0` or `x` is `NaN` + * + * @sample samples.math.MathSamples.Floats.sqrt */ @SinceKotlin("1.2") public expect fun sqrt(x: Float): Float @@ -690,6 +717,8 @@ * - `exp(NaN)` is `NaN` * - `exp(+Inf)` is `+Inf` * - `exp(-Inf)` is `0.0` + * + * @sample samples.math.MathSamples.Floats.exp */ @SinceKotlin("1.2") public expect fun exp(x: Float): Float @@ -732,6 +761,8 @@ * - `ln(x)` is `NaN` when `x < 0.0` * - `ln(+Inf)` is `+Inf` * - `ln(0.0)` is `-Inf` + * + * @sample samples.math.MathSamples.Floats.ln */ @SinceKotlin("1.2") public expect fun ln(x: Float): Float @@ -831,6 +862,7 @@ * - `abs(NaN)` is `NaN` * * @see absoluteValue extension property for [Float] + * @sample samples.math.MathSamples.Floats.abs */ @SinceKotlin("1.2") public expect fun abs(x: Float): Float @@ -856,6 +888,8 @@ * Returns the smaller of two values. * * If either value is `NaN`, then the result is `NaN`. + * + * @sample samples.math.MathSamples.Floats.min */ @SinceKotlin("1.2") public expect fun min(a: Float, b: Float): Float @@ -864,6 +898,8 @@ * Returns the greater of two values. * * If either value is `NaN`, then the result is `NaN`. + * + * @sample samples.math.MathSamples.Floats.max */ @SinceKotlin("1.2") public expect fun max(a: Float, b: Float): Float @@ -897,6 +933,8 @@ * - `NaN.pow(x)` is `NaN` for `x != 0.0` * - `b.pow(Inf)` is `NaN` for `abs(b) == 1.0` * - `b.pow(x)` is `NaN` for `b < 0` and `x` is finite and not an integer + * + * @sample samples.math.MathSamples.Floats.pow */ @SinceKotlin("1.2") public expect fun Float.pow(x: Float): Float
diff --git a/libraries/stdlib/samples/test/samples/math/MathSamples.kt b/libraries/stdlib/samples/test/samples/math/MathSamples.kt index c9ce24f..67bef32 100644 --- a/libraries/stdlib/samples/test/samples/math/MathSamples.kt +++ b/libraries/stdlib/samples/test/samples/math/MathSamples.kt
@@ -13,6 +13,143 @@ class MathSamples { class Doubles { @Sample + fun abs() { + assertPrints(abs(3.14), "3.14") + assertPrints(abs(-3.14), "3.14") + assertPrints(abs(0.0), "0.0") + + // Special cases + assertPrints(abs(Double.NaN), "NaN") + assertPrints(abs(Double.POSITIVE_INFINITY), "Infinity") + assertPrints(abs(Double.NEGATIVE_INFINITY), "Infinity") + } + + @Sample + fun min() { + assertPrints(min(1.0, 2.0), "1.0") + assertPrints(min(-1.0, -2.0), "-2.0") + assertPrints(min(-1.0, 2.0), "-1.0") + assertPrints(min(0.0, 0.0), "0.0") + + // Special cases + assertPrints(min(Double.NaN, 1.0), "NaN") + assertPrints(min(1.0, Double.NaN), "NaN") + assertPrints(min(Double.POSITIVE_INFINITY, 1.0), "1.0") + assertPrints(min(Double.NEGATIVE_INFINITY, 1.0), "-Infinity") + } + + @Sample + fun max() { + assertPrints(max(1.0, 2.0), "2.0") + assertPrints(max(-1.0, -2.0), "-1.0") + assertPrints(max(-1.0, 2.0), "2.0") + assertPrints(max(0.0, 0.0), "0.0") + + // Special cases + assertPrints(max(Double.NaN, 1.0), "NaN") + assertPrints(max(1.0, Double.NaN), "NaN") + assertPrints(max(Double.POSITIVE_INFINITY, 1.0), "Infinity") + assertPrints(max(Double.NEGATIVE_INFINITY, 1.0), "1.0") + } + + @Sample + fun sin() { + // Values close to common angles + assertPrints(sin(0.0), "0.0") + assertEquals(1.0, sin(PI / 2), 1e-15) + assertEquals(0.0, sin(PI), 1e-15) + assertEquals(-1.0, sin(3 * PI / 2), 1e-15) + assertEquals(0.0, sin(2 * PI), 1e-15) + + // Special cases + assertPrints(sin(Double.NaN), "NaN") + assertPrints(sin(Double.POSITIVE_INFINITY), "NaN") + assertPrints(sin(Double.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun cos() { + // Values close to common angles + assertEquals(1.0, cos(0.0), 1e-15) + assertEquals(0.0, cos(PI / 2), 1e-15) + assertEquals(-1.0, cos(PI), 1e-15) + assertEquals(0.0, cos(3 * PI / 2), 1e-15) + assertEquals(1.0, cos(2 * PI), 1e-15) + + // Special cases + assertPrints(cos(Double.NaN), "NaN") + assertPrints(cos(Double.POSITIVE_INFINITY), "NaN") + assertPrints(cos(Double.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun tan() { + // Values close to common angles + assertEquals(0.0, tan(0.0), 1e-15) + assertEquals(0.0, tan(PI), 1e-15) + assertEquals(0.0, tan(2 * PI), 1e-15) + + // Special cases + assertPrints(tan(Double.NaN), "NaN") + assertPrints(tan(Double.POSITIVE_INFINITY), "NaN") + assertPrints(tan(Double.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun sqrt() { + assertPrints(sqrt(0.0), "0.0") + assertPrints(sqrt(1.0), "1.0") + assertPrints(sqrt(4.0), "2.0") + assertEquals(1.4142135623730951, sqrt(2.0), 1e-15) + + // Special cases + assertPrints(sqrt(Double.NaN), "NaN") + assertPrints(sqrt(-1.0), "NaN") + assertPrints(sqrt(Double.POSITIVE_INFINITY), "Infinity") + } + + @Sample + fun pow() { + assertPrints(2.0.pow(0.0), "1.0") + assertPrints(2.0.pow(1.0), "2.0") + assertPrints(2.0.pow(2.0), "4.0") + assertEquals(1.4142135623730951, 2.0.pow(0.5), 1e-15) + assertPrints((-2.0).pow(2.0), "4.0") + assertPrints((-2.0).pow(3.0), "-8.0") + + // Special cases + assertPrints(Double.NaN.pow(1.0), "NaN") + assertPrints(1.0.pow(Double.NaN), "NaN") + assertPrints(1.0.pow(Double.POSITIVE_INFINITY), "NaN") + assertPrints((-1.0).pow(0.5), "NaN") // Negative base with non-integer exponent + } + + @Sample + fun exp() { + assertPrints(exp(0.0), "1.0") + assertEquals(E, exp(1.0), 1e-15) + assertEquals(E * E, exp(2.0), 1e-15) + + // Special cases + assertPrints(exp(Double.NaN), "NaN") + assertPrints(exp(Double.POSITIVE_INFINITY), "Infinity") + assertPrints(exp(Double.NEGATIVE_INFINITY), "0.0") + } + + @Sample + fun ln() { + assertPrints(ln(1.0), "0.0") + assertEquals(1.0, ln(E), 1e-15) + assertEquals(2.0, ln(E * E), 1e-15) + + // Special cases + assertPrints(ln(Double.NaN), "NaN") + assertPrints(ln(-1.0), "NaN") + assertPrints(ln(0.0), "-Infinity") + assertPrints(ln(Double.POSITIVE_INFINITY), "Infinity") + } + + @Sample fun floor() { assertPrints(floor(3.14159), "3.0") assertPrints(floor(-1.1), "-2.0") @@ -136,6 +273,143 @@ class Floats { @Sample + fun abs() { + assertPrints(abs(3.14f), "3.14") + assertPrints(abs(-3.14f), "3.14") + assertPrints(abs(0.0f), "0.0") + + // Special cases + assertPrints(abs(Float.NaN), "NaN") + assertPrints(abs(Float.POSITIVE_INFINITY), "Infinity") + assertPrints(abs(Float.NEGATIVE_INFINITY), "Infinity") + } + + @Sample + fun min() { + assertPrints(min(1.0f, 2.0f), "1.0") + assertPrints(min(-1.0f, -2.0f), "-2.0") + assertPrints(min(-1.0f, 2.0f), "-1.0") + assertPrints(min(0.0f, 0.0f), "0.0") + + // Special cases + assertPrints(min(Float.NaN, 1.0f), "NaN") + assertPrints(min(1.0f, Float.NaN), "NaN") + assertPrints(min(Float.POSITIVE_INFINITY, 1.0f), "1.0") + assertPrints(min(Float.NEGATIVE_INFINITY, 1.0f), "-Infinity") + } + + @Sample + fun max() { + assertPrints(max(1.0f, 2.0f), "2.0") + assertPrints(max(-1.0f, -2.0f), "-1.0") + assertPrints(max(-1.0f, 2.0f), "2.0") + assertPrints(max(0.0f, 0.0f), "0.0") + + // Special cases + assertPrints(max(Float.NaN, 1.0f), "NaN") + assertPrints(max(1.0f, Float.NaN), "NaN") + assertPrints(max(Float.POSITIVE_INFINITY, 1.0f), "Infinity") + assertPrints(max(Float.NEGATIVE_INFINITY, 1.0f), "1.0") + } + + @Sample + fun sin() { + // Values close to common angles + assertPrints(sin(0.0f), "0.0") + assertEquals(1.0f, sin(PI.toFloat() / 2), 1e-6f) + assertEquals(0.0f, sin(PI.toFloat()), 1e-6f) + assertEquals(-1.0f, sin(3 * PI.toFloat() / 2), 1e-6f) + assertEquals(0.0f, sin(2 * PI.toFloat()), 1e-6f) + + // Special cases + assertPrints(sin(Float.NaN), "NaN") + assertPrints(sin(Float.POSITIVE_INFINITY), "NaN") + assertPrints(sin(Float.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun cos() { + // Values close to common angles + assertEquals(1.0f, cos(0.0f), 1e-6f) + assertEquals(0.0f, cos(PI.toFloat() / 2), 1e-6f) + assertEquals(-1.0f, cos(PI.toFloat()), 1e-6f) + assertEquals(0.0f, cos(3 * PI.toFloat() / 2), 1e-6f) + assertEquals(1.0f, cos(2 * PI.toFloat()), 1e-6f) + + // Special cases + assertPrints(cos(Float.NaN), "NaN") + assertPrints(cos(Float.POSITIVE_INFINITY), "NaN") + assertPrints(cos(Float.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun tan() { + // Values close to common angles + assertEquals(0.0f, tan(0.0f), 1e-6f) + assertEquals(0.0f, tan(PI.toFloat()), 1e-6f) + assertEquals(0.0f, tan(2 * PI.toFloat()), 1e-6f) + + // Special cases + assertPrints(tan(Float.NaN), "NaN") + assertPrints(tan(Float.POSITIVE_INFINITY), "NaN") + assertPrints(tan(Float.NEGATIVE_INFINITY), "NaN") + } + + @Sample + fun sqrt() { + assertPrints(sqrt(0.0f), "0.0") + assertPrints(sqrt(1.0f), "1.0") + assertPrints(sqrt(4.0f), "2.0") + assertEquals(1.4142135f, sqrt(2.0f), 1e-6f) + + // Special cases + assertPrints(sqrt(Float.NaN), "NaN") + assertPrints(sqrt(-1.0f), "NaN") + assertPrints(sqrt(Float.POSITIVE_INFINITY), "Infinity") + } + + @Sample + fun pow() { + assertPrints(2.0f.pow(0.0f), "1.0") + assertPrints(2.0f.pow(1.0f), "2.0") + assertPrints(2.0f.pow(2.0f), "4.0") + assertEquals(1.4142135f, 2.0f.pow(0.5f), 1e-6f) + assertPrints((-2.0f).pow(2.0f), "4.0") + assertPrints((-2.0f).pow(3.0f), "-8.0") + + // Special cases + assertPrints(Float.NaN.pow(1.0f), "NaN") + assertPrints(1.0f.pow(Float.NaN), "NaN") + assertPrints(1.0f.pow(Float.POSITIVE_INFINITY), "NaN") + assertPrints((-1.0f).pow(0.5f), "NaN") // Negative base with non-integer exponent + } + + @Sample + fun exp() { + assertPrints(exp(0.0f), "1.0") + assertEquals(E.toFloat(), exp(1.0f), 1e-6f) + assertEquals((E * E).toFloat(), exp(2.0f), 1e-6f) + + // Special cases + assertPrints(exp(Float.NaN), "NaN") + assertPrints(exp(Float.POSITIVE_INFINITY), "Infinity") + assertPrints(exp(Float.NEGATIVE_INFINITY), "0.0") + } + + @Sample + fun ln() { + assertPrints(ln(1.0f), "0.0") + assertEquals(1.0f, ln(E.toFloat()), 1e-6f) + assertEquals(2.0f, ln((E * E).toFloat()), 1e-6f) + + // Special cases + assertPrints(ln(Float.NaN), "NaN") + assertPrints(ln(-1.0f), "NaN") + assertPrints(ln(0.0f), "-Infinity") + assertPrints(ln(Float.POSITIVE_INFINITY), "Infinity") + } + + @Sample fun floor() { assertPrints(floor(3.14159f), "3.0") assertPrints(floor(-1.1f), "-2.0")