计数Kotlin中的位数

我目前正在计数的数字使用简单的string.length方法:

val number = 829 val length = number.toString().length 

我想知道这是一个好方法,还是在Kotlin有一个更合适的方法来做到这一点。

您可以在java.lang.Math使用标准的Java数学库。 log10函数会给你数字的长度减1(有一些例外)。 这个函数虽然双打,所以你必须来回转换。

在Kotlin中可以这样写length函数:

 fun Int.length() = when(this) { 0 -> 1 else -> Math.log10(Math.abs(toDouble())).toInt() + 1 } 

那么你可以这样调用它:

 println(829.length()) // Prints 3 println(-1234.length()) // Prints 4 (it disregards the minus sign) 

如果由于某种原因,你不想诉诸于字符串或双打,你可以使用二进制搜索整数数组:

 private val limits = arrayOf(-1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999) fun countDigits(x: Int): Int { assert(x >= 0) val result = limits.binarySearch(x) return result.xor(result.shr(31)) // one's complement absolute value } 

当然,如果你希望它是非常有效的,你可以对这个特定的用例进行二进制搜索硬编码,或者你得到了代码行的支付:

 fun countDigits(x: Int): Int { assert(x >= 0) if (x <= 99999) { if (x <= 99) { if (x <= 9) { return 1 } else { return 2 } } else { if (x <= 999) { return 3 } else { if (x <= 9999) { return 4 } else { return 5 } } } } else { if (x <= 9999999) { if (x <= 999999) { return 6 } else { return 7 } } else { if (x <= 99999999) { return 8 } else { if (x <= 999999999) { return 9 } else { return 10 } } } } } 

无论哪种方式,确保你有正确的所有这些边界情况:

 class CountDigitsTest { @Test fun oneDigit() { assertEquals(1, countDigits(0)) assertEquals(1, countDigits(9)) } @Test fun twoDigits() { assertEquals(2, countDigits(10)) assertEquals(2, countDigits(99)) } @Test fun threeDigits() { assertEquals(3, countDigits(100)) assertEquals(3, countDigits(999)) } @Test fun fourDigits() { assertEquals(4, countDigits(1000)) assertEquals(4, countDigits(9999)) } @Test fun fiveDigits() { assertEquals(5, countDigits(10000)) assertEquals(5, countDigits(99999)) } @Test fun sixDigits() { assertEquals(6, countDigits(100000)) assertEquals(6, countDigits(999999)) } @Test fun sevenDigits() { assertEquals(7, countDigits(1000000)) assertEquals(7, countDigits(9999999)) } @Test fun eightDigits() { assertEquals(8, countDigits(10000000)) assertEquals(8, countDigits(99999999)) } @Test fun nineDigits() { assertEquals(9, countDigits(100000000)) assertEquals(9, countDigits(999999999)) } @Test fun tenDigits() { assertEquals(10, countDigits(1000000000)) assertEquals(10, countDigits(Int.MAX_VALUE)) } } 

所有这一切都假设你不关心负整数。 如果你这样做,而且你在修改代码时遇到了麻烦,请随时寻求帮助。