Kotlin 将数字分解为 2 的幂

Kotlin decomposing numbers into powers of 2

嗨,我正在用 kotlin 编写一个应用程序,需要将数字分解为 2 的幂。

我已经在 c#、PHP 和 swift 中完成了此操作,但 kotlin 的工作方式有所不同。

经过研究,我认为这与我的代码中的数字在某处变为负数有关,解决方案在于将一个或多个变量声明为 "Long" 以防止这种情况发生,但我一直无法弄清楚如何做到这一点。

这是我的代码:

    var salads = StringBuilder()
    var value = 127
    var j=0
    while (j < 256) {

        var mask = 1 shl j
        if(value != 0 && mask != 0)  {

            salads.append(mask)
            salads.append(",")

        }
        j += 1
    }

    // salads = (salads.dropLast()) // removes the final ","
    println("Salads = $salads")

这应该输出以下内容: 1,2,4,8,16,32,64 我实际得到的是:

1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,

有什么想法吗?

您想以某种方式执行 "value" 和 "mask" 的 "bitwise AND" 以确定 "value" 的第 j 位是否已设置。我想你只是在你的 kotlin 实现中忘记了那个测试。

这至少适用于您指定的一个输入:

fun powersOfTwo(value :Long): String {

    val result = ArrayList<String>()

    var i = 0
    var lastMask = 0

    while (lastMask < value) {

        val mask = 1 shl i

        if (value != 0.toLong() && mask < value) {

            result.add(mask.toString())
        }

        lastMask = mask
        i += 1
    }

    return result.joinToString(",")
}

运行 它在单元测试中:

@Test
fun addition_isCorrect() {

    val result = powersOfTwo(127)

    assertEquals("1,2,4,8,16,32,64", result)
}

测试通过。

嗨,我终于设法让它正常工作了:

fun decomposeByTwo(value :Int): String {

val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {

    var mask = 1 shl j
    if ((value and mask) != 0) {
        value -= mask
        result.add(mask.toString())

    }
    j += 1
}

return result.toString()
}

我希望这对试图掌握按位选项的人有所帮助!

您可以获得一个列表,其中包含符合 Int 的所有两个的幂,并使用中缀函数 and:

测试每个值是否包含它
val value = 126

val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64

在 Kotlin playground 中查看完整代码:https://pl.kotl.in/f4CZtmCyI