Integer math functions and tests for them
#KT-4900
This commit is contained in:
@@ -821,21 +821,98 @@ public inline fun Float.roundToLong(): Long = toDouble().roundToLong()
|
||||
|
||||
|
||||
|
||||
// Int
|
||||
// also as extension val [absoluteValue]
|
||||
fun abs(a: Int): Int = if (a < 0) -a else a
|
||||
|
||||
inline fun min(a: Int, b: Int): Int = minOf(a, b)
|
||||
inline fun max(a: Int, b: Int): Int = maxOf(a, b)
|
||||
/**
|
||||
* Returns the absolute value of the given value [a].
|
||||
*
|
||||
* Special cases:
|
||||
* - `abs(Int.MIN_VALUE)` is `Int.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see absoluteValue extension property for [Int]
|
||||
*/
|
||||
// TODO: remove manual 'or' when KT-19290 is fixed
|
||||
public fun abs(a: Int): Int = if (a < 0) (-a or 0) else a
|
||||
|
||||
inline val Int.absoluteValue: Int get() = abs(this)
|
||||
/**
|
||||
* Returns the smaller of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun min(a: Int, b: Int): Int = minOf(a, b)
|
||||
|
||||
/**
|
||||
* Returns the greater of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun max(a: Int, b: Int): Int = maxOf(a, b)
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this value.
|
||||
*
|
||||
* Special cases:
|
||||
* - `Int.MIN_VALUE.absoluteValue` is `Int.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see abs function
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline val Int.absoluteValue: Int get() = abs(this)
|
||||
|
||||
/**
|
||||
* Returns the sign of this value:
|
||||
* - `-1` if the value is negative,
|
||||
* - `0` if the value is zero,
|
||||
* - `1` if the value is positive
|
||||
*/
|
||||
public val Int.sign: Int get() = when {
|
||||
this < 0 -> -1
|
||||
this > 0 -> 1
|
||||
else -> 0
|
||||
}
|
||||
|
||||
|
||||
// Long
|
||||
// also as extension val [absoluteValue]
|
||||
fun abs(a: Long): Long = if (a < 0) -a else a
|
||||
|
||||
inline fun min(a: Long, b: Long): Long = minOf(a, b)
|
||||
inline fun max(a: Long, b: Long): Long = maxOf(a, b)
|
||||
/**
|
||||
* Returns the absolute value of the given value [a].
|
||||
*
|
||||
* Special cases:
|
||||
* - `abs(Long.MIN_VALUE)` is `Long.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see absoluteValue extension property for [Long]
|
||||
*/
|
||||
public fun abs(a: Long): Long = if (a < 0) -a else a
|
||||
|
||||
/**
|
||||
* Returns the smaller of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun min(a: Long, b: Long): Long = minOf(a, b)
|
||||
|
||||
/**
|
||||
* Returns the greater of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun max(a: Long, b: Long): Long = maxOf(a, b)
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this value.
|
||||
*
|
||||
* Special cases:
|
||||
* - `Long.MIN_VALUE.absoluteValue` is `Long.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see abs function
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline val Long.absoluteValue: Long get() = abs(this)
|
||||
|
||||
/**
|
||||
* Returns the sign of this value:
|
||||
* - `-1` if the value is negative,
|
||||
* - `0` if the value is zero,
|
||||
* - `1` if the value is positive
|
||||
*/
|
||||
public val Long.sign: Int get() = when {
|
||||
this < 0 -> -1
|
||||
this > 0 -> 1
|
||||
else -> 0
|
||||
}
|
||||
|
||||
|
||||
inline val Long.absoluteValue: Long get() = abs(this)
|
||||
|
||||
@@ -915,21 +915,99 @@ public fun Float.roundToLong(): Long = toDouble().roundToLong()
|
||||
|
||||
|
||||
|
||||
// Int
|
||||
// also as extension val [absoluteValue]
|
||||
// ================== Integer math functions =====================================
|
||||
|
||||
/**
|
||||
* Returns the absolute value of the given value [a].
|
||||
*
|
||||
* Special cases:
|
||||
* - `abs(Int.MIN_VALUE)` is `Int.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see absoluteValue extension property for [Int]
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun abs(a: Int): Int = nativeMath.abs(a)
|
||||
|
||||
/**
|
||||
* Returns the smaller of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun min(a: Int, b: Int): Int = nativeMath.min(a, b)
|
||||
|
||||
/**
|
||||
* Returns the greater of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun max(a: Int, b: Int): Int = nativeMath.max(a, b)
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this value.
|
||||
*
|
||||
* Special cases:
|
||||
* - `Int.MIN_VALUE.absoluteValue` is `Int.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see abs function
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline val Int.absoluteValue: Int get() = nativeMath.abs(this)
|
||||
|
||||
/**
|
||||
* Returns the sign of this value:
|
||||
* - `-1` if the value is negative,
|
||||
* - `0` if the value is zero,
|
||||
* - `1` if the value is positive
|
||||
*/
|
||||
public val Int.sign: Int get() = when {
|
||||
this < 0 -> -1
|
||||
this > 0 -> 1
|
||||
else -> 0
|
||||
}
|
||||
|
||||
// Long
|
||||
// also as extension val [absoluteValue]
|
||||
|
||||
|
||||
/**
|
||||
* Returns the absolute value of the given value [a].
|
||||
*
|
||||
* Special cases:
|
||||
* - `abs(Long.MIN_VALUE)` is `Long.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see absoluteValue extension property for [Long]
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun abs(a: Long): Long = nativeMath.abs(a)
|
||||
|
||||
/**
|
||||
* Returns the smaller of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun min(a: Long, b: Long): Long = nativeMath.min(a, b)
|
||||
|
||||
/**
|
||||
* Returns the greater of two values.
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline fun max(a: Long, b: Long): Long = nativeMath.max(a, b)
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this value.
|
||||
*
|
||||
* Special cases:
|
||||
* - `Long.MIN_VALUE.absoluteValue` is `Long.MIN_VALUE` due to an overflow
|
||||
*
|
||||
* @see abs function
|
||||
*/
|
||||
@InlineOnly
|
||||
public inline val Long.absoluteValue: Long get() = nativeMath.abs(this)
|
||||
|
||||
/**
|
||||
* Returns the sign of this value:
|
||||
* - `-1` if the value is negative,
|
||||
* - `0` if the value is zero,
|
||||
* - `1` if the value is positive
|
||||
*/
|
||||
public val Long.sign: Int get() = when {
|
||||
this < 0 -> -1
|
||||
this > 0 -> 1
|
||||
else -> 0
|
||||
}
|
||||
|
||||
|
||||
@@ -517,3 +517,32 @@ class FloatMathTest {
|
||||
|
||||
}
|
||||
|
||||
class IntegerMathTest {
|
||||
|
||||
@Test fun intSigns() {
|
||||
val negatives = listOf(Int.MIN_VALUE, -65536, -1)
|
||||
val positives = listOf(1, 100, 256, Int.MAX_VALUE)
|
||||
negatives.forEach { assertEquals(-1, it.sign) }
|
||||
positives.forEach { assertEquals(1, it.sign) }
|
||||
assertEquals(0, 0.sign)
|
||||
|
||||
(negatives - Int.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) }
|
||||
assertEquals(Int.MIN_VALUE, Int.MIN_VALUE.absoluteValue)
|
||||
|
||||
positives.forEach { assertEquals(it, it.absoluteValue) }
|
||||
}
|
||||
|
||||
|
||||
@Test fun longSigns() {
|
||||
val negatives = listOf(Long.MIN_VALUE, -65536L, -1L)
|
||||
val positives = listOf(1L, 100L, 256L, Long.MAX_VALUE)
|
||||
negatives.forEach { assertEquals(-1, it.sign) }
|
||||
positives.forEach { assertEquals(1, it.sign) }
|
||||
assertEquals(0, 0L.sign)
|
||||
|
||||
(negatives - Long.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) }
|
||||
assertEquals(Long.MIN_VALUE, Long.MIN_VALUE.absoluteValue)
|
||||
|
||||
positives.forEach { assertEquals(it, it.absoluteValue) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user