Add missing operators for f32.

This commit is contained in:
Stephen Chung 2020-08-25 09:27:47 +08:00
parent 7cd345b128
commit 790878f209
2 changed files with 37 additions and 22 deletions

View File

@ -1146,7 +1146,7 @@ pub fn run_builtin_binary_op(
"*" => return Ok(Some((x * y).into())),
"/" => return Ok(Some((x / y).into())),
"%" => return Ok(Some((x % y).into())),
"~" => return pow_i_i_u(x, y).map(Into::into).map(Some),
"~" => return Ok(Some(x.pow(y as u32).into())),
">>" => return shr_u(x, y).map(Into::into).map(Some),
"<<" => return shl_u(x, y).map(Into::into).map(Some),
_ => (),
@ -1223,7 +1223,7 @@ pub fn run_builtin_binary_op(
"*" => return Ok(Some((x * y).into())),
"/" => return Ok(Some((x / y).into())),
"%" => return Ok(Some((x % y).into())),
"~" => return pow_f_f(x, y).map(Into::into).map(Some),
"~" => return Ok(Some(x.powf(y).into())),
"==" => return Ok(Some((x == y).into())),
"!=" => return Ok(Some((x != y).into())),
">" => return Ok(Some((x > y).into())),
@ -1274,7 +1274,7 @@ pub fn run_builtin_op_assignment(
"*=" => return Ok(Some(*x *= y)),
"/=" => return Ok(Some(*x /= y)),
"%=" => return Ok(Some(*x %= y)),
"~=" => return Ok(Some(*x = pow_i_i_u(*x, y)?)),
"~=" => return Ok(Some(*x = (*x).pow(y as u32))),
">>=" => return Ok(Some(*x = shr_u(*x, y)?)),
"<<=" => return Ok(Some(*x = shl_u(*x, y)?)),
_ => (),
@ -1317,7 +1317,7 @@ pub fn run_builtin_op_assignment(
"*=" => return Ok(Some(*x *= y)),
"/=" => return Ok(Some(*x /= y)),
"%=" => return Ok(Some(*x %= y)),
"~=" => return Ok(Some(*x = pow_f_f(*x, y)?)),
"~=" => return Ok(Some(*x = (*x).powf(y))),
_ => (),
}
}

View File

@ -4,9 +4,6 @@ use crate::parser::INT;
use crate::{result::EvalAltResult, token::Position};
#[cfg(not(feature = "no_float"))]
use crate::parser::FLOAT;
use num_traits::{
identities::Zero, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl,
CheckedShr, CheckedSub,
@ -238,18 +235,28 @@ pub fn pow_i_i(x: INT, y: INT) -> FuncReturn<INT> {
}
}
}
// Unchecked integer power - may panic on overflow or if the power index is too high (> u32::MAX)
pub fn pow_i_i_u(x: INT, y: INT) -> FuncReturn<INT> {
Ok(x.pow(y as u32))
}
// Floating-point power - always well-defined
#[cfg(not(feature = "no_float"))]
pub fn pow_f_f(x: FLOAT, y: FLOAT) -> FuncReturn<FLOAT> {
pub fn pow_f_f_32(x: f32, y: f32) -> FuncReturn<f32> {
Ok(x.powf(y))
}
// Checked power
#[cfg(not(feature = "no_float"))]
pub fn pow_f_i(x: FLOAT, y: INT) -> FuncReturn<FLOAT> {
pub fn pow_f_i_32(x: f32, y: INT) -> FuncReturn<f32> {
// Raise to power that is larger than an i32
if y > (i32::MAX as INT) {
return EvalAltResult::ErrorArithmetic(
format!("Number raised to too large an index: {} ~ {}", x, y),
Position::none(),
)
.into();
}
Ok(x.powi(y as i32))
}
// Checked power
#[cfg(not(feature = "no_float"))]
pub fn pow_f_i_64(x: f64, y: INT) -> FuncReturn<f64> {
// Raise to power that is larger than an i32
if y > (i32::MAX as INT) {
return EvalAltResult::ErrorArithmetic(
@ -263,7 +270,12 @@ pub fn pow_f_i(x: FLOAT, y: INT) -> FuncReturn<FLOAT> {
}
// Unchecked power - may be incorrect if the power index is too high (> i32::MAX)
#[cfg(not(feature = "no_float"))]
pub fn pow_f_i_u(x: FLOAT, y: INT) -> FuncReturn<FLOAT> {
pub fn pow_f_i_u_32(x: f32, y: INT) -> FuncReturn<f32> {
Ok(x.powi(y as i32))
}
// Unchecked power - may be incorrect if the power index is too high (> i32::MAX)
#[cfg(not(feature = "no_float"))]
pub fn pow_f_i_u_64(x: f64, y: INT) -> FuncReturn<f64> {
Ok(x.powi(y as i32))
}
@ -352,6 +364,7 @@ def_package!(crate:ArithmeticPackage:"Basic arithmetic", lib, {
reg_op!(lib, "-", sub_u, f32);
reg_op!(lib, "*", mul_u, f32);
reg_op!(lib, "/", div_u, f32);
reg_op!(lib, "%", modulo_u, f32);
reg_sign!(lib, "sign", f32, f32);
reg_sign!(lib, "sign", f64, f64);
}
@ -370,15 +383,17 @@ def_package!(crate:ArithmeticPackage:"Basic arithmetic", lib, {
#[cfg(not(feature = "no_float"))]
{
// Checked power
if cfg!(not(feature = "unchecked")) {
lib.set_fn_2("~", pow_f_i);
} else {
lib.set_fn_2("~", pow_f_i_u);
}
// Power
lib.set_fn_2("~", pow_f_f_32);
// Floating-point modulo and power
reg_op!(lib, "%", modulo_u, f32);
// Checked float raised to integer power
if cfg!(not(feature = "unchecked")) {
lib.set_fn_2("~", pow_f_i_32);
lib.set_fn_2("~", pow_f_i_64);
} else {
lib.set_fn_2("~", pow_f_i_u_32);
lib.set_fn_2("~", pow_f_i_u_64);
}
// Floating-point unary
reg_unary!(lib, "-", neg_u, f32, f64);