今天遇到一个 在As3, JS里面显示Int64问题。 JS,AS只有Number类型, 最大能支持的整数是 +2^53 ,及(−9007199254740992 到 9007199254740992) 当数字超过限度时,只能直接显示对应的字符串,无法用Number来转化。
网上找了一个开源的库, 将Int64分成2个32位的数,存储在一个对象的high,low字段里。 通过 higth * 4294967296 + low 来表示对应数;然后实现Int64.toString() 方法, 显示出对应的字符串。
开源库在实现的这个方法有问题,没能正确计算。 我花了点时间 修改了这个问题。
大致思路是 对该数 取余 y=x%10; x= x/10; 将余数y放到数组里, 结果x不为0就继续重复上述步骤, 最后得到的数组反序就是要得的字符串;
当用high,low 2段来表示数时,取余运算就稍微比较复杂了, 需要用到下面的取余运算规则
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p
(1) (a - b) % p = (a % p - b % p) % p
(2) (a * b) % p = (a % p * b % p) % p
(3) a ^ b % p = ((a % p)^b) % p
(4) 结合律: ((a+b) % p + c) % p = (a + (b+c) % p) % p
(5) ((a*b) % p * c)% p = (a * (b*c) % p) % p
(6) 交换律: (a + b) % p = (b+a) % p
(7) (a * b) % p = (b * a) % p
(8) 分配律: ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p
重要定理
若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);
(10) 若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);
(11) 若a≡b (% p),c≡d (% p),
则 (a + c) ≡ (b + d) (%p),
(a - c) ≡ (b - d) (%p),
(a * c) ≡ (b * d) (%p),
(a / c) ≡ (b / d) (%p);
// 一些关键代码
function div( n:unit):uint
{
var MaxMod:uint = 0x100000000%n;
var modHigh:uint = hight%n;
var mod:uint = ((modHigh * MaxMod)%n + low%n)%n;
hight = Math.floor( high/n);
low = Math.floor((modHigh * 0x100000000 + low)/n );
high += Math.floor( low/0x100000000);
return mod;
}
// toString()里的处理部分
var digitChars:Array = [];
var tmp:Int64 = new UInt64(high, low);
if( high < 0)
{
// 负数的话,时补码表示的; 反码再加1 得到原码
tmp.bitwiseNot();
tmp.add(1);
}
do
{
var digit:uint = tmp.div( radix);
digitChars.push( digit < 10 ? '0' : 'a').charCodeAt() + digit);
}
while( tmp.high != 0)
var flag:String = high < 0 ? "-" : "";
return flag + tmp.low.toString(radix) + String.fromCharCode.apply(String, digitChars.reverse());