Числовой тип и побитовые операции - PullRequest
2 голосов
/ 29 февраля 2012

Я хочу упаковать миллисекунды эпохи в 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

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 02 марта 2012

Тип Number - это 64-разрядное число двойной точности IEEE 754, которое отличается от обычного int.Биты не выстроены совершенно одинаково.То, что вам нужно, это ByteArray представление нормального 64-битного 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()

2 голосов
/ 29 февраля 2012

Я просто догадываюсь, но я думаю, что ваша переменная t автоматически преобразуется в int, прежде чем операция с битами вступит в силу.Это, конечно, уничтожает значение.

Я не думаю, что возможно использовать Number в битовых операциях - AS3 поддерживает только те с int -s.

В зависимости откак вы получаете значение в t, вы можете начать с 2 int -s, а затем извлечь из них байты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...