浏览代码

fixed i32 multiply overflow on JS (fixed issue #1532)

Nicolas Cannasse 12 年之前
父节点
当前提交
fb294a6df1
共有 1 个文件被更改,包括 21 次插入10 次删除
  1. 21 10
      std/haxe/Int64.hx

+ 21 - 10
std/haxe/Int64.hx

@@ -26,7 +26,7 @@ class Int64 {
 	var high : Int;
 	var low : Int;
 
-	function new(high, low) {
+	inline function new(high, low) {
 		this.high = i32(high);
 		this.low = i32(low);
 	}
@@ -39,6 +39,17 @@ class Int64 {
 		#end
 	}
 
+	@:extern static inline function i32mul(a:Int,b:Int) {
+		#if (php || js || flash8)
+		/*
+			We can't simply use i32(a*b) since we might overflow (52 bits precision in doubles)
+		*/
+		return i32(i32((a * (b >>> 16)) << 16) + (a * (b&0xFFFF)));
+		#else
+		return a * b;
+		#end
+	}
+	
 	#if as3 public #end function toString() {
 		if ((high|low) == 0 )
 			return "0";
@@ -104,16 +115,16 @@ class Int64 {
 		var mask = 0xFFFF;
 		var al = a.low & mask, ah = a.low >>> 16;
 		var bl = b.low & mask, bh = b.low >>> 16;
-		var p00 = i32(al * bl);
-		var p10 = i32(ah * bl);
-		var p01 = i32(al * bh);
-		var p11 = i32(ah * bh);
+		var p00 = al * bl;
+		var p10 = ah * bl;
+		var p01 = al * bh;
+		var p11 = ah * bh;
 		var low = p00;
-		var high = i32(p11 + i32((p01 >>> 16) + (p10 >>> 16)));
-		p01 = (p01 << 16); low = i32(low + p01); if( uicompare(low,p01) < 0 ) high = i32(high + 1);
-		p10 = (p10 << 16); low = i32(low + p10); if( uicompare(low,p10) < 0 ) high = i32(high + 1);
-		high = i32(high + i32(a.low * b.high));
-		high = i32(high + i32(a.high * b.low));
+		var high = i32(p11 + (p01 >>> 16) + (p10 >>> 16));
+		p01 = i32(p01 << 16); low = i32(low + p01); if( uicompare(low, p01) < 0 ) high = i32(high + 1);
+		p10 = i32(p10 << 16); low = i32(low + p10); if( uicompare(low, p10) < 0 ) high = i32(high + 1);
+		high = i32(high + i32mul(a.low,b.high));
+		high = i32(high + i32mul(a.high,b.low));
 		return new Int64(high, low);
 	}