Browse Source

fixed Int64 bits shifts overflows

Nicolas Cannasse 14 years ago
parent
commit
a9112fef80
3 changed files with 27 additions and 3 deletions
  1. 7 3
      std/haxe/Int64.hx
  2. 18 0
      tests/unit/TestInt32.hx
  3. 2 0
      tests/unit/TestInt64.hx

+ 7 - 3
std/haxe/Int64.hx

@@ -159,15 +159,15 @@ class Int64 {
 	}
 
 	public static inline function shl( a : Int64, b : Int ) : Int64 {
-		return if( b < 32 ) new Int64( a.high.shl(b).or(a.low.ushr(32 - b)), a.low.shl(b) ) else new Int64( a.low.shl(b - 32), 0.ofInt() );
+		return if( b & 63 == 0 ) a else if( b & 63 < 32 ) new Int64( a.high.shl(b).or(a.low.ushr(32 - (b&63))), a.low.shl(b) ) else new Int64( a.low.shl(b - 32), 0.ofInt() );
 	}
 
 	public static inline function shr( a : Int64, b : Int ) : Int64 {
-		return if( b < 32 ) new Int64( a.high.shr(b), a.low.ushr(b).or(a.high.shl(32 - b)) ) else new Int64( a.high.shr(31), a.high.shr(b - 32) );
+		return if( b & 63 == 0 ) a else if( b & 63 < 32 ) new Int64( a.high.shr(b), a.low.ushr(b).or(a.high.shl(32 - (b&63))) ) else new Int64( a.high.shr(31), a.high.shr(b - 32) );
 	}
 
 	public static inline function ushr( a : Int64, b : Int ) : Int64 {
-		return if( b < 32 ) new Int64( a.high.ushr(b), a.low.ushr(b).or(a.high.shl(32 - b)) ) else new Int64( 0.ofInt(), a.high.ushr(b - 32) );
+		return if( b & 63 == 0 ) a else if( b & 63 < 32 ) new Int64( a.high.ushr(b), a.low.ushr(b).or(a.high.shl(32 - (b&63))) ) else new Int64( 0.ofInt(), a.high.ushr(b - 32) );
 	}
 
 	public static inline function and( a : Int64, b : Int64 ) : Int64 {
@@ -211,6 +211,10 @@ class Int64 {
 		return if( v != 0 ) v else Int32.ucompare(a.low, b.low);
 	}
 
+	public static inline function toStr( a : Int64 ) : String {
+		return a.toString();
+	}
+
 }
 
 

+ 18 - 0
tests/unit/TestInt32.hx

@@ -101,6 +101,24 @@ class TestInt32 extends Test {
 
 		eq( 0x050BCDEF.ofInt().mul(256.ofInt()).mod(0xFF.ofInt()).toInt(), 200 );
 
+		// bit shifts are % 32
+		
+		eq( i(i32(5).shl(0)), 5 );
+		eq( i(i32(5).shr(0)), 5 );
+		eq( i(i32(5).ushr(0)), 5 );
+
+		eq( i(i32(5).shl(32)), 5 );
+		eq( i(i32(5).shr(32)), 5 );
+		eq( i(i32(5).ushr(32)), 5 );
+
+		eq( i(i32(5).shl(33)), 10 );
+		eq( i(i32(5).shr(33)), 2 );
+		eq( i(i32(5).ushr(33)), 2 );
+		
+		eq( i(i32(5).shl(-5)), 671088640 );
+		eq( i(i32(5).shr(-31)), 2 );
+		eq( i(i32(5).ushr(-31)), 2 );
+		
 	}
 
 }

+ 2 - 0
tests/unit/TestInt64.hx

@@ -18,6 +18,8 @@ class TestInt64 extends Test {
 		eq32( p40.getLow(), 0, 0 );
 		eq32( p40.getHigh(), 0, 256 );
 		eq( Std.string(p40), "1099511627776" );
+		
+		eq( 1.ofInt().shl(0).toStr(), "1" );
 	}
 
 }