initial commit
This commit is contained in:
349
math/src/main/java/com/icegps/memory/Bits.kt
Normal file
349
math/src/main/java/com/icegps/memory/Bits.kt
Normal file
@@ -0,0 +1,349 @@
|
||||
package com.icegps.memory
|
||||
|
||||
import com.icegps.math.*
|
||||
import kotlin.rotateLeft as rotateLeftKotlin
|
||||
import kotlin.rotateRight as rotateRightKotlin
|
||||
|
||||
/** Returns the bits in memory of [this] float */
|
||||
public inline fun Float.reinterpretAsInt(): Int = this.toRawBits()
|
||||
/** Returns the bits in memory of [this] float */
|
||||
public inline fun Double.reinterpretAsLong(): Long = this.toRawBits()
|
||||
|
||||
/** Returns the float representation of [this] memory bits */
|
||||
public inline fun Int.reinterpretAsFloat(): Float = Float.fromBits(this)
|
||||
/** Returns the float representation of [this] memory bits */
|
||||
public inline fun Long.reinterpretAsDouble(): Double = Double.fromBits(this)
|
||||
|
||||
/** Rotates [this] [bits] bits to the left */
|
||||
public fun UInt.rotateLeft(bits: Int): UInt = this.rotateLeftKotlin(bits)
|
||||
/** Rotates [this] [bits] bits to the left */
|
||||
public fun Int.rotateLeft(bits: Int): Int = this.rotateLeftKotlin(bits)
|
||||
/** Rotates [this] [bits] bits to the left */
|
||||
public fun Long.rotateLeft(bits: Int): Long = this.rotateLeftKotlin(bits)
|
||||
|
||||
/** Rotates [this] [bits] bits to the right */
|
||||
public fun UInt.rotateRight(bits: Int): UInt = this.rotateRightKotlin(bits)
|
||||
/** Rotates [this] [bits] bits to the right */
|
||||
public fun Int.rotateRight(bits: Int): Int = this.rotateRightKotlin(bits)
|
||||
/** Rotates [this] [bits] bits to the right */
|
||||
public fun Long.rotateRight(bits: Int): Long = this.rotateRightKotlin(bits)
|
||||
|
||||
/** Reverses the bytes of [this] [Short]: AABB -> BBAA */
|
||||
public fun Short.reverseBytes(): Short {
|
||||
val low = ((this.toInt() ushr 0) and 0xFF)
|
||||
val high = ((this.toInt() ushr 8) and 0xFF)
|
||||
return ((high and 0xFF) or (low shl 8)).toShort()
|
||||
}
|
||||
|
||||
/** Reverses the bytes of [this] [Char]: AABB -> BBAA */
|
||||
public fun Char.reverseBytes(): Char = this.code.toShort().reverseBytes().toInt().toChar()
|
||||
|
||||
/** Reverses the bytes of [this] [Int]: AABBCCDD -> DDCCBBAA */
|
||||
public fun Int.reverseBytes(): Int {
|
||||
val v0 = ((this ushr 0) and 0xFF)
|
||||
val v1 = ((this ushr 8) and 0xFF)
|
||||
val v2 = ((this ushr 16) and 0xFF)
|
||||
val v3 = ((this ushr 24) and 0xFF)
|
||||
return (v0 shl 24) or (v1 shl 16) or (v2 shl 8) or (v3 shl 0)
|
||||
}
|
||||
|
||||
/** Reverses the bytes of [this] [Long]: AABBCCDDEEFFGGHH -> HHGGFFEEDDCCBBAA */
|
||||
public fun Long.reverseBytes(): Long {
|
||||
val v0 = (this ushr 0).toInt().reverseBytes().toLong() and 0xFFFFFFFFL
|
||||
val v1 = (this ushr 32).toInt().reverseBytes().toLong() and 0xFFFFFFFFL
|
||||
return (v0 shl 32) or (v1 shl 0)
|
||||
}
|
||||
|
||||
/** Reverse the bits of [this] Int: abcdef...z -> z...fedcba */
|
||||
public fun Int.reverseBits(): Int {
|
||||
var v = this
|
||||
v = ((v ushr 1) and 0x55555555) or ((v and 0x55555555) shl 1) // swap odd and even bits
|
||||
v = ((v ushr 2) and 0x33333333) or ((v and 0x33333333) shl 2) // swap consecutive pairs
|
||||
v = ((v ushr 4) and 0x0F0F0F0F) or ((v and 0x0F0F0F0F) shl 4) // swap nibbles ...
|
||||
v = ((v ushr 8) and 0x00FF00FF) or ((v and 0x00FF00FF) shl 8) // swap bytes
|
||||
v = ((v ushr 16) and 0x0000FFFF) or ((v and 0x0000FFFF) shl 16) // swap 2-byte long pairs
|
||||
return v
|
||||
}
|
||||
|
||||
/** Returns the number of leading zeros of the bits of [this] integer */
|
||||
public inline fun Int.countLeadingZeros(): Int = this.countLeadingZeroBits()
|
||||
|
||||
/** Returns the number of trailing zeros of the bits of [this] integer */
|
||||
public fun Int.countTrailingZeros(): Int = this.countTrailingZeroBits()
|
||||
|
||||
/** Returns the number of leading ones of the bits of [this] integer */
|
||||
public fun Int.countLeadingOnes(): Int = this.inv().countLeadingZeros()
|
||||
|
||||
/** Returns the number of trailing ones of the bits of [this] integer */
|
||||
public fun Int.countTrailingOnes(): Int = this.inv().countTrailingZeros()
|
||||
|
||||
/** Takes n[bits] of [this] [Int], and extends the last bit, creating a plain [Int] in one's complement */
|
||||
public fun Int.signExtend(bits: Int): Int = (this shl (32 - bits)) shr (32 - bits) // Int.SIZE_BITS
|
||||
/** Takes n[bits] of [this] [Long], and extends the last bit, creating a plain [Long] in one's complement */
|
||||
public fun Long.signExtend(bits: Int): Long = (this shl (64 - bits)) shr (64 - bits) // Long.SIZE_BITS
|
||||
|
||||
/** Creates an [Int] with [this] bits set to 1 */
|
||||
public fun Int.mask(): Int = (1 shl this) - 1
|
||||
/** Creates a [Long] with [this] bits set to 1 */
|
||||
public fun Long.mask(): Long = (1L shl this.toInt()) - 1L
|
||||
|
||||
/** Creates an [Int] with [this] bits set to 1, displaced [offset] bits */
|
||||
public fun Int.mask(offset: Int): Int = mask() shl offset
|
||||
/** Creates a [Long] with [this] bits set to 1, displaced [offset] bits */
|
||||
public fun Long.mask(offset: Int): Long = mask() shl offset
|
||||
|
||||
inline class IntMaskRange private constructor(val raw: Int) {
|
||||
val offset: Int get() = raw.extract8(0)
|
||||
val size: Int get() = raw.extract8(8)
|
||||
fun toMask(): Int = size.mask(offset)
|
||||
|
||||
override fun toString(): String = "IntMaskRange(offset=$offset, size=$size)"
|
||||
|
||||
fun extract(value: Int): Int = value.extract(offset, size)
|
||||
fun extractSigned(value: Int, signed: Boolean = true): Int = value.extractSigned(offset, size, signed)
|
||||
|
||||
companion object {
|
||||
fun fromRange(offset: Int, size: Int): IntMaskRange = IntMaskRange(0.insert8(offset, 0).insert8(size, 8))
|
||||
fun fromMask(mask: Int): IntMaskRange {
|
||||
if (mask == 0) return IntMaskRange(0)
|
||||
val offset = mask.countTrailingZeroBits()
|
||||
val size = (32 - mask.countLeadingZeroBits()) - offset
|
||||
return fromRange(offset, size)
|
||||
}
|
||||
}
|
||||
operator fun component1(): Int = offset
|
||||
operator fun component2(): Int = size
|
||||
}
|
||||
|
||||
fun Int.extractMaskRange(): IntMaskRange = IntMaskRange.fromMask(this)
|
||||
|
||||
//fun Int.getBit(offset: Int): Boolean = ((this ushr offset) and 1) != 0
|
||||
//fun Int.getBits(offset: Int, count: Int): Int = (this ushr offset) and count.mask()
|
||||
|
||||
/** Extracts [count] bits at [offset] from [this] [Int] */
|
||||
public fun Int.extract(offset: Int, count: Int): Int = (this ushr offset) and count.mask()
|
||||
/** Extracts a bits at [offset] from [this] [Int] (returning a [Boolean]) */
|
||||
inline fun Int.extract(offset: Int): Boolean = extract1(offset) != 0
|
||||
/** Extracts a bits at [offset] from [this] [Int] (returning a [Boolean]) */
|
||||
inline fun Int.extractBool(offset: Int): Boolean = extract1(offset) != 0
|
||||
/** Extracts 1 bit at [offset] from [this] [Int] */
|
||||
inline fun Int.extract1(offset: Int): Int = (this ushr offset) and 0b1
|
||||
/** Extracts 2 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract2(offset: Int): Int = (this ushr offset) and 0b11
|
||||
/** Extracts 3 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract3(offset: Int): Int = (this ushr offset) and 0b111
|
||||
/** Extracts 4 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract4(offset: Int): Int = (this ushr offset) and 0b1111
|
||||
/** Extracts 5 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract5(offset: Int): Int = (this ushr offset) and 0b11111
|
||||
/** Extracts 6 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract6(offset: Int): Int = (this ushr offset) and 0b111111
|
||||
/** Extracts 7 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract7(offset: Int): Int = (this ushr offset) and 0b1111111
|
||||
/** Extracts 8 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract8(offset: Int): Int = (this ushr offset) and 0b11111111
|
||||
/** Extracts 9 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract9(offset: Int): Int = (this ushr offset) and 0b111111111
|
||||
/** Extracts 10 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract10(offset: Int): Int = (this ushr offset) and 0b1111111111
|
||||
/** Extracts 11 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract11(offset: Int): Int = (this ushr offset) and 0b11111111111
|
||||
/** Extracts 12 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract12(offset: Int): Int = (this ushr offset) and 0b111111111111
|
||||
/** Extracts 13 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract13(offset: Int): Int = (this ushr offset) and 0b1111111111111
|
||||
/** Extracts 14 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract14(offset: Int): Int = (this ushr offset) and 0b11111111111111
|
||||
/** Extracts 15 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract15(offset: Int): Int = (this ushr offset) and 0b111111111111111
|
||||
/** Extracts 16 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract16(offset: Int): Int = (this ushr offset) and 0b1111111111111111
|
||||
/** Extracts 17 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract17(offset: Int): Int = (this ushr offset) and 0b11111111111111111
|
||||
/** Extracts 18 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract18(offset: Int): Int = (this ushr offset) and 0b111111111111111111
|
||||
/** Extracts 19 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract19(offset: Int): Int = (this ushr offset) and 0b1111111111111111111
|
||||
/** Extracts 20 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract20(offset: Int): Int = (this ushr offset) and 0b11111111111111111111
|
||||
/** Extracts 21 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract21(offset: Int): Int = (this ushr offset) and 0b111111111111111111111
|
||||
/** Extracts 22 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract22(offset: Int): Int = (this ushr offset) and 0b1111111111111111111111
|
||||
/** Extracts 23 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract23(offset: Int): Int = (this ushr offset) and 0b11111111111111111111111
|
||||
/** Extracts 24 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract24(offset: Int): Int = (this ushr offset) and 0xFFFFFF
|
||||
/** Extracts 25 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract25(offset: Int): Int = (this ushr offset) and 0b1111111111111111111111111
|
||||
/** Extracts 26 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract26(offset: Int): Int = (this ushr offset) and 0b11111111111111111111111111
|
||||
/** Extracts 27 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract27(offset: Int): Int = (this ushr offset) and 0b111111111111111111111111111
|
||||
/** Extracts 28 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract28(offset: Int): Int = (this ushr offset) and 0b1111111111111111111111111111
|
||||
/** Extracts 29 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract29(offset: Int): Int = (this ushr offset) and 0b11111111111111111111111111111
|
||||
/** Extracts 30 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract30(offset: Int): Int = (this ushr offset) and 0b111111111111111111111111111111
|
||||
/** Extracts 31 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract31(offset: Int): Int = (this ushr offset) and 0b1111111111111111111111111111111
|
||||
/** Extracts 32 bits at [offset] from [this] [Int] */
|
||||
inline fun Int.extract32(offset: Int): Int = (this ushr offset) and -1
|
||||
|
||||
|
||||
/** Extracts [count] bits at [offset] from [this] [Int] sign-extending its result if [signed] is set to true */
|
||||
public fun Int.extractSigned(offset: Int, count: Int, signed: Boolean): Int = if (signed) extractSigned(offset, count) else extract(offset, count)
|
||||
|
||||
/** Extracts [count] bits at [offset] from [this] [Int] sign-extending its result */
|
||||
public fun Int.extractSigned(offset: Int, count: Int): Int = ((this ushr offset) and count.mask()).signExtend(count)
|
||||
/** Extracts 8 bits at [offset] from [this] [Int] sign-extending its result */
|
||||
public fun Int.extract8Signed(offset: Int): Int = (this ushr offset).toByte().toInt()
|
||||
/** Extracts 16 bits at [offset] from [this] [Int] sign-extending its result */
|
||||
public fun Int.extract16Signed(offset: Int): Int = (this ushr offset).toShort().toInt()
|
||||
|
||||
/** Extracts 8 bits at [offset] from [this] [Int] as [Byte] */
|
||||
public fun Int.extractByte(offset: Int): Byte = (this ushr offset).toByte()
|
||||
/** Extracts 16 bits at [offset] from [this] [Int] as [Short] */
|
||||
public fun Int.extractShort(offset: Int): Short = (this ushr offset).toShort()
|
||||
|
||||
/** Extracts [count] at [offset] from [this] [Int] and convert the possible values into the range 0x00..[scale] */
|
||||
public fun Int.extractScaled(offset: Int, count: Int, scale: Int): Int = (extract(offset, count) * scale) / count.mask()
|
||||
/** Extracts [count] at [offset] from [this] [Int] and convert the possible values into the range 0.0..1.0 */
|
||||
public fun Int.extractScaledf01(offset: Int, count: Int): Float = extract(offset, count).toFloat() / count.mask().toFloat()
|
||||
|
||||
/** Extracts [count] at [offset] from [this] [Int] and convert the possible values into the range 0x00..0xFF */
|
||||
public fun Int.extractScaledFF(offset: Int, count: Int): Int = extractScaled(offset, count, 0xFF)
|
||||
/** Extracts [count] at [offset] from [this] [Int] and convert the possible values into the range 0x00..0xFF (if there are 0 bits, returns [default]) */
|
||||
public fun Int.extractScaledFFDefault(offset: Int, count: Int, default: Int): Int =
|
||||
if (count == 0) default else extractScaled(offset, count, 0xFF)
|
||||
|
||||
/** Replaces [this] bits from [offset] to [offset]+[count] with [value] and returns the result of doing such replacement */
|
||||
public fun Int.insert(value: Int, offset: Int, count: Int): Int {
|
||||
val mask = count.mask() shl offset
|
||||
val ovalue = (value shl offset) and mask
|
||||
return (this and mask.inv()) or ovalue
|
||||
}
|
||||
|
||||
public fun Int.insertNoClear(value: Int, offset: Int, count: Int): Int {
|
||||
return this or ((value and count.mask()) shl offset)
|
||||
}
|
||||
|
||||
public fun Int.clear(offset: Int, count: Int): Int {
|
||||
return (this and (count.mask() shl offset).inv())
|
||||
}
|
||||
|
||||
public fun Int.insert1(value: Int, offset: Int): Int = insertMask(value, offset, 0b1)
|
||||
public fun Int.insert2(value: Int, offset: Int): Int = insertMask(value, offset, 0b11)
|
||||
public fun Int.insert3(value: Int, offset: Int): Int = insertMask(value, offset, 0b111)
|
||||
public fun Int.insert4(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111)
|
||||
public fun Int.insert5(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111)
|
||||
public fun Int.insert6(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111)
|
||||
public fun Int.insert7(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111)
|
||||
public fun Int.insert8(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111)
|
||||
public fun Int.insert9(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111)
|
||||
public fun Int.insert10(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111)
|
||||
public fun Int.insert11(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111)
|
||||
public fun Int.insert12(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111)
|
||||
public fun Int.insert13(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111)
|
||||
public fun Int.insert14(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111)
|
||||
public fun Int.insert15(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111)
|
||||
public fun Int.insert16(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111)
|
||||
public fun Int.insert17(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111111)
|
||||
public fun Int.insert18(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111111)
|
||||
public fun Int.insert19(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111111)
|
||||
public fun Int.insert20(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111111111)
|
||||
public fun Int.insert21(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111111111)
|
||||
public fun Int.insert22(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111111111)
|
||||
public fun Int.insert23(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111111111111)
|
||||
public fun Int.insert24(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111111111111)
|
||||
public fun Int.insert25(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111111111111)
|
||||
public fun Int.insert26(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111111111111111)
|
||||
public fun Int.insert27(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111111111111111)
|
||||
public fun Int.insert28(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111111111111111)
|
||||
public fun Int.insert29(value: Int, offset: Int): Int = insertMask(value, offset, 0b11111111111111111111111111111)
|
||||
public fun Int.insert30(value: Int, offset: Int): Int = insertMask(value, offset, 0b111111111111111111111111111111)
|
||||
public fun Int.insert31(value: Int, offset: Int): Int = insertMask(value, offset, 0b1111111111111111111111111111111)
|
||||
public fun Int.insert32(value: Int, offset: Int): Int = insertMask(value, offset, -1)
|
||||
|
||||
/** Fast Insert: do not clear bits, assume affecting bits are 0 */
|
||||
public fun Int.finsert(value: Int, offset: Int): Int = this or (value shl offset)
|
||||
public fun Int.finsert24(value: Int, offset: Int): Int = this or ((value and 0xFFFFFF) shl offset)
|
||||
public fun Int.finsert16(value: Int, offset: Int): Int = this or ((value and 0xFFFF) shl offset)
|
||||
public fun Int.finsert12(value: Int, offset: Int): Int = this or ((value and 0xFFF) shl offset)
|
||||
public fun Int.finsert8(value: Int, offset: Int): Int = this or ((value and 0xFF) shl offset)
|
||||
public fun Int.finsert7(value: Int, offset: Int): Int = this or ((value and 0b1111111) shl offset)
|
||||
public fun Int.finsert6(value: Int, offset: Int): Int = this or ((value and 0b111111) shl offset)
|
||||
public fun Int.finsert5(value: Int, offset: Int): Int = this or ((value and 0b11111) shl offset)
|
||||
public fun Int.finsert4(value: Int, offset: Int): Int = this or ((value and 0b1111) shl offset)
|
||||
public fun Int.finsert3(value: Int, offset: Int): Int = this or ((value and 0b111) shl offset)
|
||||
public fun Int.finsert2(value: Int, offset: Int): Int = this or ((value and 0b11) shl offset)
|
||||
public fun Int.finsert1(value: Int, offset: Int): Int = this or ((value and 0b1) shl offset)
|
||||
public fun Int.finsert(value: Boolean, offset: Int): Int = finsert(value.toInt(), offset)
|
||||
|
||||
inline fun Int.insertMask(value: Int, offset: Int, mask: Int): Int {
|
||||
return (this and (mask shl offset).inv()) or ((value and mask) shl offset)
|
||||
}
|
||||
/** Replaces 1 bit at [offset] with [value] and returns the result of doing such replacement */
|
||||
public fun Int.insert(value: Boolean, offset: Int): Int {
|
||||
val bits = (1 shl offset)
|
||||
return if (value) this or bits else this and bits.inv()
|
||||
}
|
||||
|
||||
public fun Int.insertScaled(value: Int, offset: Int, count: Int, scale: Int): Int = insert((value * count.mask()) / scale, offset, count)
|
||||
public fun Int.insertScaledFF(value: Int, offset: Int, count: Int): Int = if (count == 0) this else this.insertScaled(value, offset, count, 0xFF)
|
||||
/** Extracts [count] at [offset] from [this] [Int] and convert the possible values into the range 0.0..1.0 */
|
||||
public fun Int.insertScaledf01(value: Float, offset: Int, count: Int): Int = this.insert((value.coerceIn(0f, 1f) * offset.mask()).toInt(), offset, count)
|
||||
|
||||
|
||||
/** Check if [this] has all the bits set in [bits] set */
|
||||
public infix fun Int.hasFlags(bits: Int): Boolean = (this and bits) == bits
|
||||
public infix fun Int.hasBits(bits: Int): Boolean = (this and bits) == bits
|
||||
|
||||
/** Check if a specific bit at [index] is set */
|
||||
public infix fun Int.hasBitSet(index: Int): Boolean = ((this ushr index) and 1) != 0
|
||||
|
||||
public infix fun Long.hasFlags(bits: Long): Boolean = (this and bits) == bits
|
||||
public infix fun Long.hasBits(bits: Long): Boolean = (this and bits) == bits
|
||||
|
||||
/** Creates an integer with only bit [bit] set */
|
||||
public fun bit(bit: Int): Int = 1 shl bit
|
||||
|
||||
/** Returns the integer [this] without the [bits] set */
|
||||
public fun Int.unsetBits(bits: Int): Int = this and bits.inv()
|
||||
|
||||
/** Returns the integer [this] with the [bits] set */
|
||||
public fun Int.setBits(bits: Int): Int = this or bits
|
||||
|
||||
/** Returns the integer [this] with the [bits] set or unset depending on the [set] parameter */
|
||||
public fun Int.setBits(bits: Int, set: Boolean): Int = if (set) setBits(bits) else unsetBits(bits)
|
||||
|
||||
public fun Int.without(bits: Int): Int = this and bits.inv()
|
||||
public fun Int.with(bits: Int): Int = this or bits
|
||||
|
||||
public fun Long.without(bits: Long): Long = this and bits.inv()
|
||||
public fun Long.with(bits: Long): Long = this or bits
|
||||
|
||||
/** Get high 32-bits of this Long */
|
||||
val Long.high: Int get() = (this ushr 32).toInt()
|
||||
/** Get low 32-bits of this Long */
|
||||
val Long.low: Int get() = this.toInt()
|
||||
|
||||
/** Get high 32-bits of this Long */
|
||||
val Long._high: Int get() = (this ushr 32).toInt()
|
||||
/** Get low 32-bits of this Long */
|
||||
val Long._low: Int get() = this.toInt()
|
||||
|
||||
inline fun Long.Companion.fromLowHigh(low: Int, high: Int): Long = (low.toLong() and 0xFFFFFFFFL) or (high.toLong() shl 32)
|
||||
|
||||
inline fun Int.fastForEachOneBits(block: (Int) -> Unit) {
|
||||
var value = this
|
||||
var index = 0
|
||||
while (value != 0) {
|
||||
val shift = value.countTrailingZeroBits()
|
||||
index += shift
|
||||
if (index < 32) block(index)
|
||||
value = value ushr (shift + 1)
|
||||
index++
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user