添加两个数字不会得到正确的结果

时间:2015-01-13 09:37:20

标签: actionscript-3 numbers add

我尝试添加两个数字,但没有得到正确的结果

var n1:Number =  2785077255;
var n2:Number = 100000097214922752;
trace(Number(n1 + n2));//trace 100000100000000000, not 100000100000000007
trace((Number.MAX_VALUE - Number(n1 + n2)) > 100);//trace true

当我得到错误的结果时,我认为它超过了数字的最大值,所以我测试它并没有像我想象的那样追踪错误。

1 个答案:

答案 0 :(得分:1)

是的,问题出在Number,因为@Phylogenesis提到,它实际上是64位双倍,52位用于螳螂,但是你的结果超过了它。 好消息是,有一个解决方法,事件二:)

  1. 使用一些BigInteger / LongInt AS3强制转换(您可以对其中的几个进行google),例如来自BigIntegeras3cryptoLongInt来自lodgamebox

  2. 目前仅用于倍增,但您可以将该解决方案修改为一项小任务。为了获得最佳性能(不创建临时数组/字节数组),您可以使用我创建过一次的实用工具方法(它基于LongInt库中的lodgamebox

    /**
     * Safe multiplying of two 32 bits uint without precision lost.  
     * 
     * Usage:
     * Default behaviour (with 64 bit Number mantis overflow): 
     *      uint(1234567890 * 134775813) = 1878152736
     * 
     * Fixed correct result by that method: 
     *      uint(1234567890 * 134775813) = 1878152730
     * 
     * @param val1
     * @param val2
     * @return 
     * 
     */
    public static function multiplyLong(val1:uint, val2:uint):uint
    {
        var resNum:Number = val1*val2;
        //52 bits of mantis in 64 bit double (Number) without loose in precision
        if(resNum <= 0xFFFFFFFFFFFFF)
            return uint(resNum);
    
        //count only low 32 bits of multiplying result 
        var i:uint, mul:Number, ln:uint=0, hn:uint=0, _low:uint = val1;
        for (i = 1<<31; i; i >>>= 1)
        {
            if(val2 & i)
            {
                mul = _low * i;
                ln += mul & uint.MAX_VALUE;
            }
        }
        _low = ln;
    
        return _low;
    }