我想将epoch毫秒打包成6个字节,但我有问题。我来介绍一下:
trace(t);
for (var i:int = 6; i > 0; i--) {
dataBuffer.writeByte(((t >>> 8*(i-1)) & 255));
trace(dataBuffer[dataBuffer.length - 1]);
}
输出:
1330454496254
131
254
197
68
131
254
我做错了什么?
答案 0 :(得分:2)
我只是猜测,但我认为你的t
变量在位操作生效之前会自动转换为int
。当然,这会破坏价值。
我认为在位操作中不可能使用Number
- AS3仅支持int
- s的那些。
根据您在t
中获取值的方式,您可能希望从2 int
开始,然后从这些字节中提取字节。
答案 1 :(得分:2)
Number
类型是IEEE 754 64位双精度数字,与普通int
的格式完全不同。这些位的排列方式并不完全相同。您正在寻找的是正常64位ByteArray
类型的int
表示形式,当然在ActionScript 3中不存在。
这是一个将Number
对象转换为“int64”等价物的函数:
private function numberToInt64Bytes(n:Number):ByteArray
{
// Write your IEEE 754 64-bit double-precision number to a byte array.
var b:ByteArray = new ByteArray();
b.writeDouble(n);
// Get the exponent.
var e:int = ((b[0] & 0x7F) << 4) | (b[1] >> 4);
// Significant bits.
var s:int = e - 1023;
// Number of bits to shift towards the right.
var x:int = (52 - s) % 8;
// Read and write positions in the byte array.
var r:int = 8 - int((52 - s) / 8);
var w:int = 8;
// Clear the first two bytes of the sign bit and the exponent.
b[0] &= 0x80;
b[1] &= 0xF;
// Add the "hidden" fraction bit.
b[1] |= 0x10;
// Shift everything.
while (w > 1) {
if (--r > 0) {
if (w < 8)
b[w] |= b[r] << (8 - x);
b[--w] = b[r] >> x;
} else {
b[--w] = 0;
}
}
// Now you've got your 64-bit signed two's complement integer.
return b;
}
请注意,它仅适用于特定范围内的整数,并且不处理“非数字”和无穷大等值。在其他情况下,它可能也会失败。
这是一个用法示例:
var n:Number = 1330454496254;
var bytes:ByteArray = numberToInt64Bytes(n);
trace("bytes:",
bytes[0].toString(16),
bytes[1].toString(16),
bytes[2].toString(16),
bytes[3].toString(16),
bytes[4].toString(16),
bytes[5].toString(16),
bytes[6].toString(16),
bytes[7].toString(16)
);
输出:
bytes: 0 0 1 35 c5 44 83 fe
以后序列化AS3中的数据以供Java程序读取应该很有用。
家庭作业:写int64BytesToNumber()