Repository: JetBrains/kotlin
File: libraries/stdlib/test/numbers/MathTest.kt (Kotlin)

Code before:

        for (invalid in listOf(-1.00001, 1.00001, Double.NaN, Double.MAX_VALUE, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) {
            assertTrue(atanh(invalid).isNaN())
        }
    }

    @Test fun cubeRoots() {
        val testingPairs = mapOf(
            Double.NaN to Double.NaN,
            Double.POSITIVE_INFINITY to Double.POSITIVE_INFINITY,
            Double.NEGATIVE_INFINITY to Double.NEGATIVE_INFINITY,
            Double.fromBits(0x0010000000000000) to 2.812644285236262E-103, // smallest normal value
            Double.fromBits(0x1L) to 1.7031839360032603E-108, // smallest value (denormal)
            Double.MAX_VALUE to 5.643803094122362E102,
            0.0 to 0.0,
            0.9 to 0.9654893846056297,
            9.9 to 2.1472291690189413,
            27.0 to 3.0,
            399.1289 to 7.362710510208026,
            8123.452 to 20.102351976782558,
            21717.639 to 27.9,
            392890.22 to 73.24147345684439
        )

        for ((x, result) in testingPairs) {
            assertEquals(result, cbrt(x), 1e-118)
            assertEquals(cbrt(-x), -cbrt(x))
        }
    }

    @Test fun powers() {
        assertEquals(5.0, hypot(3.0, 4.0))
        assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.NaN))
        assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NaN, Double.POSITIVE_INFINITY))
        assertTrue(hypot(Double.NaN, 0.0).isNaN())

        assertEquals(1.0, Double.NaN.pow(0.0))
        assertEquals(1.0, Double.POSITIVE_INFINITY.pow(0))
        assertEquals(49.0, 7.0.pow(2))
        assertEquals(0.25, 2.0.pow(-2))
        assertTrue(0.0.pow(Double.NaN).isNaN())
        assertTrue(Double.NaN.pow(-1).isNaN())
        assertTrue((-7.0).pow(1 / 3.0).isNaN())
        assertTrue(1.0.pow(Double.POSITIVE_INFINITY).isNaN())
        assertTrue((-1.0).pow(Double.NEGATIVE_INFINITY).isNaN())

        assertEquals(5.0, sqrt(9.0 + 16.0))
        assertTrue(sqrt(-1.0).isNaN())
        assertTrue(sqrt(Double.NaN).isNaN())

        assertTrue(exp(Double.NaN).isNaN())

Review comment (bug):
I don't think that the absolute tolerance is suitable here. For example, it fails in test for `kotlin-stdlib-js` with "Expected <0.9654893846056297> with absolute tolerance <1e-118>, actual <0.9654893846056298>".

Code after:
            assertAlmostEquals(approx, acosh(cosh(-approx)))
        }
        for (invalid in listOf(-1.0, 0.0, 0.99999, Double.NaN)) {
            assertTrue(acosh(invalid).isNaN())
        }
    }

    @Test fun inverseHyperbolicTan() {
        for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, Double.MIN_VALUE, -Double.MIN_VALUE)) {
            assertEquals(exact, atanh(tanh(exact)))
        }
        for (approx in listOf(0.00001)) {
            assertAlmostEquals(approx, atanh(tanh(approx)))
        }

        for (invalid in listOf(-1.00001, 1.00001, Double.NaN, Double.MAX_VALUE, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) {
            assertTrue(atanh(invalid).isNaN())
        }
    }

    @Test fun cubeRoots() {
        val testingPairs = mapOf(
            Double.NaN to Double.NaN,
            Double.POSITIVE_INFINITY to Double.POSITIVE_INFINITY,
            Double.NEGATIVE_INFINITY to Double.NEGATIVE_INFINITY,
            Double.fromBits(0x0010000000000000) to 2.812644285236262E-103, // smallest normal value
            Double.fromBits(0x1L) to 1.7031839360032603E-108, // smallest value (denormal)
            Double.MAX_VALUE to 5.643803094122362E102,
            0.0 to 0.0,
            0.9 to 0.9654893846056297,
            9.9 to 2.1472291690189413,
            27.0 to 3.0,
            399.1289 to 7.362710510208026,
            8123.452 to 20.102351976782558,
            21717.639 to 27.9,
            392890.22 to 73.24147345684439
        )

        for ((x, result) in testingPairs) {
            assertEquals(result, cbrt(x), if (result.isFinite()) 2.0 * result.ulp else 0.0)
            assertEquals(cbrt(-x), -cbrt(x))
        }
    }

    @Test fun powers() {
        assertEquals(5.0, hypot(3.0, 4.0))
        assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.NaN))
        assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NaN, Double.POSITIVE_INFINITY))
        assertTrue(hypot(Double.NaN, 0.0).isNaN())

        assertEquals(1.0, Double.NaN.pow(0.0))