JVM-specific math functions and tests
#KT-4900
This commit is contained in:
@@ -358,7 +358,19 @@ public inline fun Double.pow(other: Double): Double = nativeMath.pow(this, other
|
||||
@InlineOnly
|
||||
public inline fun Double.pow(other: Int): Double = nativeMath.pow(this, other.toDouble())
|
||||
|
||||
|
||||
/**
|
||||
* Computes the remainder of division of this value by the [other] value according to the IEEE 754 standard.
|
||||
*
|
||||
* The result is computed as `r = this - (q * other)` where `q` is the quotient of division rounded to the nearest integer,
|
||||
* `q = round(this / other)`.
|
||||
*
|
||||
* Special cases:
|
||||
* - `x.IEEErem(y)` is `NaN`, when `x` is `NaN` or `y` is `NaN` or `x` is `+Inf|-Inf` or `y` is zero.
|
||||
* - `x.IEEErem(y) == x` when `x` is finite and `y` is infinite.
|
||||
*
|
||||
* @see round
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun Double.IEEErem(other: Double): Double = nativeMath.IEEEremainder(this, other)
|
||||
|
||||
/**
|
||||
@@ -397,9 +409,39 @@ public inline fun Double.withSign(sign: Double): Double = nativeMath.copySign(th
|
||||
@InlineOnly
|
||||
public inline fun Double.withSign(sign: Int): Double = nativeMath.copySign(this, sign.toDouble())
|
||||
|
||||
/**
|
||||
* Returns the ulp of this value.
|
||||
*
|
||||
* An ulp is a positive distance between this value and the next nearest [Double] value larger in magnitude.
|
||||
*
|
||||
* Special Cases:
|
||||
* - `NaN.ulp` is `NaN`
|
||||
* - `x.ulp` is `+Inf` when `x` is `+Inf` or `-Inf`
|
||||
* - `0.0.ulp` is `Double.NIN_VALUE`
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline val Double.ulp: Double get() = nativeMath.ulp(this)
|
||||
|
||||
/**
|
||||
* Returns the [Double] value nearest to this value in direction of positive infinity.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun Double.nextUp(): Double = nativeMath.nextUp(this)
|
||||
/**
|
||||
* Returns the [Double] value nearest to this value in direction of negative infinity.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun Double.nextDown(): Double = nativeMath.nextAfter(this, Double.NEGATIVE_INFINITY)
|
||||
|
||||
/**
|
||||
* Returns the [Double] value nearest to this value in direction from this value towards the value [to].
|
||||
*
|
||||
* Special cases:
|
||||
* - `x.nextTowards(y)` is `NaN` if either `x` or `y` are `NaN`
|
||||
* - `x.nextTowards(x) == x`
|
||||
*
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun Double.nextTowards(to: Double): Double = nativeMath.nextAfter(this, to)
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
@file:kotlin.jvm.JvmVersion
|
||||
package test.numbers
|
||||
|
||||
import kotlin.test.*
|
||||
import org.junit.Test
|
||||
import kotlin.math.*
|
||||
|
||||
class MathJVMTest {
|
||||
|
||||
@Test fun IEEEremainder() {
|
||||
val data = arrayOf( // a a IEEErem 2.5
|
||||
doubleArrayOf(-2.0, 0.5),
|
||||
doubleArrayOf(-1.25, -1.25),
|
||||
doubleArrayOf( 0.0, 0.0),
|
||||
doubleArrayOf( 1.0, 1.0),
|
||||
doubleArrayOf( 1.25, 1.25),
|
||||
doubleArrayOf( 1.5, -1.0),
|
||||
doubleArrayOf( 2.0, -0.5),
|
||||
doubleArrayOf( 2.5, 0.0),
|
||||
doubleArrayOf( 3.5, 1.0),
|
||||
doubleArrayOf( 3.75, -1.25),
|
||||
doubleArrayOf( 4.0, -1.0)
|
||||
)
|
||||
for ((a, r) in data) {
|
||||
assertEquals(r, a.IEEErem(2.5), "($a).IEEErem(2.5)")
|
||||
}
|
||||
|
||||
assertTrue(Double.NaN.IEEErem(2.5).isNaN())
|
||||
assertTrue(2.0.IEEErem(Double.NaN).isNaN())
|
||||
assertTrue(Double.POSITIVE_INFINITY.IEEErem(2.0).isNaN())
|
||||
assertTrue(2.0.IEEErem(0.0).isNaN())
|
||||
assertEquals(PI, PI.IEEErem(Double.NEGATIVE_INFINITY))
|
||||
}
|
||||
|
||||
@Test fun nextAndPrev() {
|
||||
for (value in listOf(0.0, -0.0, Double.MIN_VALUE, -1.0, 2.0.pow(10))) {
|
||||
val next = value.nextUp()
|
||||
if (next > 0) {
|
||||
assertEquals(next, value + value.ulp)
|
||||
} else {
|
||||
assertEquals(value, next - next.ulp)
|
||||
}
|
||||
|
||||
val prev = value.nextDown()
|
||||
if (prev > 0) {
|
||||
assertEquals(value, prev + prev.ulp)
|
||||
}
|
||||
else {
|
||||
assertEquals(prev, value - value.ulp)
|
||||
}
|
||||
|
||||
val toZero = value.nextTowards(0.0)
|
||||
if (toZero != 0.0) {
|
||||
assertEquals(value, toZero + toZero.ulp.withSign(toZero))
|
||||
}
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, Double.MAX_VALUE.nextUp())
|
||||
assertEquals(Double.MAX_VALUE, Double.POSITIVE_INFINITY.nextDown())
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (-Double.MAX_VALUE).nextDown())
|
||||
assertEquals((-Double.MAX_VALUE), Double.NEGATIVE_INFINITY.nextUp())
|
||||
|
||||
assertTrue(Double.NaN.ulp.isNaN())
|
||||
assertTrue(Double.NaN.nextDown().isNaN())
|
||||
assertTrue(Double.NaN.nextUp().isNaN())
|
||||
assertTrue(Double.NaN.nextTowards(0.0).isNaN())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user