From 01a613dca4042dde8d2374ff0e6610cb9eddc415 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Tue, 13 Aug 2019 08:27:08 +0300 Subject: [PATCH] Add tests for floating-point to integral conversion --- .../stdlib/test/numbers/ConversionTest.kt | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 libraries/stdlib/test/numbers/ConversionTest.kt diff --git a/libraries/stdlib/test/numbers/ConversionTest.kt b/libraries/stdlib/test/numbers/ConversionTest.kt new file mode 100644 index 00000000000..5eec6434104 --- /dev/null +++ b/libraries/stdlib/test/numbers/ConversionTest.kt @@ -0,0 +1,181 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package test.numbers + +import kotlin.math.* +import kotlin.random.Random +import kotlin.test.* + +class ConversionTest { + + @Test + fun doubleToLong() { + fun testEquals(expected: Long, v: Double) = assertEquals(expected, v.toLong()) + + testEquals(0L, 0.0) + testEquals(0L, Double.NaN) + testEquals(0L, Double.MIN_VALUE) + + testEquals(1L, 1.0) + testEquals(-1L, -1.0) + + testEquals(Long.MIN_VALUE, -2_000_000_000_000_000_000_000.0) + testEquals(Long.MIN_VALUE, -(2.0.pow(Long.SIZE_BITS - 1))) + testEquals(Long.MIN_VALUE, -(2.0.pow(Long.SIZE_BITS + 5))) + testEquals(Long.MIN_VALUE, -Double.MAX_VALUE) + testEquals(Long.MIN_VALUE, Double.NEGATIVE_INFINITY) + + testEquals(Long.MAX_VALUE, 2_000_000_000_000_000_000_000.0) + testEquals(Long.MAX_VALUE, 2.0.pow(Long.SIZE_BITS - 1)) + testEquals(Long.MAX_VALUE, 2.0.pow(Long.SIZE_BITS + 5)) + testEquals(Long.MAX_VALUE, Double.MAX_VALUE) + testEquals(Long.MAX_VALUE, Double.POSITIVE_INFINITY) + + repeat(100) { + val v = Random.nextDouble(from = 2.0.pow(Long.SIZE_BITS - 1), until = 2.0.pow(Long.SIZE_BITS + 8)) + testEquals(Long.MIN_VALUE, -v) + testEquals(Long.MAX_VALUE, v) + } + + repeat(100) { + val v = Random.nextLong(1L shl 53) + testEquals(v, v.toDouble()) + testEquals(-v, -v.toDouble()) + } + + fun testTrailingBits(v: Double, count: Int) { + val mask = (1L shl count) - 1L + assertEquals(0L, v.toLong() and mask) + } + + var withTrailingZeros = 2.0.pow(63) + repeat(10) { + withTrailingZeros = withTrailingZeros.nextDown() + testTrailingBits(withTrailingZeros, 10) + } + + withTrailingZeros = -(2.0.pow(63)) + repeat(10) { + testTrailingBits(withTrailingZeros, 10) + withTrailingZeros = withTrailingZeros.nextUp() + } + + repeat(100) { + val msb = Random.nextInt(53, 63) + val v = 2.0.pow(msb) * (1.0 + Random.nextDouble()) + testTrailingBits(v, msb - 52) + } + } + + @Test + fun doubleToInt() { + fun testEquals(expected: Int, v: Double) = assertEquals(expected, v.toInt()) + + testEquals(0, 0.0) + testEquals(0, Double.NaN) + testEquals(0, Double.MIN_VALUE) + + testEquals(1, 1.0) + testEquals(-1, -1.0) + + testEquals(Int.MIN_VALUE, -2_000_000_000_000.0) + testEquals(Int.MIN_VALUE, Int.MIN_VALUE.toDouble()) + testEquals(Int.MIN_VALUE, -(2.0.pow(Int.SIZE_BITS - 1))) + testEquals(Int.MIN_VALUE, -(2.0.pow(Int.SIZE_BITS + 12))) + testEquals(Int.MIN_VALUE, -Double.MAX_VALUE) + testEquals(Int.MIN_VALUE, Double.NEGATIVE_INFINITY) + + testEquals(Int.MAX_VALUE, 2_000_000_000_000.0) + testEquals(Int.MAX_VALUE, Int.MAX_VALUE.toDouble()) + testEquals(Int.MAX_VALUE, 2.0.pow(Int.SIZE_BITS - 1)) + testEquals(Int.MAX_VALUE, 2.0.pow(Int.SIZE_BITS + 12)) + testEquals(Int.MAX_VALUE, Double.MAX_VALUE) + testEquals(Int.MAX_VALUE, Double.POSITIVE_INFINITY) + + repeat(100) { + val v = Random.nextDouble(from = 2.0.pow(Int.SIZE_BITS - 1), until = 2.0.pow(Int.SIZE_BITS + 8)) + testEquals(Int.MIN_VALUE, -v) + testEquals(Int.MAX_VALUE, v) + } + + repeat(100) { + val v = Random.nextDouble(from = Int.MIN_VALUE.toDouble(), until = Int.MAX_VALUE.toDouble()) + testEquals(v.toLong().toInt(), v) + } + } + + @Test + fun floatToLong() { + fun testEquals(expected: Long, v: Float) = assertEquals(expected, v.toLong()) + + testEquals(0L, 0.0f) + testEquals(0L, Float.NaN) + testEquals(0L, Float.MIN_VALUE) + + testEquals(1L, 1.0f) + testEquals(-1L, -1.0f) + + testEquals(Long.MIN_VALUE, -2_000_000_000_000_000_000_000.0f) + testEquals(Long.MIN_VALUE, -(2.0f.pow(Long.SIZE_BITS - 1))) + testEquals(Long.MIN_VALUE, -(2.0f.pow(Long.SIZE_BITS + 5))) + testEquals(Long.MIN_VALUE, -Float.MAX_VALUE) + testEquals(Long.MIN_VALUE, Float.NEGATIVE_INFINITY) + + testEquals(Long.MAX_VALUE, 2_000_000_000_000_000_000_000.0f) + testEquals(Long.MAX_VALUE, 2.0f.pow(Long.SIZE_BITS - 1)) + testEquals(Long.MAX_VALUE, 2.0f.pow(Long.SIZE_BITS + 5)) + testEquals(Long.MAX_VALUE, Float.MAX_VALUE) + testEquals(Long.MAX_VALUE, Float.POSITIVE_INFINITY) + + repeat(100) { + val v = Random.nextDouble(from = 2.0.pow(Long.SIZE_BITS - 1), until = 2.0.pow(Long.SIZE_BITS + 8)).toFloat() + testEquals(Long.MIN_VALUE, -v) + testEquals(Long.MAX_VALUE, v) + } + + repeat(100) { + val v = Random.nextLong(1L shl 23) + testEquals(v, v.toFloat()) + testEquals(-v, -v.toFloat()) + } + } + + @Test + fun floatToInt() { + fun testEquals(expected: Int, v: Float) = assertEquals(expected, v.toInt()) + + testEquals(0, 0.0f) + testEquals(0, Float.NaN) + testEquals(0, Float.MIN_VALUE) + + testEquals(1, 1.0f) + testEquals(-1, -1.0f) + + testEquals(Int.MIN_VALUE, -2_000_000_000_000.0f) + testEquals(Int.MIN_VALUE, -(2.0f.pow(Int.SIZE_BITS - 1))) + testEquals(Int.MIN_VALUE, -(2.0f.pow(Int.SIZE_BITS + 12))) + testEquals(Int.MIN_VALUE, -Float.MAX_VALUE) + testEquals(Int.MIN_VALUE, Float.NEGATIVE_INFINITY) + + testEquals(Int.MAX_VALUE, 2_000_000_000_000.0f) + testEquals(Int.MAX_VALUE, 2.0f.pow(Int.SIZE_BITS - 1)) + testEquals(Int.MAX_VALUE, 2.0f.pow(Int.SIZE_BITS + 12)) + testEquals(Int.MAX_VALUE, Float.MAX_VALUE) + testEquals(Int.MAX_VALUE, Float.POSITIVE_INFINITY) + + repeat(100) { + val v = Random.nextDouble(from = 2.0.pow(Int.SIZE_BITS - 1), until = 2.0.pow(Int.SIZE_BITS + 8)).toFloat() + testEquals(Int.MIN_VALUE, -v) + testEquals(Int.MAX_VALUE, v) + } + + repeat(100) { + val v = Random.nextInt(1 shl 23) + testEquals(v, v.toFloat()) + testEquals(-v, -v.toFloat()) + } + } +} \ No newline at end of file