From 2227c6c5222ee33fa411173395ca236d27072eda Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Fri, 24 Nov 2017 17:04:17 +0700 Subject: [PATCH] stdlib: Implement float/double <-> bits conversion --- runtime/src/main/cpp/Operator.cpp | 18 ++++++++ runtime/src/main/kotlin/kotlin/Numbers.kt | 54 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/runtime/src/main/cpp/Operator.cpp b/runtime/src/main/cpp/Operator.cpp index 6795eaa3d6f..ab61c8ab422 100644 --- a/runtime/src/main/cpp/Operator.cpp +++ b/runtime/src/main/cpp/Operator.cpp @@ -386,6 +386,15 @@ KInt Kotlin_Float_bits (KFloat a) { return alias.i; } +KFloat Kotlin_Float_fromBits (KInt a) { + union { + KFloat f; + KInt i; + } alias; + alias.i = a; + return alias.f; +} + KBoolean Kotlin_Float_isNaN (KFloat a) { return isnan(a); } KBoolean Kotlin_Float_isInfinite (KFloat a) { return isinf(a); } KBoolean Kotlin_Float_isFinite (KFloat a) { return isfinite(a); } @@ -455,6 +464,15 @@ KLong Kotlin_Double_bits (KDouble a) { return alias.l; } +KDouble Kotlin_Double_fromBits (KLong a) { + union { + KDouble d; + KLong l; + } alias; + alias.l = a; + return alias.d; +} + KBoolean Kotlin_Double_isNaN (KDouble a) { return isnan(a); } KBoolean Kotlin_Double_isInfinite (KDouble a) { return isinf(a); } KBoolean Kotlin_Double_isFinite (KDouble a) { return isfinite(a); } diff --git a/runtime/src/main/kotlin/kotlin/Numbers.kt b/runtime/src/main/kotlin/kotlin/Numbers.kt index b58f913021a..84214f7286c 100644 --- a/runtime/src/main/kotlin/kotlin/Numbers.kt +++ b/runtime/src/main/kotlin/kotlin/Numbers.kt @@ -53,3 +53,57 @@ external public fun Double.isFinite(): Boolean */ @SymbolName("Kotlin_Float_isFinite") external public fun Float.isFinite(): Boolean + +/** + * Returns a bit representation of the specified floating-point value as [Long] + * according to the IEEE 754 floating-point "double format" bit layout. + */ +@SinceKotlin("1.2") +@kotlin.internal.InlineOnly +public inline fun Double.toBits(): Long = if (isNaN()) Double.NaN.toRawBits() else toRawBits() + +/** + * Returns a bit representation of the specified floating-point value as [Long] + * according to the IEEE 754 floating-point "double format" bit layout, + * preserving `NaN` values exact layout. + */ +@SinceKotlin("1.2") +public fun Double.toRawBits(): Long = bits() + +/** + * Returns the [Double] value corresponding to a given bit representation. + */ +@SinceKotlin("1.2") +@kotlin.internal.InlineOnly +public inline fun Double.Companion.fromBits(bits: Long): Double = kotlin.fromBits(bits) + +@PublishedApi +@SymbolName("Kotlin_Double_fromBits") +external internal fun fromBits(bits: Long): Double + +/** + * Returns a bit representation of the specified floating-point value as [Int] + * according to the IEEE 754 floating-point "single format" bit layout. + */ +@SinceKotlin("1.2") +@kotlin.internal.InlineOnly +public inline fun Float.toBits(): Int = if (isNaN()) Float.NaN.toRawBits() else toRawBits() + +/** + * Returns a bit representation of the specified floating-point value as [Int] + * according to the IEEE 754 floating-point "single format" bit layout, + * preserving `NaN` values exact layout. + */ +@SinceKotlin("1.2") +public fun Float.toRawBits(): Int = bits() + +/** + * Returns the [Float] value corresponding to a given bit representation. + */ +@SinceKotlin("1.2") +@kotlin.internal.InlineOnly +public inline fun Float.Companion.fromBits(bits: Int): Float = kotlin.fromBits(bits) + +@PublishedApi +@SymbolName("Kotlin_Float_fromBits") +external internal fun fromBits(bits: Int): Float