Merge pull request #1122 from rtfeldman/num-sqrt-bugfix

Fix bug in Num.sqrt
This commit is contained in:
Richard Feldman 2021-03-28 12:42:44 -04:00 committed by GitHub
commit 706aaa26d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 51 deletions

View file

@ -413,8 +413,8 @@ fn lowlevel_4(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def {
/// Num.maxInt : Int /// Num.maxInt : Int
fn num_max_int(symbol: Symbol, var_store: &mut VarStore) -> Def { fn num_max_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh(); let int_var = var_store.fresh();
let int_percision_var = var_store.fresh(); let int_precision_var = var_store.fresh();
let body = Int(int_var, int_percision_var, i64::MAX.into()); let body = Int(int_var, int_precision_var, i64::MAX.into());
Def { Def {
annotation: None, annotation: None,
@ -428,8 +428,8 @@ fn num_max_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
/// Num.minInt : Int /// Num.minInt : Int
fn num_min_int(symbol: Symbol, var_store: &mut VarStore) -> Def { fn num_min_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh(); let int_var = var_store.fresh();
let int_percision_var = var_store.fresh(); let int_precision_var = var_store.fresh();
let body = Int(int_var, int_percision_var, i64::MIN.into()); let body = Int(int_var, int_precision_var, i64::MIN.into());
Def { Def {
annotation: None, annotation: None,
@ -1133,50 +1133,36 @@ fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bool_var = var_store.fresh(); let bool_var = var_store.fresh();
let float_var = var_store.fresh(); let float_var = var_store.fresh();
let unbound_zero_var = var_store.fresh(); let unbound_zero_var = var_store.fresh();
let percision_var = var_store.fresh(); let precision_var = var_store.fresh();
let ret_var = var_store.fresh(); let ret_var = var_store.fresh();
let body = If { let body = If {
branch_var: ret_var, branch_var: ret_var,
cond_var: bool_var, cond_var: bool_var,
branches: vec![( branches: vec![(
// if-condition no_region(RunLowLevel {
no_region( op: LowLevel::NumGte,
// Num.neq denominator 0 args: vec![
RunLowLevel { (float_var, Var(Symbol::ARG_1)),
op: LowLevel::NotEq, (float_var, Float(unbound_zero_var, precision_var, 0.0)),
args: vec![ ],
(float_var, Var(Symbol::ARG_1)), ret_var: bool_var,
(float_var, Float(unbound_zero_var, percision_var, 0.0)), }),
],
ret_var: bool_var,
},
),
// denominator was not zero
no_region(
// Ok (Float.#divUnchecked numerator denominator)
tag(
"Ok",
vec![
// Num.#divUnchecked numerator denominator
RunLowLevel {
op: LowLevel::NumSqrtUnchecked,
args: vec![(float_var, Var(Symbol::ARG_1))],
ret_var: float_var,
},
],
var_store,
),
),
)],
final_else: Box::new(
// denominator was zero
no_region(tag( no_region(tag(
"Err", "Ok",
vec![tag("DivByZero", Vec::new(), var_store)], vec![RunLowLevel {
op: LowLevel::NumSqrtUnchecked,
args: vec![(float_var, Var(Symbol::ARG_1))],
ret_var: float_var,
}],
var_store, var_store,
)), )),
), )],
final_else: Box::new(no_region(tag(
"Err",
vec![tag("SqrtOfNegative", Vec::new(), var_store)],
var_store,
))),
}; };
defn( defn(
@ -1387,8 +1373,8 @@ fn num_int_cast(symbol: Symbol, var_store: &mut VarStore) -> Def {
/// Num.maxI128: I128 /// Num.maxI128: I128
fn num_max_i128(symbol: Symbol, var_store: &mut VarStore) -> Def { fn num_max_i128(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh(); let int_var = var_store.fresh();
let int_percision_var = var_store.fresh(); let int_precision_var = var_store.fresh();
let body = Int(int_var, int_percision_var, i128::MAX); let body = Int(int_var, int_precision_var, i128::MAX);
let std = roc_builtins::std::types(); let std = roc_builtins::std::types();
let solved = std.get(&symbol).unwrap(); let solved = std.get(&symbol).unwrap();
@ -2653,7 +2639,7 @@ fn num_div_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bool_var = var_store.fresh(); let bool_var = var_store.fresh();
let num_var = var_store.fresh(); let num_var = var_store.fresh();
let unbound_zero_var = var_store.fresh(); let unbound_zero_var = var_store.fresh();
let percision_var = var_store.fresh(); let precision_var = var_store.fresh();
let ret_var = var_store.fresh(); let ret_var = var_store.fresh();
let body = If { let body = If {
@ -2667,7 +2653,7 @@ fn num_div_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
op: LowLevel::NotEq, op: LowLevel::NotEq,
args: vec![ args: vec![
(num_var, Var(Symbol::ARG_2)), (num_var, Var(Symbol::ARG_2)),
(num_var, Float(unbound_zero_var, percision_var, 0.0)), (num_var, Float(unbound_zero_var, precision_var, 0.0)),
], ],
ret_var: bool_var, ret_var: bool_var,
}, },
@ -2716,7 +2702,7 @@ fn num_div_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
let bool_var = var_store.fresh(); let bool_var = var_store.fresh();
let num_var = var_store.fresh(); let num_var = var_store.fresh();
let unbound_zero_var = var_store.fresh(); let unbound_zero_var = var_store.fresh();
let unbound_zero_percision_var = var_store.fresh(); let unbound_zero_precision_var = var_store.fresh();
let ret_var = var_store.fresh(); let ret_var = var_store.fresh();
let body = If { let body = If {
@ -2732,7 +2718,7 @@ fn num_div_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
(num_var, Var(Symbol::ARG_2)), (num_var, Var(Symbol::ARG_2)),
( (
num_var, num_var,
Int(unbound_zero_var, unbound_zero_percision_var, 0), Int(unbound_zero_var, unbound_zero_precision_var, 0),
), ),
], ],
ret_var: bool_var, ret_var: bool_var,
@ -2787,7 +2773,7 @@ fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh(); let list_var = var_store.fresh();
let len_var = var_store.fresh(); let len_var = var_store.fresh();
let zero_var = var_store.fresh(); let zero_var = var_store.fresh();
let zero_percision_var = var_store.fresh(); let zero_precision_var = var_store.fresh();
let list_elem_var = var_store.fresh(); let list_elem_var = var_store.fresh();
let ret_var = var_store.fresh(); let ret_var = var_store.fresh();
@ -2802,7 +2788,7 @@ fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
RunLowLevel { RunLowLevel {
op: LowLevel::NotEq, op: LowLevel::NotEq,
args: vec![ args: vec![
(len_var, Int(zero_var, zero_percision_var, 0)), (len_var, Int(zero_var, zero_precision_var, 0)),
( (
len_var, len_var,
RunLowLevel { RunLowLevel {
@ -2826,7 +2812,7 @@ fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
op: LowLevel::ListGetUnsafe, op: LowLevel::ListGetUnsafe,
args: vec![ args: vec![
(list_var, Var(Symbol::ARG_1)), (list_var, Var(Symbol::ARG_1)),
(len_var, Int(zero_var, zero_percision_var, 0)), (len_var, Int(zero_var, zero_precision_var, 0)),
], ],
ret_var: list_elem_var, ret_var: list_elem_var,
}, },
@ -2868,7 +2854,7 @@ fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh(); let list_var = var_store.fresh();
let len_var = var_store.fresh(); let len_var = var_store.fresh();
let num_var = var_store.fresh(); let num_var = var_store.fresh();
let num_percision_var = var_store.fresh(); let num_precision_var = var_store.fresh();
let list_elem_var = var_store.fresh(); let list_elem_var = var_store.fresh();
let ret_var = var_store.fresh(); let ret_var = var_store.fresh();
@ -2883,7 +2869,7 @@ fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
RunLowLevel { RunLowLevel {
op: LowLevel::NotEq, op: LowLevel::NotEq,
args: vec![ args: vec![
(len_var, Int(num_var, num_percision_var, 0)), (len_var, Int(num_var, num_precision_var, 0)),
( (
len_var, len_var,
RunLowLevel { RunLowLevel {
@ -2922,7 +2908,7 @@ fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
ret_var: len_var, ret_var: len_var,
}, },
), ),
(arg_var, Int(num_var, num_percision_var, 1)), (arg_var, Int(num_var, num_precision_var, 1)),
], ],
ret_var: len_var, ret_var: len_var,
}, },

View file

@ -375,6 +375,36 @@ mod gen_num {
); );
} }
#[test]
fn f64_sqrt_zero() {
assert_evals_to!(
indoc!(
r#"
when Num.sqrt 0 is
Ok val -> val
Err _ -> -1
"#
),
0.0,
f64
);
}
#[test]
fn f64_sqrt_negative() {
assert_evals_to!(
indoc!(
r#"
when Num.sqrt -1 is
Err _ -> 42
Ok val -> val
"#
),
42.0,
f64
);
}
#[test] #[test]
fn f64_round_old() { fn f64_round_old() {
assert_evals_to!("Num.round 3.6", 4, i64); assert_evals_to!("Num.round 3.6", 4, i64);