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:
Ilya Gorbunov
2020-02-25 21:29:56 +03:00
parent 3e6ab65ccc
commit d88d2cb058
5 changed files with 55 additions and 10 deletions
+3 -1
View File
@@ -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)
}
+4 -1
View File
@@ -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
+3 -1
View File
@@ -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
+45 -5
View File
@@ -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)