ソースを参照

added feq support to UnitBuilder, and slightly increased margin of error (it was failing on Math.sin(Math.PI / 2) == 1.0)

Simon Krajewski 12 年 前
コミット
3fe2ee1415
2 ファイル変更24 行追加12 行削除
  1. 4 1
      tests/unit/Test.hx
  2. 20 11
      tests/unit/UnitBuilder.hx

+ 4 - 1
tests/unit/Test.hx

@@ -13,7 +13,10 @@ package unit;
 
 	function feq( v : Float, v2 : Float, ?pos ) {
 		count++;
-		if( Math.abs(v - v2) > 1e-18 ) report(v+" should be "+v2,pos);
+		if (!Math.isFinite(v) || !Math.isFinite(v2))
+			eq(v, v2, pos);
+		else if ( Math.abs(v - v2) > 1e-15 )
+			report(v+" should be "+v2,pos);
 	}
 
 	function t( v, ?pos ) {

+ 20 - 11
tests/unit/UnitBuilder.hx

@@ -2,6 +2,7 @@ package unit;
 
 import haxe.macro.Context;
 import haxe.macro.Expr;
+import haxe.macro.Type;
 using StringTools;
 
 class UnitBuilder {
@@ -45,18 +46,26 @@ class UnitBuilder {
 		}
 	}
 	
-	static function collapseToAndExpr(el:Array<Expr>) {
-		return switch(el) {
-			case []: throw "";
-			case [e]: e;
-		case _:
-			var e = el.pop();
-			{ expr: EBinop(OpBoolAnd, e, collapseToAndExpr(el)), pos: e.pos }
-		}
-	}	
-	
 	static function mkEq(e1, e2, p) {
-		var e = macro eq($e1, $e2);
+		function isFloat(e) {
+			try return switch(Context.typeof(e)) {
+				case TAbstract(tr, _):
+					tr.get().name == "Float";
+				case _:
+					false;
+			} catch (e:Dynamic) {
+				return false;
+			}
+		}
+		var e = switch [isFloat(e1) || isFloat(e2), e2.expr] {
+			// hell yeah
+			case [true, EField( { expr:EConst(CIdent("Math")) }, "POSITIVE_INFINITY" | "NEGATIVE_INFINITY")] if (Context.defined("cpp") || Context.defined("php")):
+				macro Math.isFinite($e1);
+			case [true, _]:
+				macro feq($e1, $e2);
+			case _:
+				macro eq($e1, $e2);
+		}
 		return {
 			expr: e.expr,
 			pos: p