mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
compiler: float comparison uses machine epsilon by default
This commit is contained in:
parent
f35f6083cd
commit
56e4ed1e6b
@ -1540,7 +1540,7 @@ fn (p mut Parser) bterm() string {
|
||||
// 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_float && tok == .eq) || (is_str || is_ustr)) && !p.is_js {
|
||||
if (is_float || is_str || is_ustr) && !p.is_js {
|
||||
p.gen(',')
|
||||
}
|
||||
else if p.is_sql && tok == .eq {
|
||||
@ -1594,9 +1594,16 @@ fn (p mut Parser) bterm() string {
|
||||
case Token.lt: p.cgen.set_placeholder(ph, 'ustring_lt(')
|
||||
}
|
||||
}
|
||||
if is_float && tok == .eq {
|
||||
if is_float {
|
||||
p.gen(')')
|
||||
p.cgen.set_placeholder(ph, '${expr_type}_eq(')
|
||||
switch tok {
|
||||
case Token.eq: p.cgen.set_placeholder(ph, '${expr_type}_eq(')
|
||||
case Token.ne: p.cgen.set_placeholder(ph, '${expr_type}_ne(')
|
||||
case Token.le: p.cgen.set_placeholder(ph, '${expr_type}_le(')
|
||||
case Token.ge: p.cgen.set_placeholder(ph, '${expr_type}_ge(')
|
||||
case Token.gt: p.cgen.set_placeholder(ph, '${expr_type}_gt(')
|
||||
case Token.lt: p.cgen.set_placeholder(ph, '${expr_type}_lt(')
|
||||
}
|
||||
}
|
||||
}
|
||||
return typ
|
||||
|
@ -26,6 +26,7 @@ pub fn ptr_str(ptr voidptr) string {
|
||||
}
|
||||
|
||||
// compare floats using C epsilon
|
||||
// ==
|
||||
pub fn (a f64) eq(b f64) bool {
|
||||
return C.fabs(a - b) <= C.DBL_EPSILON
|
||||
}
|
||||
@ -39,6 +40,78 @@ pub fn (a f32) eqbit(b f32) bool {
|
||||
return C.DEFAULT_EQUAL(a, b)
|
||||
}
|
||||
|
||||
// !=
|
||||
fn (a f64) ne(b f64) bool {
|
||||
return !a.eq(b)
|
||||
}
|
||||
fn (a f32) ne(b f32) bool {
|
||||
return !a.eq(b)
|
||||
}
|
||||
pub fn (a f64) nebit(b f64) bool {
|
||||
return C.DEFAULT_NOT_EQUAL(a, b)
|
||||
}
|
||||
pub fn (a f32) nebit(b f32) bool {
|
||||
return C.DEFAULT_NOT_EQUAL(a, b)
|
||||
}
|
||||
|
||||
// a < b
|
||||
fn (a f64) lt(b f64) bool {
|
||||
return a.ne(b) && a.ltbit(b)
|
||||
}
|
||||
fn (a f32) lt(b f32) bool {
|
||||
return a.ne(b) && a.ltbit(b)
|
||||
}
|
||||
fn (a f64) ltbit(b f64) bool {
|
||||
return C.DEFAULT_LT(a, b)
|
||||
}
|
||||
fn (a f32) ltbit(b f32) bool {
|
||||
return C.DEFAULT_LT(a, b)
|
||||
}
|
||||
|
||||
// a <= b
|
||||
fn (a f64) le(b f64) bool {
|
||||
return !a.gt(b)
|
||||
}
|
||||
fn (a f32) le(b f32) bool {
|
||||
return !a.gt(b)
|
||||
}
|
||||
fn (a f64) lebit(b f64) bool {
|
||||
return C.DEFAULT_LE(a, b)
|
||||
}
|
||||
fn (a f32) lebit(b f32) bool {
|
||||
return C.DEFAULT_LE(a, b)
|
||||
}
|
||||
|
||||
// a > b
|
||||
fn (a f64) gt(b f64) bool {
|
||||
return a.ne(b) && a.gtbit(b)
|
||||
}
|
||||
fn (a f32) gt(b f32) bool {
|
||||
return a.ne(b) && a.gtbit(b)
|
||||
}
|
||||
fn (a f64) gtbit(b f64) bool {
|
||||
return C.DEFAULT_GT(a, b)
|
||||
}
|
||||
fn (a f32) gtbit(b f32) bool {
|
||||
return C.DEFAULT_GT(a, b)
|
||||
}
|
||||
|
||||
// a >= b
|
||||
fn (a f64) ge(b f64) bool {
|
||||
return !a.lt(b)
|
||||
}
|
||||
fn (a f32) ge(b f32) bool {
|
||||
return !a.lt(b)
|
||||
}
|
||||
fn (a f64) gebit(b f64) bool {
|
||||
return C.DEFAULT_GE(a, b)
|
||||
}
|
||||
fn (a f32) gebit(b f32) bool {
|
||||
return C.DEFAULT_GE(a, b)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// fn (nn i32) str() string {
|
||||
// return i
|
||||
// }
|
||||
|
@ -17,12 +17,33 @@ fn test_float_equal_operator() {
|
||||
a -= 0.000001
|
||||
assert a == 1
|
||||
assert !a.eqbit(1)
|
||||
assert !(a != 1)
|
||||
assert a.nebit(1)
|
||||
a += 0.000001
|
||||
assert !(a < 1)
|
||||
assert !a.ltbit(1)
|
||||
assert !(a <= 1)
|
||||
assert !a.lebit(1)
|
||||
assert a > 1
|
||||
assert a.gtbit(1)
|
||||
assert a >= 1
|
||||
assert a.gebit(1)
|
||||
|
||||
a = f64(1)
|
||||
a += 0.000001
|
||||
a -= 0.000001
|
||||
assert a == 1
|
||||
assert !a.eqbit(1)
|
||||
assert !(a != 1)
|
||||
a += 0.000001
|
||||
assert !(a < 1)
|
||||
assert !a.ltbit(1)
|
||||
assert !(a <= 1)
|
||||
assert !a.lebit(1)
|
||||
assert a > 1
|
||||
assert a.gtbit(1)
|
||||
assert a >= 1
|
||||
assert a.gebit(1)
|
||||
}
|
||||
|
||||
fn test_str_methods() {
|
||||
|
Loading…
Reference in New Issue
Block a user