【问题标题】:How to correctly handle Byte values greater than 127 in Kotlin?如何在 Kotlin 中正确处理大于 127 的字节值?
【发布时间】:2016-12-03 17:18:07
【问题描述】:

假设我有一个 Kotlin 程序,其变量 b 类型为 Byte,外部系统向其中写入大于 127 的值。 “外部”意味着我无法更改它返回的值的类型。

val a:Int = 128 val b:Byte = a.toByte()

a.toByte() 和 b.toInt() 都返回 -128。

想象一下,我想从变量 b 中获取正确的值 (128)。我该怎么做?

换句话说:magicallyExtractRightValue 的什么实现将使以下测试运行?

@Test
fun testByteConversion() {
    val a:Int = 128
    val b:Byte = a.toByte()

    System.out.println(a.toByte())
    System.out.println(b.toInt())

    val c:Int = magicallyExtractRightValue(b)

    Assertions.assertThat(c).isEqualTo(128)
}

private fun magicallyExtractRightValue(b: Byte): Int {
    throw UnsupportedOperationException("not implemented")
}

更新 1:Thilo 建议的这个解决方案似乎有效。

private fun magicallyExtractRightValue(o: Byte): Int = when {
    (o.toInt() < 0) -> 255 + o.toInt() + 1
    else -> o.toInt()
}

【问题讨论】:

  • byte 是用 Java 签名的,所以你必须忍受这个。为什么必须使用byte? int 来自哪里?
  • 我有一个外部库,我不想更改。它给了我带有负数的字节类型值。
  • 所以图书馆已经给了你“-127”。为什么需要转换它?除非您以数字方式使用它,否则它不会产生影响。如果您确定该库确实“意味着” 128,则可以在结束时使用short 或int(通过对负数执行 255 + b 进行转换)。
  • 我需要实际的数值,因为在另一个第三方库中,该数值被用作数组中的索引。
  • 数组索引为int。您可以通过 int x = b &lt; 0 ? 255 + b : b; 从“无符号字节”转换

标签: types type-conversion kotlin


【解决方案1】:

在 Kotlin 1.3+ 中,您可以使用 unsigned types。例如toUByte (Kotlin Playground):

private fun magicallyExtractRightValue(b: Byte): Int {
    return b.toUByte().toInt()
}

甚至需要直接使用UByte 而不是Byte (Kotlin Playground):

private fun magicallyExtractRightValue(b: UByte): Int {
    return b.toInt()
}

对于 Kotlin 1.3 之前的版本,我建议使用 and 创建一个 extension function 来执行此操作:

fun Byte.toPositiveInt() = toInt() and 0xFF

示例用法:

val a: List<Int> = listOf(0, 1, 63, 127, 128, 244, 255)
println("from ints: $a")
val b: List<Byte> = a.map(Int::toByte)
println("to bytes: $b")
val c: List<Int> = b.map(Byte::toPositiveInt)
println("to positive ints: $c")

示例输出:

from ints: [0, 1, 63, 127, 128, 244, 255]
to bytes: [0, 1, 63, 127, -128, -12, -1]
to positive ints: [0, 1, 63, 127, 128, 244, 255]

【讨论】:

  • eclipse Kotlin 插件不知何故不知道按位and,这还能怎么做?
  • @Xerus 我还没有真正使用过 Eclipse 插件,所以我不确定该说什么,但我怀疑某些配置错误,因为and 是“kotlin-stdlib”的一部分。您可以尝试将其用作非中缀:toInt().and(0xFF).
  • 为什么这没有融入 Kotlin 中??!?
  • 根据您的数据,这对BluetoothGattCharacteristic 非常有帮助。谢谢。
【解决方案2】:

好老的printf 做我们想做的事:

java.lang.String.format("%02x", byte)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多