From 6d483c0a56cc25ff677eef48e8e6250f00f0f315 Mon Sep 17 00:00:00 2001 From: hazohelet <48541090+hazohelet@users.noreply.github.com> Date: Mon, 30 Sep 2019 00:27:53 +0900 Subject: [PATCH] parser: float1 == float2 uses machine epsilon by default --- compiler/parser.v | 9 ++++++++- vlib/builtin/int.v | 9 +++++++++ vlib/builtin/int_test.v | 14 ++++++++++++++ vlib/math/math_test.v | 8 ++++---- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/compiler/parser.v b/compiler/parser.v index c481bc7fd3..923afef94f 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -1597,11 +1597,14 @@ fn (p mut Parser) bterm() string { p.expected_type = typ is_str := typ=='string' && !p.is_sql is_ustr := typ=='ustring' + is_float := typ=='f64' || typ=='f32' + expr_type := typ + tok := p.tok // if tok in [ .eq, .gt, .lt, .le, .ge, .ne] { if tok == .eq || tok == .gt || tok == .lt || tok == .le || tok == .ge || tok == .ne { p.fgen(' ${p.tok.str()} ') - if (is_str || is_ustr) && !p.is_js { + if ((is_float && tok == .eq) || (is_str || is_ustr)) && !p.is_js { p.gen(',') } else if p.is_sql && tok == .eq { @@ -1655,6 +1658,10 @@ fn (p mut Parser) bterm() string { case Token.lt: p.cgen.set_placeholder(ph, 'ustring_lt(') } } + if is_float && tok == .eq { + p.gen(')') + p.cgen.set_placeholder(ph, '${expr_type}_eq(') + } } return typ } diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 5543d9475d..5ec3726539 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -29,6 +29,15 @@ pub fn ptr_str(ptr voidptr) string { pub fn (a f64) eq(b f64) bool { return C.fabs(a - b) <= C.DBL_EPSILON } +pub fn (a f32) eq(b f32) bool { + return C.fabsf(a - b) <= C.FLT_EPSILON +} +pub fn (a f64) eqbit(b f64) bool { + return C.DEFAULT_EQUAL(a, b) +} +pub fn (a f32) eqbit(b f32) bool { + return C.DEFAULT_EQUAL(a, b) +} // fn (nn i32) str() string { // return i diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index eae41cce39..0a2389c1e6 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -11,6 +11,20 @@ fn test_const() { assert u == 1 // make sure this works without the cast } +fn test_float_equal_operator() { + mut a := f32(1) + a += 0.000001 + a -= 0.000001 + assert a == 1 + assert !a.eqbit(1) + + a = f64(1) + a += 0.000001 + a -= 0.000001 + assert a == 1 + assert !a.eqbit(1) +} + fn test_str_methods() { assert i8(1).str() == '1' assert i8(-1).str() == '-1' diff --git a/vlib/math/math_test.v b/vlib/math/math_test.v index c52300b7db..202556489c 100644 --- a/vlib/math/math_test.v +++ b/vlib/math/math_test.v @@ -37,14 +37,14 @@ fn test_factorial() { fn test_erf() { assert math.erf(0) == 0 - assert (math.erf(1.5) + math.erf(-1.5)).eq(0) + assert math.erf(1.5) + math.erf(-1.5) == 0 assert math.erfc(0) == 1 - assert (math.erf(2.5) + math.erfc(2.5)).eq(1) - assert (math.erfc(3.6) + math.erfc(-3.6)).eq(2) + assert math.erf(2.5) + math.erfc(2.5) == 1 + assert math.erfc(3.6) + math.erfc(-3.6) == 2 } fn test_gamma() { assert math.gamma(1) == 1 assert math.gamma(5) == 24 - assert math.log_gamma(4.5).eq(math.log(math.gamma(4.5))) + assert math.log_gamma(4.5) == math.log(math.gamma(4.5)) }