我尝试添加两个数字,但没有得到正确的结果
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
当我得到错误的结果时,我认为它超过了数字的最大值,所以我测试它并没有像我想象的那样追踪错误。
答案 0 :(得分:1)
是的,问题出在Number
,因为@Phylogenesis提到,它实际上是64位双倍,52位用于螳螂,但是你的结果超过了它。
好消息是,有一个解决方法,事件二:)
使用一些BigInteger
/ LongInt
AS3强制转换(您可以对其中的几个进行google),例如来自BigInteger
的as3crypto或LongInt
来自lodgamebox
目前仅用于倍增,但您可以将该解决方案修改为一项小任务。为了获得最佳性能(不创建临时数组/字节数组),您可以使用我创建过一次的实用工具方法(它基于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;
}