Получить номер из двух монет - PullRequest
2 голосов
/ 22 марта 2011

Я читаю 64-разрядное целое число со знаком (Java long) из сети во Flash + ActionScript3 и сохраняю его как два uint (первые и последние 32 бита).

var l:LongNumber = new LongNumber();
l.msb = socket.readUnsignedInt();
l.lsb = socket.readUnsignedInt();

Как я могу преобразовать его в фактическое число как Number?

Я знаю, Number может содержать только 53-разрядные целые числа, а не 64, но этого достаточно (хотя было бы неплохо бросить Error при преобразовании больших чисел).

Ответы [ 3 ]

1 голос
/ 22 марта 2011

Я нашел свое решение (только для положительных чисел)

(Number(msb) * Math.pow(2, 32)) + Number(lsb)

или жесткое кодирование 2 ^ 32

(Number(msb) * 4294967296) + Number(lsb)

1 голос
/ 24 марта 2011

Да, readDouble () здесь бесполезно, оно будет интерпретировать ваше 64-битное целое как форматированное с плавающей запятой IEEE 754 с плавающей запятой (знаковый бит + 11 экспонентных бит + 52 дробных бита), и это получитВы - результат мусора.

(Число (мсб) * Math.pow (2, 32)) + Число (lsb) не является полным решением, если вам нужно поддерживать отрицательные числа,Этот код получает правильный результат только в том случае, если ваш номер равен нулю или положительное число не превышает 2 ^ 63-1 (например, бит знака не установлен).Если бит знака установлен, ваш код будет эффективно интерпретировать 64 бита как целое число без знака, а это не то, что отправляет вам Java.Если вы используете свое решение и задаетесь вопросом, почему вы всегда получаете положительный результат, вот почему.

Возможно, есть действительно крутой трюк для поддержки отрицательных и положительных чисел в одной строке кода, нопотому что я не могу решить это прямо сейчас, я скажу вам простой способ, которым я вижу решение в моей голове:

Я бы использовал msb & 0x80000000 , чтобы прочитать знакнемного.Если он не установлен, используйте формулу выше.Если он установлен, сначала преобразуйте число из дополнительного формата 2 в формат без знака:

msb = (msb ^ 0xFFFFFFFF);

lsb = (lsb^ 0xFFFFFFFF) + 1;

Затем примените ваш форум к msb и lsb и (поскольку бит знака был установлен) умножьте полученное число на -1.

if (msb & 0x80000000)
{
    msb ^= 0xFFFFFFFF;
    lsb ^= 0xFFFFFFFF;
    result = -(Number(msb)*4294967296 + Number(lsb) + 1);
}
else
{
    result = Number(msb)*4294967296 + Number(lsb);
}
0 голосов
/ 22 марта 2011

readDouble()
UPD:

var ba:ByteArray = new ByteArray();
ba.writeUnsignedInt(uint1);
ba.writeUnsignedInt(uint2);
ba.position = 0;
result = ba.readDouble();
...