181 lines
6.2 KiB
Kotlin
181 lines
6.2 KiB
Kotlin
/*
|
|
* 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())
|
|
}
|
|
}
|
|
} |