diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index dc12b126654..4843f6a5b79 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1449,6 +1449,27 @@ task hash0(type: RunKonanTest) { source = "runtime/basic/hash0.kt" } +task ieee754(type: RunKonanTest) { + goldValue = "Infinity 2147483647 -1 -1\n" + + "3.4028235E38\n" + + "NAN2SHORT:: 0\n" + + "MAX2SHORT:: -1\n" + + "2147483647 -1\n" + + "FLOAT:: Infinity INT:: 2147483647\n" + + "FLOAT:: 1.7014117E38 INT:: 2147483647\n" + + "FLOAT:: 3.4028235E38 INT:: 2147483647\n" + + "FLOAT:: 3.14 INT:: 3\n" + + "FLOAT:: NaN INT:: 0\n" + + "FLOAT:: -33333.125 INT:: -33333\n" + + "FLOAT:: 1.4E-45 INT:: 0\n" + + "FLOAT:: -Infinity INT:: -2147483648\n" + + "FLOAT:: -1.2 INT:: -1\n" + + "FLOAT:: -12.6 INT:: -12\n" + + "FLOAT:: 2.3 INT:: 2\n" + + "OK\n" + source = "runtime/basic/ieee754.kt" +} + task array_list1(type: RunKonanTest) { goldValue = "OK\n" source = "runtime/collections/array_list1.kt" diff --git a/backend.native/tests/runtime/basic/ieee754.kt b/backend.native/tests/runtime/basic/ieee754.kt new file mode 100644 index 00000000000..169d74d85bf --- /dev/null +++ b/backend.native/tests/runtime/basic/ieee754.kt @@ -0,0 +1,29 @@ +package runtime.basic.ieee754 + +import kotlin.test.* + +@Test fun runTest() { + val v = Float.POSITIVE_INFINITY + val i = v.toInt() + println("$v $i ${v.toShort()} ${i.toShort()}") + + val a = 42 + val b = Float.MAX_VALUE + println("${a + b}") + + val s = Float.NaN.toShort() + println("NAN2SHORT:: $s") + + val d: Float = Float.MAX_VALUE + println("MAX2SHORT:: ${d.toShort()}") + val d2i = d.toInt() + println("$d2i ${d2i.toShort()}") + + for (f in arrayOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE / 2, Float.MAX_VALUE, + 3.14f, Float.NaN, -33333.12312f, Float.MIN_VALUE, Float.NEGATIVE_INFINITY, + -1.2f, -12.6f, 2.3f)) { + println("FLOAT:: $f INT:: ${f.toInt()}") + } + + println("OK") +} \ No newline at end of file diff --git a/runtime/src/main/cpp/Operator.cpp b/runtime/src/main/cpp/Operator.cpp index ab61c8ab422..6587f68a2b6 100644 --- a/runtime/src/main/cpp/Operator.cpp +++ b/runtime/src/main/cpp/Operator.cpp @@ -370,12 +370,22 @@ KFloat Kotlin_Float_dec (KFloat a ) { return --a; } KFloat Kotlin_Float_unaryPlus (KFloat a ) { return +a; } KFloat Kotlin_Float_unaryMinus (KFloat a ) { return -a; } -KByte Kotlin_Float_toByte (KFloat a ) { return a; } -KShort Kotlin_Float_toShort (KFloat a ) { return a; } -KInt Kotlin_Float_toInt (KFloat a ) { return a; } -KLong Kotlin_Float_toLong (KFloat a ) { return a; } +KInt Kotlin_Float_toInt (KFloat a ) { + if (isnan(a)) return 0; + if (a >= (KFloat) INT_MAX) return INT_MAX; + if (a <= (KFloat) INT_MIN) return INT_MIN; + return a; +} +KLong Kotlin_Float_toLong (KFloat a ) { + if (isnan(a)) return 0; + if (a >= (KFloat) LONG_MAX) return LONG_MAX; + if (a <= (KFloat) LONG_MIN) return LONG_MIN; + return a; +} KFloat Kotlin_Float_toFloat (KFloat a ) { return a; } KDouble Kotlin_Float_toDouble (KFloat a ) { return a; } +KByte Kotlin_Float_toByte (KFloat a ) { return (KByte) Kotlin_Float_toInt(a); } +KShort Kotlin_Float_toShort (KFloat a ) { return (KShort) Kotlin_Float_toInt(a); } KInt Kotlin_Float_bits (KFloat a) { union { @@ -448,10 +458,20 @@ KDouble Kotlin_Double_dec (KDouble a ) { return --a; } KDouble Kotlin_Double_unaryPlus (KDouble a ) { return +a; } KDouble Kotlin_Double_unaryMinus (KDouble a ) { return -a; } -KByte Kotlin_Double_toByte (KDouble a ) { return a; } -KShort Kotlin_Double_toShort (KDouble a ) { return a; } -KInt Kotlin_Double_toInt (KDouble a ) { return a; } -KLong Kotlin_Double_toLong (KDouble a ) { return a; } +KInt Kotlin_Double_toInt (KDouble a ) { + if (isnan(a)) return 0; + if (a >= (KDouble) INT_MAX) return INT_MAX; + if (a <= (KDouble) INT_MIN) return INT_MIN; + return a; +} +KLong Kotlin_Double_toLong (KDouble a ) { + if (isnan(a)) return 0; + if (a >= (KDouble) LONG_MAX) return LONG_MAX; + if (a <= (KDouble) LONG_MIN) return LONG_MIN; + return a; +} +KByte Kotlin_Double_toByte (KDouble a ) { return (KByte) Kotlin_Double_toInt(a); } +KShort Kotlin_Double_toShort (KDouble a ) { return (KShort) Kotlin_Double_toInt(a); } KFloat Kotlin_Double_toFloat (KDouble a ) { return a; } KDouble Kotlin_Double_toDouble (KDouble a ) { return a; } diff --git a/runtime/src/main/kotlin/kotlin/Primitives.kt b/runtime/src/main/kotlin/kotlin/Primitives.kt index 01dbca7991b..fcf622fa056 100644 --- a/runtime/src/main/kotlin/kotlin/Primitives.kt +++ b/runtime/src/main/kotlin/kotlin/Primitives.kt @@ -975,8 +975,7 @@ public final class Float : Number(), Comparable { /** * A constant holding the "not a number" value of Float. */ - @Suppress("DIVISION_BY_ZERO") - public val NaN: Float = 0.0f / 0.0f + public val NaN: Float = kotlinx.cinterop.bitsToFloat(0x7fc00000) } /** @@ -1194,8 +1193,7 @@ public final class Double : Number(), Comparable { /** * A constant holding the "not a number" value of Double. */ - @Suppress("DIVISION_BY_ZERO") - public val NaN: Double = 0.0 / 0.0 + public val NaN: Double = kotlinx.cinterop.bitsToDouble(0x7ff8000000000000L) } /**