scala-将Int序列化为ArrayBuffer[Byte]。小把戏出错了
我想将一个数组序列化为字节数组或数组缓冲区 我意识到我可以使用“java.nio.ByteBuffer”,但我只是为了好玩而尝试,并试图自己去做 以下代码适用于正整数,但在序列化负整数时出错。 有人能解释一下原因或者给我一个更正吗scala-将Int序列化为ArrayBuffer[Byte]。小把戏出错了,scala,bit-manipulation,Scala,Bit Manipulation,我想将一个数组序列化为字节数组或数组缓冲区 我意识到我可以使用“java.nio.ByteBuffer”,但我只是为了好玩而尝试,并试图自己去做 以下代码适用于正整数,但在序列化负整数时出错。 有人能解释一下原因或者给我一个更正吗 import scala.collection.mutable.ArrayBuffer object b { val INTBYTES:Int = 4 // int is 4 bytes def toArrayBuf(x:Int): ArrayBuffer
import scala.collection.mutable.ArrayBuffer
object b {
val INTBYTES:Int = 4 // int is 4 bytes
def toArrayBuf(x:Int): ArrayBuffer[Byte] = {
val buf = new ArrayBuffer[Byte](INTBYTES)
for(i <- 0 until INTBYTES) {
buf += ((x >>> (INTBYTES - i - 1 << 3)) & 0xFF).toByte
}
buf
}
}
但是这个带负int的函数做了一些奇怪的事情:-
scala> val test2:Int = 0x8f0f0f0f
test2: Int = -1894838513
scala> println(test2.toBinaryString)
10001111000011110000111100001111
scala> val t2 = b.toArrayBuf(test2)
t2: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(-113, 15, 15, 15)
scala> t2.foreach( it => printf("%s ",it.toInt.toBinaryString))
11111111111111111111111110001111 1111 1111 1111
请注意,整个int的第一个字节已填充为1,它应为“10001111”
有什么想法吗
供参考
即时通讯使用:-
scala -version
Scala code runner version 2.10.1 -- Copyright 2002-2013, LAMP/EPFL
java -fullversion
java full version "1.7.0_40-b31"
with OpenJDK
感谢Scala的
ToBinarysting
方法遵从Integer
上的Java方法。从这些文件中:
公共静态字符串toBinaryString(int i)
返回整数参数的无符号字符串表示形式
以2为底的整数。无符号整数值是参数加号
2^32如果参数是否定的;否则,它等于
论点此值在中转换为ASCII数字字符串
二进制(基2),无额外的前导0
换句话说,它是按规定工作的。您的位旋转似乎是正常的,但当您打印出数字时,您需要意识到字符的数量取决于数据类型的长度。(例如,二进制中的-1:Int是11111111111,而-1:Byte是11111111。)正数可以不使用它,因为前导零没有显示,如上所述
解决方案:将您自己的设置为字节的二进制字符串
,或者仅从Int版本中获取最右边的8位数字就可以了(尽管效率较低),即
Scala的
tobinarysting
方法遵从Integer
上的Java方法。从这些文件中:
公共静态字符串toBinaryString(int i)
返回整数参数的无符号字符串表示形式
以2为底的整数。无符号整数值是参数加号
2^32如果参数是否定的;否则,它等于
论点此值在中转换为ASCII数字字符串
二进制(基2),无额外的前导0
换句话说,它是按规定工作的。您的位旋转似乎是正常的,但当您打印出数字时,您需要意识到字符的数量取决于数据类型的长度。(例如,二进制中的-1:Int是11111111111,而-1:Byte是11111111。)正数可以不使用它,因为前导零没有显示,如上所述
解决方案:将您自己的设置为字节的二进制字符串
,或者仅从Int版本中获取最右边的8位数字就可以了(尽管效率较低),即
根据Luigi的建议,我为Byte砍掉了一个皮条客,该皮条客提供了一个正常工作的Tobinarysting,以防其他人遇到类似的问题
object b {
val INTBYTES:Int = 4 // int is 4 bytes
val SIZEBYTE:Short = 8
def toArrayBuf(x:Int): ArrayBuffer[Byte] = {
val buf = new ArrayBuffer[Byte](INTBYTES)
for(i <- 0 until INTBYTES) {
buf += ((x >>> (INTBYTES - i - 1 << 3)) & 0xFF).toByte
}
buf
}
def toBinaryString(x: Byte): String = {
val buf = new StringBuilder(SIZEBYTE)
for(i <- 0 until SIZEBYTE) {
buf.append((x >>> (SIZEBYTE - i - 1)) & 0x01)
}
buf.toString()
}
}
//pimp Byte
implicit def fooBar(byte: Byte) = new {def toBinaryString = b.toBinaryString(byte)}
及
感谢Luigi接受Luigi的建议,我为Byte创建了一个pimp,它提供了一个正常工作的Tobinarysting,以防其他人遇到类似问题。我就是这么做的
object b {
val INTBYTES:Int = 4 // int is 4 bytes
val SIZEBYTE:Short = 8
def toArrayBuf(x:Int): ArrayBuffer[Byte] = {
val buf = new ArrayBuffer[Byte](INTBYTES)
for(i <- 0 until INTBYTES) {
buf += ((x >>> (INTBYTES - i - 1 << 3)) & 0xFF).toByte
}
buf
}
def toBinaryString(x: Byte): String = {
val buf = new StringBuilder(SIZEBYTE)
for(i <- 0 until SIZEBYTE) {
buf.append((x >>> (SIZEBYTE - i - 1)) & 0x01)
}
buf.toString()
}
}
//pimp Byte
implicit def fooBar(byte: Byte) = new {def toBinaryString = b.toBinaryString(byte)}
及
感谢Luigi如果您想在scala中实现类似的功能,您可能需要查看akka.util.ByteString及其构建器。它包含各种有用的方法来转换具有不同端点的原语。它是不变的,所以它不像ByteBuffer那么低级。很好的建议,鲁迪格,我会用它,但正如我提到的,我是在为自己做实验,以获得更好的理解,干杯如果你想在scala中使用类似的东西,你可能想看看akka.util.ByteString及其构建器。它包含各种有用的方法来转换具有不同端点的原语。它是不变的,所以它不像ByteBuffer那么低级。好的建议鲁迪奇,我会用它,但正如我提到的,我正在为自己做实验,以获得更好的理解,干杯!谢谢你的回答。我很高兴这个小把戏是正确的,似乎很遗憾scala没有有用的二进制表示格式和转换用于接近机器类型。太好了!谢谢你的回答。我很高兴这个小把戏是正确的,但scala没有提供有用的二进制表示格式和转换,这似乎是一个遗憾。
object b {
val INTBYTES:Int = 4 // int is 4 bytes
val SIZEBYTE:Short = 8
def toArrayBuf(x:Int): ArrayBuffer[Byte] = {
val buf = new ArrayBuffer[Byte](INTBYTES)
for(i <- 0 until INTBYTES) {
buf += ((x >>> (INTBYTES - i - 1 << 3)) & 0xFF).toByte
}
buf
}
def toBinaryString(x: Byte): String = {
val buf = new StringBuilder(SIZEBYTE)
for(i <- 0 until SIZEBYTE) {
buf.append((x >>> (SIZEBYTE - i - 1)) & 0x01)
}
buf.toString()
}
}
//pimp Byte
implicit def fooBar(byte: Byte) = new {def toBinaryString = b.toBinaryString(byte)}
scala> val test:Int = 0x4f0f0f0f
test: Int = 1326386959
scala> println(test.toBinaryString)
1001111000011110000111100001111
scala> val t1 = toArrayBuf(test)
t1: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(79, 15, 15, 15)
scala> t1.foreach( it => printf("%s ",it.toBinaryString))
01001111 00001111 00001111 00001111
scala> val test2:Int = 0x8f0f0f0f
test2: Int = -1894838513
scala> println(test2.toBinaryString)
10001111000011110000111100001111
scala> val t2 = toArrayBuf(test2)
t2: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(-113, 15, 15, 15)
scala> t2.foreach( it => printf("%s ",it.toBinaryString))
10001111 00001111 00001111 00001111