mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Merge pull request #1122 from rtfeldman/num-sqrt-bugfix
Fix bug in Num.sqrt
This commit is contained in:
commit
706aaa26d3
2 changed files with 67 additions and 51 deletions
|
@ -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
|
|
||||||
RunLowLevel {
|
|
||||||
op: LowLevel::NotEq,
|
|
||||||
args: vec![
|
args: vec![
|
||||||
(float_var, Var(Symbol::ARG_1)),
|
(float_var, Var(Symbol::ARG_1)),
|
||||||
(float_var, Float(unbound_zero_var, percision_var, 0.0)),
|
(float_var, Float(unbound_zero_var, precision_var, 0.0)),
|
||||||
],
|
],
|
||||||
ret_var: bool_var,
|
ret_var: bool_var,
|
||||||
},
|
}),
|
||||||
),
|
no_region(tag(
|
||||||
// denominator was not zero
|
|
||||||
no_region(
|
|
||||||
// Ok (Float.#divUnchecked numerator denominator)
|
|
||||||
tag(
|
|
||||||
"Ok",
|
"Ok",
|
||||||
vec![
|
vec![RunLowLevel {
|
||||||
// Num.#divUnchecked numerator denominator
|
|
||||||
RunLowLevel {
|
|
||||||
op: LowLevel::NumSqrtUnchecked,
|
op: LowLevel::NumSqrtUnchecked,
|
||||||
args: vec![(float_var, Var(Symbol::ARG_1))],
|
args: vec![(float_var, Var(Symbol::ARG_1))],
|
||||||
ret_var: float_var,
|
ret_var: float_var,
|
||||||
},
|
}],
|
||||||
],
|
|
||||||
var_store,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)],
|
|
||||||
final_else: Box::new(
|
|
||||||
// denominator was zero
|
|
||||||
no_region(tag(
|
|
||||||
"Err",
|
|
||||||
vec![tag("DivByZero", Vec::new(), var_store)],
|
|
||||||
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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue