Reputation: 2101
I try to add two numbers, but don't get correct result
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
When I got the wrong result, I thought it exceed the Number's max value,so I test it and it doesn't trace false as I thought.
Upvotes: 0
Views: 71
Reputation: 5267
Yes, the problem is in Number
as @Phylogenesis mentioned, it's actually 64 bit double with 52 bits for mantis, but your result exceededs that.
The good news are that there is a workaround for that, event two :)
Use some BigInteger
/LongInt
AS3 impelementation (you can google several of them), for instance BigInteger
from as3crypto, or LongInt
from lodgamebox
It's currently only for multiplying, but you can modify that solution as a small task. For best performance (without creation of temporary arrays/byte arrays) you can use that utility method that I created once (it's based on LongInt
from lodgamebox
library)
/**
* 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;
}
Upvotes: 1