Add more details about bit shift operations #KT-41112
This commit is contained in:
committed by
Abduqodiri Qurbonzoda
parent
1c0ac850e8
commit
36e6247125
@@ -589,12 +589,30 @@ public class Int private constructor() : Number(), Comparable<Int> {
|
||||
/** Creates a range from this value to the specified [other] value. */
|
||||
public operator fun rangeTo(other: Long): LongRange
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun shl(bitCount: Int): Int
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun shr(bitCount: Int): Int
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun ushr(bitCount: Int): Int
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
public infix fun and(other: Int): Int
|
||||
/** Performs a bitwise OR operation between the two values. */
|
||||
@@ -818,12 +836,30 @@ public class Long private constructor() : Number(), Comparable<Long> {
|
||||
/** Creates a range from this value to the specified [other] value. */
|
||||
public operator fun rangeTo(other: Long): LongRange
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun shl(bitCount: Int): Long
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun shr(bitCount: Int): Long
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun ushr(bitCount: Int): Long
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
public infix fun and(other: Long): Long
|
||||
/** Performs a bitwise OR operation between the two values. */
|
||||
|
||||
@@ -31,6 +31,19 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) {
|
||||
"and" to "Performs a bitwise AND operation between the two values.",
|
||||
"or" to "Performs a bitwise OR operation between the two values.",
|
||||
"xor" to "Performs a bitwise XOR operation between the two values.")
|
||||
|
||||
|
||||
internal fun shiftOperatorsDocDetail(kind: PrimitiveType): String {
|
||||
val bitsUsed = when (kind) {
|
||||
PrimitiveType.INT -> "five"
|
||||
PrimitiveType.LONG -> "six"
|
||||
else -> throw IllegalArgumentException("Bit shift operation is not implemented for $kind")
|
||||
}
|
||||
return """
|
||||
* Note that only the $bitsUsed lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..${kind.bitSize - 1}`.
|
||||
"""
|
||||
}
|
||||
}
|
||||
private val typeDescriptions: Map<PrimitiveType, String> = mapOf(
|
||||
PrimitiveType.DOUBLE to "double-precision 64-bit IEEE 754 floating point number",
|
||||
@@ -124,7 +137,7 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) {
|
||||
generateRangeTo(kind)
|
||||
|
||||
if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG) {
|
||||
generateBitShiftOperators(className)
|
||||
generateBitShiftOperators(kind)
|
||||
}
|
||||
if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG /* || kind == PrimitiveType.BYTE || kind == PrimitiveType.SHORT */) {
|
||||
generateBitwiseOperators(className, since = if (kind == PrimitiveType.BYTE || kind == PrimitiveType.SHORT) "1.1" else null)
|
||||
@@ -202,10 +215,17 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) {
|
||||
out.println()
|
||||
}
|
||||
|
||||
private fun generateBitShiftOperators(className: String) {
|
||||
private fun generateBitShiftOperators(kind: PrimitiveType) {
|
||||
val className = kind.capitalized
|
||||
val detail = shiftOperatorsDocDetail(kind)
|
||||
for ((name, doc) in shiftOperators) {
|
||||
out.println(" /** $doc */")
|
||||
out.println(" /**")
|
||||
out.println(" * $doc")
|
||||
out.println(" *")
|
||||
out.println(detail.replaceIndent(" "))
|
||||
out.println(" */")
|
||||
out.println(" public infix fun $name(bitCount: Int): $className")
|
||||
out.println()
|
||||
}
|
||||
}
|
||||
private fun generateBitwiseOperators(className: String, since: String?) {
|
||||
|
||||
@@ -176,9 +176,15 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
|
||||
|
||||
fun generateShiftOperator(name: String, implementation: String = name) {
|
||||
val doc = GeneratePrimitives.shiftOperators[implementation]!!
|
||||
out.println(" /** $doc */")
|
||||
val detail = GeneratePrimitives.shiftOperatorsDocDetail(type.asSigned)
|
||||
out.println(" /**")
|
||||
out.println(" * $doc")
|
||||
out.println(" *")
|
||||
out.println(detail.replaceIndent(" "))
|
||||
out.println(" */")
|
||||
out.println(" @kotlin.internal.InlineOnly")
|
||||
out.println(" public inline infix fun $name(bitCount: Int): $className = $className(data $implementation bitCount)")
|
||||
out.println()
|
||||
}
|
||||
|
||||
generateShiftOperator("shl")
|
||||
|
||||
@@ -598,12 +598,30 @@ public class Int private constructor() : Number(), Comparable<Int> {
|
||||
/** Creates a range from this value to the specified [other] value. */
|
||||
public operator fun rangeTo(other: Long): LongRange
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun shl(bitCount: Int): Int
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun shr(bitCount: Int): Int
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
public infix fun ushr(bitCount: Int): Int
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
public infix fun and(other: Int): Int
|
||||
/** Performs a bitwise OR operation between the two values. */
|
||||
|
||||
@@ -201,13 +201,28 @@ public class Long internal constructor(
|
||||
/** Creates a range from this value to the specified [other] value. */
|
||||
public operator fun rangeTo(other: Long): LongRange = LongRange(this, other)
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun shl(bitCount: Int): Long = shiftLeft(bitCount)
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun shr(bitCount: Int): Long = shiftRight(bitCount)
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public infix fun ushr(bitCount: Int): Long = shiftRightUnsigned(bitCount)
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
|
||||
@@ -23,14 +23,58 @@ class BitwiseOperationsTest {
|
||||
|
||||
@Test fun shlForInt() {
|
||||
assertEquals(4, 1 shl 2)
|
||||
assertEquals(4, 1 shl 34)
|
||||
}
|
||||
|
||||
@Test fun shrForInt() {
|
||||
assertEquals(1, 2 shr 1)
|
||||
assertEquals(1, 2 shr 33)
|
||||
}
|
||||
|
||||
@Test fun ushrForInt() {
|
||||
assertEquals(2147483647, -1 ushr 1)
|
||||
assertEquals(2147483647, -1 ushr 33)
|
||||
}
|
||||
|
||||
@Test fun shlForUInt() {
|
||||
assertEquals(4u, 1u shl 2)
|
||||
assertEquals(4u, 1u shl 34)
|
||||
}
|
||||
|
||||
@Test fun shrForUInt() {
|
||||
assertEquals(1u, 2u shr 1)
|
||||
assertEquals(1u, 2u shr 33)
|
||||
|
||||
assertEquals(Int.MAX_VALUE.toUInt(), UInt.MAX_VALUE shr 1)
|
||||
assertEquals(Int.MAX_VALUE.toUInt(), UInt.MAX_VALUE shr 33)
|
||||
}
|
||||
|
||||
@Test fun shlForLong() {
|
||||
assertEquals(4L, 1L shl 2)
|
||||
assertEquals(4L, 1L shl 66)
|
||||
}
|
||||
|
||||
@Test fun shrForLong() {
|
||||
assertEquals(1L, 2L shr 1)
|
||||
assertEquals(1L, 2L shr 65)
|
||||
}
|
||||
|
||||
@Test fun ushrForLong() {
|
||||
assertEquals(Long.MAX_VALUE, -1L ushr 1)
|
||||
assertEquals(Long.MAX_VALUE, -1L ushr 65)
|
||||
}
|
||||
|
||||
@Test fun shlForULong() {
|
||||
assertEquals(4UL, 1UL shl 2)
|
||||
assertEquals(4UL, 1UL shl 66)
|
||||
}
|
||||
|
||||
@Test fun shrForULong() {
|
||||
assertEquals(1UL, 2UL shr 1)
|
||||
assertEquals(1UL, 2UL shr 65)
|
||||
|
||||
assertEquals(Long.MAX_VALUE.toULong(), ULong.MAX_VALUE shr 1)
|
||||
assertEquals(Long.MAX_VALUE.toULong(), ULong.MAX_VALUE shr 65)
|
||||
}
|
||||
|
||||
@Test fun invForInt() {
|
||||
|
||||
@@ -145,12 +145,24 @@ public inline class UInt @PublishedApi internal constructor(@PublishedApi intern
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun rangeTo(other: UInt): UIntRange = UIntRange(this, other)
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun shl(bitCount: Int): UInt = UInt(data shl bitCount)
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun shr(bitCount: Int): UInt = UInt(data ushr bitCount)
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun and(other: UInt): UInt = UInt(this.data and other.data)
|
||||
|
||||
@@ -145,12 +145,24 @@ public inline class ULong @PublishedApi internal constructor(@PublishedApi inter
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun rangeTo(other: ULong): ULongRange = ULongRange(this, other)
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun shl(bitCount: Int): ULong = ULong(data shl bitCount)
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun shr(bitCount: Int): ULong = ULong(data ushr bitCount)
|
||||
|
||||
/** Performs a bitwise AND operation between the two values. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline infix fun and(other: ULong): ULong = ULong(this.data and other.data)
|
||||
|
||||
@@ -844,17 +844,32 @@ public class Int private constructor() : Number(), Comparable<Int> {
|
||||
/** Returns the negative of this value. */
|
||||
public inline operator fun unaryMinus(): Int = 0 - this
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
@WasmInstruction(WasmInstruction.I32_SHL)
|
||||
public infix fun shl(bitCount: Int): Int =
|
||||
implementedAsIntrinsic
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
@WasmInstruction(WasmInstruction.I32_SHR_S)
|
||||
public infix fun shr(bitCount: Int): Int =
|
||||
implementedAsIntrinsic
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the five lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..31`.
|
||||
*/
|
||||
@WasmInstruction(WasmInstruction.I32_SHR_U)
|
||||
public infix fun ushr(bitCount: Int): Int =
|
||||
implementedAsIntrinsic
|
||||
@@ -1233,15 +1248,30 @@ public class Long private constructor() : Number(), Comparable<Long> {
|
||||
// return LongRange(this, other.toLong())
|
||||
// }
|
||||
|
||||
/** Shifts this value left by the [bitCount] number of bits. */
|
||||
/**
|
||||
* Shifts this value left by the [bitCount] number of bits.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public inline infix fun shl(bitCount: Int): Long =
|
||||
wasm_i64_shl(this, bitCount.toLong())
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public inline infix fun shr(bitCount: Int): Long =
|
||||
wasm_i64_shr_s(this, bitCount.toLong())
|
||||
|
||||
/** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */
|
||||
/**
|
||||
* Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.
|
||||
*
|
||||
* Note that only the six lowest-order bits of the [bitCount] are used as the shift distance.
|
||||
* The shift distance actually used is therefore always in the range `0..63`.
|
||||
*/
|
||||
public inline infix fun ushr(bitCount: Int): Long =
|
||||
wasm_i64_shr_u(this, bitCount.toLong())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user