Test new Double/Float constants
Split test expectations based on actual support of enforced Float range KT-29182, KT-13887
This commit is contained in:
@@ -12,4 +12,6 @@ internal expect fun String.removeLeadingPlusOnJava6(): String
|
||||
internal expect inline fun testOnNonJvm6And7(f: () -> Unit)
|
||||
|
||||
public expect fun testOnJvm(action: () -> Unit)
|
||||
public expect fun testOnJs(action: () -> Unit)
|
||||
public expect fun testOnJs(action: () -> Unit)
|
||||
|
||||
public expect val isFloat32RangeEnforced: Boolean
|
||||
@@ -22,8 +22,6 @@ class BuiltinCompanionJsTest {
|
||||
}
|
||||
|
||||
@Test fun floatMinMaxValues() {
|
||||
assertEquals(js("Number.MIN_VALUE"), Float.MIN_VALUE)
|
||||
assertEquals(js("Number.MAX_VALUE"), Float.MAX_VALUE)
|
||||
assertEquals(js("Number.POSITIVE_INFINITY"), Float.POSITIVE_INFINITY)
|
||||
assertEquals(js("Number.NEGATIVE_INFINITY"), Float.NEGATIVE_INFINITY)
|
||||
}
|
||||
|
||||
@@ -20,4 +20,7 @@ internal actual inline fun testOnNonJvm6And7(f: () -> Unit) {
|
||||
|
||||
|
||||
public actual fun testOnJvm(action: () -> Unit) { }
|
||||
public actual fun testOnJs(action: () -> Unit) = action()
|
||||
public actual fun testOnJs(action: () -> Unit) = action()
|
||||
|
||||
// TODO: should be true at least in JS IR after implementing KT-24975
|
||||
public actual val isFloat32RangeEnforced: Boolean = false
|
||||
@@ -30,4 +30,6 @@ public actual fun testOnJvm(action: () -> Unit) = action()
|
||||
public actual fun testOnJs(action: () -> Unit) {}
|
||||
|
||||
@Suppress("HasPlatformType", "UNCHECKED_CAST")
|
||||
public fun <T> platformNull() = Collections.singletonList(null as T).first()
|
||||
public fun <T> platformNull() = Collections.singletonList(null as T).first()
|
||||
|
||||
public actual val isFloat32RangeEnforced: Boolean = true
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package test.numbers
|
||||
|
||||
import test.isFloat32RangeEnforced
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.*
|
||||
|
||||
@@ -20,6 +21,13 @@ object NumbersTestConstants {
|
||||
|
||||
public const val longMinSucc: Long = Long.MIN_VALUE + 1L
|
||||
public const val longMaxPred: Long = Long.MAX_VALUE - 1L
|
||||
|
||||
public const val doubleMaxHalf: Double = Double.MAX_VALUE / 2
|
||||
public const val doubleMinTwice: Double = Double.MIN_VALUE * 2
|
||||
|
||||
public const val floatMaxHalf: Float = Float.MAX_VALUE / 2
|
||||
public const val floatMinTwice: Float = Float.MIN_VALUE * 2
|
||||
|
||||
}
|
||||
|
||||
class NumbersTest {
|
||||
@@ -28,6 +36,8 @@ class NumbersTest {
|
||||
var oneS: Short = 1
|
||||
var oneB: Byte = 1
|
||||
|
||||
var two: Int = 2
|
||||
|
||||
@Test fun intMinMaxValues() {
|
||||
assertTrue(Int.MIN_VALUE < 0)
|
||||
assertTrue(Int.MAX_VALUE > 0)
|
||||
@@ -80,6 +90,9 @@ class NumbersTest {
|
||||
assertTrue(Double.MIN_VALUE > 0)
|
||||
assertTrue(Double.MAX_VALUE > 0)
|
||||
|
||||
assertEquals(NumbersTestConstants.doubleMaxHalf, Double.MAX_VALUE / two)
|
||||
assertEquals(NumbersTestConstants.doubleMinTwice, Double.MIN_VALUE * two)
|
||||
|
||||
// overflow behavior
|
||||
expect(Double.POSITIVE_INFINITY) { Double.MAX_VALUE * 2 }
|
||||
expect(Double.NEGATIVE_INFINITY) {-Double.MAX_VALUE * 2 }
|
||||
@@ -90,10 +103,20 @@ class NumbersTest {
|
||||
assertTrue(Float.MIN_VALUE > 0)
|
||||
assertTrue(Float.MAX_VALUE > 0)
|
||||
|
||||
if (isFloat32RangeEnforced) {
|
||||
assertEquals(NumbersTestConstants.floatMaxHalf, Float.MAX_VALUE / two)
|
||||
assertEquals(NumbersTestConstants.floatMinTwice, Float.MIN_VALUE * two)
|
||||
} else {
|
||||
assertAlmostEquals(NumbersTestConstants.floatMaxHalf, Float.MAX_VALUE / two, 0.0000001 * NumbersTestConstants.floatMaxHalf)
|
||||
assertAlmostEquals(NumbersTestConstants.floatMinTwice, Float.MIN_VALUE * two, 0.0000001 * NumbersTestConstants.floatMinTwice)
|
||||
}
|
||||
|
||||
// overflow behavior
|
||||
expect(Float.POSITIVE_INFINITY) { Float.MAX_VALUE * 2 }
|
||||
expect(Float.NEGATIVE_INFINITY) { -Float.MAX_VALUE * 2 }
|
||||
expect(0.0F) { Float.MIN_VALUE / 2.0F }
|
||||
if (isFloat32RangeEnforced) {
|
||||
expect(Float.POSITIVE_INFINITY) { Float.MAX_VALUE * 2 }
|
||||
expect(Float.NEGATIVE_INFINITY) { -Float.MAX_VALUE * 2 }
|
||||
expect(0.0F) { Float.MIN_VALUE / 2.0F }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun charMinMaxValues() {
|
||||
@@ -162,13 +185,27 @@ class NumbersTest {
|
||||
@Test fun floatToBits() {
|
||||
val PI_F = kotlin.math.PI.toFloat()
|
||||
assertEquals(0x40490fdb, PI_F.toBits())
|
||||
assertAlmostEquals(PI_F, Float.fromBits(0x40490fdb)) // PI_F is actually Double in JS
|
||||
// -Float.MAX_VALUE, Float.MAX_VALUE, -Float.MIN_VALUE, Float.MIN_VALUE: overflow or underflow
|
||||
if (isFloat32RangeEnforced) {
|
||||
assertEquals(PI_F, Float.fromBits(0x40490fdb))
|
||||
} else {
|
||||
assertAlmostEquals(PI_F, Float.fromBits(0x40490fdb)) // PI_F is actually Double in JS
|
||||
}
|
||||
for (value in listOf(Float.NEGATIVE_INFINITY, -1.0F, -0.0F, 0.0F, Float.POSITIVE_INFINITY, 1.0F)) {
|
||||
assertEquals(value, Float.fromBits(value.toBits()))
|
||||
assertEquals(value, Float.fromBits(value.toRawBits()))
|
||||
}
|
||||
|
||||
for (value in listOf(-Float.MAX_VALUE, Float.MAX_VALUE, -Float.MIN_VALUE, Float.MIN_VALUE)) {
|
||||
if (isFloat32RangeEnforced) {
|
||||
assertEquals(value, Float.fromBits(value.toBits()))
|
||||
assertEquals(value, Float.fromBits(value.toRawBits()))
|
||||
} else {
|
||||
val tolerance = if (kotlin.math.abs(value) == Float.MIN_VALUE) 0.001 * value else 0.0000001 * value
|
||||
assertAlmostEquals(value, Float.fromBits(value.toBits()), tolerance)
|
||||
assertAlmostEquals(value, Float.fromBits(value.toRawBits()), tolerance)
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(Float.NaN.toBits().let(Float.Companion::fromBits).isNaN())
|
||||
assertTrue(Float.NaN.toRawBits().let { Float.fromBits(it) }.isNaN())
|
||||
|
||||
@@ -195,6 +232,9 @@ class NumbersTest {
|
||||
testSizes(Short, Short.SIZE_BYTES, Short.SIZE_BITS, 2)
|
||||
testSizes(Int, Int.SIZE_BYTES, Int.SIZE_BITS, 4)
|
||||
testSizes(Long, Long.SIZE_BYTES, Long.SIZE_BITS, 8)
|
||||
|
||||
testSizes(Float, Float.SIZE_BYTES, Float.SIZE_BITS, 4)
|
||||
testSizes(Double, Double.SIZE_BYTES, Double.SIZE_BITS, 8)
|
||||
|
||||
testSizes(UByte, UByte.SIZE_BYTES, UByte.SIZE_BITS, 1)
|
||||
testSizes(UShort, UShort.SIZE_BYTES, UShort.SIZE_BITS, 2)
|
||||
|
||||
Reference in New Issue
Block a user