Converting 2x32 bit uint <-> Number

江枫思渺然 提交于 2019-12-25 06:33:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!