问题
How would one convert from 2x32bit uints to a Number and back (assume max value of 2^52)?
I believe the following would theoretically work (passing around as ByteArray for clarity, but an Array could work as storage as well), But it doesn't because bitwise operators evidently force Number into 32 bits :\
(see: Binary math on Number objects limited to 32 bits?):
public static function read64BitNumberFromBuffer(buffer:ByteArray):Number {
var ch1:uint = buffer.readUnsignedInt();
var ch2:uint = buffer.readUnsignedInt();
var num:Number = ((ch1 << 32) | ch2);
return(num);
}
public static function write64BitNumberToBuffer(num:Number):ByteArray {
var ch1:uint = uint((num & 0xFFFFFFFF00000000) >> 32);
var ch2:uint = uint(num & 0xFFFFFFFF);
var buffer:ByteArray = new ByteArray();
buffer.writeUnsignedInt(ch1);
buffer.writeUnsignedInt(ch2);
return(buffer);
}
One could use a library like as3crypto's BigInteger to handle this, but that seems like an awful lot of bloat for such a discrete need. Is there a robust bit of code that could be injected into the above functions to make them return the correct values?
Although I'd prefer a pure Actionscript solution, as a point of interest- are bitwise operators in Crossbridge also limited to 32 bits? (btw- I need 1500 reputation to create a tag "crossbridge", can someone do it on my behalf?)
EDIT: Tried readDouble()/writeDouble() as well but it seemed to want to switch to reverse the bytes for some reason under a more thorough test (tried playing with endian setting, to no avail other than it did affect output in the wrong way)
回答1:
OK- this seems to work perfectly:
package
{
import flash.display.Sprite;
import flash.utils.ByteArray;
public class TEMP extends Sprite
{
public function TEMP()
{
var targetNumber:Number = 6697992365;
var buffer:ByteArray = new ByteArray();
var testNumber:Number;
write64BitNumberToBuffer(buffer, targetNumber);
buffer.position = 0;
testNumber = read64BitNumberFromBuffer(buffer);
if(targetNumber == testNumber) {
trace("Passed! Both numbers are", targetNumber);
} else {
trace("Failed! Test number is", testNumber, "When it should be", targetNumber);
}
}
public static function read64BitNumberFromBuffer(buffer:ByteArray):Number {
var finalNumber:Number;
var str:String = '';
var byte:uint;
var chr:String;
while(str.length < 16) {
byte = buffer.readUnsignedByte();
chr = byte.toString(16);
if(chr.length == 1) {
chr = '0' + chr;
}
str += chr;
}
finalNumber = Number('0x' + str);
return(finalNumber);
}
public static function write64BitNumberToBuffer(buffer:ByteArray, num:Number) {
var hexString:String = num.toString(16);
var idx:uint = 16 - hexString.length;
var byte:uint;
while(idx--) {
hexString = '0' + hexString;
}
for(idx = 0; idx < hexString.length; idx += 2) {
byte = uint('0x' + hexString.substr(idx, 2));
buffer.writeByte(byte);
}
}
}
}
Output: Passed! Both numbers are 6697992365
来源:https://stackoverflow.com/questions/21758669/converting-2x32-bit-uint-number