936 lines
25 KiB
Rust
936 lines
25 KiB
Rust
//! # Numeric Instructions
|
|
//!
|
|
//! This file contains numeric instructions for int and float.
|
|
|
|
// There has to be a better way to declare these functions.
|
|
// Just don't know enough Rust yet ig.
|
|
|
|
use crate::push::state::PushState;
|
|
use rust_decimal::Decimal;
|
|
use std::cmp::{max, min};
|
|
use std::ops::{Add, Div, Mul, Sub};
|
|
|
|
use super::utils::{CastingTrait, NumericTrait};
|
|
|
|
/// Adds two addable values together.
|
|
fn _add<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Add<Output = T> + Copy,
|
|
{
|
|
Some(vals[1] + vals[0])
|
|
}
|
|
make_instruction!(int, int, _add, i128, 2);
|
|
make_instruction!(float, float, _add, Decimal, 2);
|
|
|
|
/// Subtracts two subtractable values from each other.
|
|
fn _sub<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Sub<Output = T> + Copy,
|
|
{
|
|
Some(vals[1] - vals[0])
|
|
}
|
|
make_instruction!(int, int, _sub, i128, 2);
|
|
make_instruction!(float, float, _sub, Decimal, 2);
|
|
|
|
/// Multiplies two multipliable values together.
|
|
fn _mult<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Mul<Output = T> + Copy,
|
|
{
|
|
Some(vals[1] * vals[0])
|
|
}
|
|
make_instruction!(int, int, _mult, i128, 2);
|
|
make_instruction!(float, float, _mult, Decimal, 2);
|
|
|
|
/// Divides two values from each other.
|
|
fn _div<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Div<Output = T> + Copy + NumericTrait,
|
|
{
|
|
vals[1].checked_div(vals[0])
|
|
}
|
|
make_instruction!(int, int, _div, i128, 2);
|
|
make_instruction!(float, float, _div, Decimal, 2);
|
|
|
|
/// Takes the remainder of two values
|
|
fn _rem<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Div<Output = T> + Copy + NumericTrait,
|
|
{
|
|
vals[1].checked_mod(vals[0])
|
|
}
|
|
make_instruction!(int, int, _rem, i128, 2);
|
|
make_instruction!(float, float, _rem, Decimal, 2);
|
|
|
|
/// Takes the max of two values
|
|
fn _max<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(max(vals[1], vals[0]))
|
|
}
|
|
make_instruction!(int, int, _max, i128, 2);
|
|
make_instruction!(float, float, _max, Decimal, 2);
|
|
|
|
/// Takes the min of two values
|
|
fn _min<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(min(vals[1], vals[0]))
|
|
}
|
|
make_instruction!(int, int, _min, i128, 2);
|
|
make_instruction!(float, float, _min, Decimal, 2);
|
|
|
|
/// Increments a single value by 1
|
|
fn _inc<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: NumericTrait + Copy,
|
|
{
|
|
Some(vals[0].increment())
|
|
}
|
|
make_instruction!(int, int, _inc, i128, 1);
|
|
make_instruction!(float, float, _inc, Decimal, 1);
|
|
|
|
/// Decrements a single value by 1
|
|
fn _dec<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: NumericTrait + Copy,
|
|
{
|
|
Some(vals[0].decrement())
|
|
}
|
|
make_instruction!(int, int, _dec, i128, 1);
|
|
make_instruction!(float, float, _dec, Decimal, 1);
|
|
|
|
/// Checks if the 2nd to top value is less than the top value
|
|
fn _lt<T>(vals: Vec<T>) -> Option<bool>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(vals[1] < vals[0])
|
|
}
|
|
make_instruction!(int, boolean, _lt, i128, 2);
|
|
make_instruction!(float, boolean, _lt, Decimal, 2);
|
|
|
|
/// Checks if the 2nd to top value is greater than the top value
|
|
fn _gt<T>(vals: Vec<T>) -> Option<bool>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(vals[1] > vals[0])
|
|
}
|
|
make_instruction!(int, boolean, _gt, i128, 2);
|
|
make_instruction!(float, boolean, _gt, Decimal, 2);
|
|
|
|
/// Checks if the 2nd to top value is less than or equal to the top value
|
|
fn _lte<T>(vals: Vec<T>) -> Option<bool>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(vals[1] <= vals[0])
|
|
}
|
|
make_instruction!(int, boolean, _lte, i128, 2);
|
|
make_instruction!(float, boolean, _lte, Decimal, 2);
|
|
|
|
/// Checks if the 2nd to top value is greater than or equal to the top value
|
|
fn _gte<T>(vals: Vec<T>) -> Option<bool>
|
|
where
|
|
T: Ord + Copy,
|
|
{
|
|
Some(vals[1] >= vals[0])
|
|
}
|
|
make_instruction!(int, boolean, _gte, i128, 2);
|
|
make_instruction!(float, boolean, _gte, Decimal, 2);
|
|
|
|
/// Runs sin on a single item.
|
|
fn _sin<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_sin()
|
|
}
|
|
make_instruction!(int, int, _sin, i128, 1);
|
|
make_instruction!(float, float, _sin, Decimal, 1);
|
|
|
|
/// Runs arcsin on a single item.
|
|
fn _arcsin<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_sin()?.inverse()
|
|
}
|
|
make_instruction!(int, int, _arcsin, i128, 1);
|
|
make_instruction!(float, float, _arcsin, Decimal, 1);
|
|
|
|
/// Runs cos on a single item.
|
|
fn _cos<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_cos()
|
|
}
|
|
make_instruction!(int, int, _cos, i128, 1);
|
|
make_instruction!(float, float, _cos, Decimal, 1);
|
|
|
|
/// Runs arcsin on a single item.
|
|
fn _arccos<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_cos()?.inverse()
|
|
}
|
|
make_instruction!(int, int, _arccos, i128, 1);
|
|
make_instruction!(float, float, _arccos, Decimal, 1);
|
|
|
|
/// Runs tan on a single item.
|
|
fn _tan<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_tan()
|
|
}
|
|
make_instruction!(int, int, _tan, i128, 1);
|
|
make_instruction!(float, float, _tan, Decimal, 1);
|
|
|
|
/// Runs arctan on a single item.
|
|
fn _arctan<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_tan()?.inverse()
|
|
}
|
|
make_instruction!(int, int, _arctan, i128, 1);
|
|
make_instruction!(float, float, _arctan, Decimal, 1);
|
|
|
|
/// Converts a single value from a float to an arbitrary type.
|
|
fn _from_int<T>(vals: Vec<i128>) -> Option<T>
|
|
where
|
|
T: Copy + CastingTrait,
|
|
{
|
|
T::from_int(vals[0])
|
|
}
|
|
make_instruction_out!(int, float, _from_int, i128, 1);
|
|
|
|
/// Converts a single value from a float to an arbitrary type.
|
|
fn _from_float<T>(vals: Vec<Decimal>) -> Option<T>
|
|
where
|
|
T: Copy + CastingTrait,
|
|
{
|
|
T::from_float(vals[0])
|
|
}
|
|
make_instruction_out!(float, int, _from_float, Decimal, 1);
|
|
|
|
/// Converts a bool to a to a new type.
|
|
fn _from_boolean<T>(vals: Vec<bool>) -> Option<T>
|
|
where
|
|
T: Copy + CastingTrait,
|
|
{
|
|
T::from_bool(vals[0])
|
|
}
|
|
make_instruction_out!(boolean, int, _from_boolean, bool, 1);
|
|
make_instruction_out!(boolean, float, _from_boolean, bool, 1);
|
|
|
|
/// Takes the log base 10 of a single Decimal. Acts as a
|
|
/// NoOp if the value is 0. If the value is negative, takes
|
|
/// the absolute value of the number.
|
|
fn _log<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].absolute().safe_log10()
|
|
}
|
|
make_instruction!(int, int, _log, i128, 1);
|
|
make_instruction!(float, float, _log, Decimal, 1);
|
|
|
|
/// Takes the exp of a single value. Ints get truncated.
|
|
fn _exp<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_exp()
|
|
}
|
|
make_instruction!(int, int, _exp, i128, 1);
|
|
make_instruction!(float, float, _exp, Decimal, 1);
|
|
|
|
/// Takes the square root of the absolute value of a single value.
|
|
fn _sqrt<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].safe_sqrt()
|
|
}
|
|
make_instruction!(int, int, _sqrt, i128, 1);
|
|
make_instruction!(float, float, _sqrt, Decimal, 1);
|
|
|
|
/// Takes the inverse of a single value. If the number is 0,
|
|
/// does nothing (returns None). Truncates an int to 0.
|
|
fn _inv<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
vals[0].inverse()
|
|
}
|
|
make_instruction!(int, int, _inv, i128, 1);
|
|
make_instruction!(float, float, _inv, Decimal, 1);
|
|
|
|
/// Takes the absolute value of the top number
|
|
fn _abs<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
Some(vals[0].absolute())
|
|
}
|
|
make_instruction!(int, int, _abs, i128, 1);
|
|
make_instruction!(float, float, _abs, Decimal, 1);
|
|
|
|
/// Reverses the sign of the top number
|
|
fn _sign_reverse<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
Some(vals[0].sign_reverse())
|
|
}
|
|
make_instruction!(int, int, _sign_reverse, i128, 1);
|
|
make_instruction!(float, float, _sign_reverse, Decimal, 1);
|
|
|
|
/// Squares the top number
|
|
fn _square<T>(vals: Vec<T>) -> Option<T>
|
|
where
|
|
T: Copy + NumericTrait,
|
|
{
|
|
Some(vals[0].square())
|
|
}
|
|
make_instruction!(int, int, _square, i128, 1);
|
|
make_instruction!(float, float, _square, Decimal, 1);
|
|
|
|
/// A list of all of the defined int functions in this file.
|
|
/// Must manually register functions in this list if added.
|
|
pub fn int_instructions() -> Vec<fn(&mut PushState)> {
|
|
vec![
|
|
int_add,
|
|
int_sub,
|
|
int_mult,
|
|
int_div,
|
|
int_rem,
|
|
int_max,
|
|
int_min,
|
|
int_inc,
|
|
int_dec,
|
|
int_lt,
|
|
int_gt,
|
|
int_lte,
|
|
int_gte,
|
|
int_sin,
|
|
int_arcsin,
|
|
int_cos,
|
|
int_arccos,
|
|
int_tan,
|
|
int_arctan,
|
|
int_from_float,
|
|
int_from_boolean,
|
|
int_log,
|
|
int_exp,
|
|
int_sqrt,
|
|
int_inv,
|
|
int_abs,
|
|
int_sign_reverse,
|
|
int_square,
|
|
]
|
|
}
|
|
|
|
/// All of the float instructions declared in this file.
|
|
pub fn float_instructions() -> Vec<fn(&mut PushState)> {
|
|
vec![
|
|
float_add,
|
|
float_sub,
|
|
float_mult,
|
|
float_div,
|
|
float_rem,
|
|
float_max,
|
|
float_min,
|
|
float_inc,
|
|
float_dec,
|
|
float_lt,
|
|
float_gt,
|
|
float_lte,
|
|
float_gte,
|
|
float_sin,
|
|
float_arcsin,
|
|
float_cos,
|
|
float_arccos,
|
|
float_tan,
|
|
float_arctan,
|
|
float_from_int,
|
|
float_from_boolean,
|
|
float_log,
|
|
float_exp,
|
|
float_sqrt,
|
|
float_inv,
|
|
float_abs,
|
|
float_sign_reverse,
|
|
float_square,
|
|
]
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::push::state::EMPTY_STATE;
|
|
use rust_decimal::dec;
|
|
|
|
/// Tests the _add function.
|
|
#[test]
|
|
fn add_test() {
|
|
let vals: Vec<i64> = vec![1, 2];
|
|
assert_eq!(Some(3), _add(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
|
|
assert_eq!(Some(dec!(3.3)), _add(vals));
|
|
}
|
|
|
|
/// Tests the _sub function.
|
|
#[test]
|
|
fn sub_test() {
|
|
let vals: Vec<i64> = vec![1, 2];
|
|
assert_eq!(Some(1), _sub(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
|
|
assert_eq!(Some(dec!(1.1)), _sub(vals));
|
|
}
|
|
|
|
/// Tests the _mult function.
|
|
#[test]
|
|
fn mult_test() {
|
|
let vals: Vec<i128> = vec![4, 5];
|
|
assert_eq!(Some(20), _mult(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
|
|
assert_eq!(Some(dec!(2.42)), _mult(vals));
|
|
}
|
|
|
|
/// Tests the _div function
|
|
#[test]
|
|
fn div_test() {
|
|
let vals: Vec<i128> = vec![4, 20];
|
|
assert_eq!(Some(5), _div(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 20];
|
|
assert_eq!(Some(6), _div(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(1.6), dec!(2.2)];
|
|
assert_eq!(Some(dec!(1.375)), _div(vals));
|
|
|
|
let vals: Vec<i128> = vec![0, 1];
|
|
assert_eq!(None, _div(vals));
|
|
}
|
|
|
|
/// Tests the _rem function
|
|
#[test]
|
|
fn rem_test() {
|
|
let vals: Vec<i128> = vec![3, 20];
|
|
assert_eq!(Some(2), _rem(vals));
|
|
|
|
let vals: Vec<i128> = vec![20, 20];
|
|
assert_eq!(Some(0), _rem(vals));
|
|
|
|
let vals: Vec<i128> = vec![0, 9];
|
|
assert_eq!(None, _rem(vals));
|
|
}
|
|
|
|
/// Tests the _max function
|
|
#[test]
|
|
fn max_test() {
|
|
let vals: Vec<i128> = vec![1, 2];
|
|
assert_eq!(Some(2), _max(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 0];
|
|
assert_eq!(Some(3), _max(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(2.2), dec!(1.1)];
|
|
assert_eq!(Some(dec!(2.2)), _max(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(3.3), dec!(-1.1)];
|
|
assert_eq!(Some(dec!(3.3)), _max(vals));
|
|
}
|
|
|
|
/// Tests the _min function
|
|
#[test]
|
|
fn min_test() {
|
|
let vals: Vec<i128> = vec![1, 2];
|
|
assert_eq!(Some(1), _min(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 0];
|
|
assert_eq!(Some(0), _min(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(2.2), dec!(1.1)];
|
|
assert_eq!(Some(dec!(1.1)), _min(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(3.3), dec!(-1.1)];
|
|
assert_eq!(Some(dec!(-1.1)), _min(vals));
|
|
}
|
|
|
|
/// Tests the _inc and _dec functions
|
|
#[test]
|
|
fn inc_dec_test() {
|
|
let vals: Vec<i128> = vec![2];
|
|
assert_eq!(Some(3), _inc(vals));
|
|
|
|
let vals: Vec<i128> = vec![10];
|
|
assert_eq!(Some(9), _dec(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(2.2)];
|
|
assert_eq!(Some(dec!(3.2)), _inc(vals));
|
|
|
|
let vals: Vec<Decimal> = vec![dec!(5.6)];
|
|
assert_eq!(Some(dec!(4.6)), _dec(vals));
|
|
}
|
|
|
|
/// Tests the _lt, _gt, _lte, and _gte functions
|
|
#[test]
|
|
fn lt_gt_lte_gte_test() {
|
|
let vals: Vec<i128> = vec![3, 2];
|
|
assert_eq!(Some(true), _lt(vals));
|
|
|
|
let vals: Vec<i128> = vec![1, 4];
|
|
assert_eq!(Some(false), _lt(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 3];
|
|
assert_eq!(Some(false), _lt(vals));
|
|
|
|
let vals: Vec<i128> = vec![2, 3];
|
|
assert_eq!(Some(true), _gt(vals));
|
|
|
|
let vals: Vec<i128> = vec![4, 1];
|
|
assert_eq!(Some(false), _gt(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 3];
|
|
assert_eq!(Some(false), _gt(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 2];
|
|
assert_eq!(Some(true), _lte(vals));
|
|
|
|
let vals: Vec<i128> = vec![1, 4];
|
|
assert_eq!(Some(false), _lte(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 3];
|
|
assert_eq!(Some(true), _lte(vals));
|
|
|
|
let vals: Vec<i128> = vec![2, 3];
|
|
assert_eq!(Some(true), _gte(vals));
|
|
|
|
let vals: Vec<i128> = vec![4, 1];
|
|
assert_eq!(Some(false), _gte(vals));
|
|
|
|
let vals: Vec<i128> = vec![3, 3];
|
|
assert_eq!(Some(true), _gte(vals));
|
|
}
|
|
|
|
/// Tests the various trig functions.
|
|
#[test]
|
|
fn trig_tests() {
|
|
let vals = vec![Decimal::PI];
|
|
assert_eq!(Some(dec!(0.0)), _sin(vals));
|
|
|
|
let vals = vec![Decimal::QUARTER_PI];
|
|
assert_eq!(Some(dec!(1.4142135623869512272301701717)), _arcsin(vals));
|
|
|
|
let vals = vec![Decimal::PI];
|
|
assert_eq!(Some(dec!(-1.0)), _cos(vals));
|
|
|
|
let vals = vec![Decimal::QUARTER_PI];
|
|
assert_eq!(Some(dec!(1.4142135626023406165042434783)), _arccos(vals));
|
|
|
|
let vals = vec![Decimal::PI];
|
|
assert_eq!(Some(dec!(0.0)), _tan(vals));
|
|
|
|
let vals = vec![Decimal::QUARTER_PI];
|
|
assert_eq!(Some(dec!(1.0000000043184676055890307049)), _arctan(vals));
|
|
}
|
|
|
|
/// Tests that the various addition functions.
|
|
#[test]
|
|
fn state_add() {
|
|
let mut test_state = EMPTY_STATE;
|
|
test_state.int = vec![1, 2];
|
|
test_state.float = vec![dec!(1.1), dec!(2.2)];
|
|
|
|
int_add(&mut test_state);
|
|
assert_eq!(vec![3], test_state.int);
|
|
|
|
float_add(&mut test_state);
|
|
assert_eq!(vec![dec!(3.3)], test_state.float);
|
|
}
|
|
|
|
/// Tests the various subtraction functions.
|
|
#[test]
|
|
fn state_sub() {
|
|
let mut test_state = EMPTY_STATE;
|
|
test_state.int = vec![1, 2];
|
|
test_state.float = vec![dec!(1.1), dec!(2.2)];
|
|
|
|
int_sub(&mut test_state);
|
|
assert_eq!(vec![-1], test_state.int);
|
|
|
|
float_sub(&mut test_state);
|
|
assert_eq!(vec![dec!(-1.1)], test_state.float);
|
|
}
|
|
|
|
/// Tests the various multiplication functions.
|
|
#[test]
|
|
fn state_mult() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0];
|
|
int_mult(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
|
|
test_state.int = vec![10, 3, 2];
|
|
test_state.float = vec![dec!(1.1), dec!(2.2)];
|
|
|
|
int_mult(&mut test_state);
|
|
assert_eq!(vec![10, 6], test_state.int);
|
|
|
|
float_mult(&mut test_state);
|
|
assert_eq!(vec![dec!(2.42)], test_state.float);
|
|
}
|
|
|
|
/// Tests the division functions in the state
|
|
#[test]
|
|
fn state_div() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0];
|
|
int_div(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
|
|
test_state.int = vec![2, 0];
|
|
int_div(&mut test_state);
|
|
assert_eq!(vec![2, 0], test_state.int);
|
|
|
|
test_state.int = vec![6, 3];
|
|
|
|
int_div(&mut test_state);
|
|
assert_eq!(vec![2], test_state.int);
|
|
|
|
test_state.float = vec![dec!(2.2), dec!(1.6)];
|
|
float_div(&mut test_state);
|
|
assert_eq!(vec![dec!(1.375)], test_state.float);
|
|
}
|
|
|
|
/// Tests the remainder functions in the state.
|
|
#[test]
|
|
fn state_rem() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0];
|
|
int_rem(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
|
|
test_state.int = vec![2, 0];
|
|
int_rem(&mut test_state);
|
|
assert_eq!(vec![2, 0], test_state.int);
|
|
|
|
test_state.int = vec![60, 80, 20, 3];
|
|
int_rem(&mut test_state);
|
|
assert_eq!(vec![60, 80, 2], test_state.int);
|
|
|
|
test_state.float = vec![dec!(2.7), dec!(1.2)];
|
|
float_rem(&mut test_state);
|
|
assert_eq!(vec![dec!(0.3)], test_state.float);
|
|
}
|
|
|
|
/// Tests the min and max functions in the state
|
|
#[test]
|
|
fn state_min_max() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0];
|
|
int_max(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
|
|
test_state.int = vec![0];
|
|
int_min(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
|
|
test_state.int = vec![1, 2, 3];
|
|
int_max(&mut test_state);
|
|
assert_eq!(vec![1, 3], test_state.int);
|
|
|
|
test_state.int = vec![1, 2, 3];
|
|
int_min(&mut test_state);
|
|
assert_eq!(vec![1, 2], test_state.int);
|
|
|
|
test_state.float = vec![dec!(1.2), dec!(4.6)];
|
|
float_max(&mut test_state);
|
|
assert_eq!(vec![dec!(4.6)], test_state.float);
|
|
|
|
test_state.float = vec![dec!(0.0), dec!(1.2), dec!(4.6)];
|
|
float_min(&mut test_state);
|
|
assert_eq!(vec![dec!(0.0), dec!(1.2)], test_state.float);
|
|
}
|
|
|
|
/// Tests the inc and dec functions in the state
|
|
#[test]
|
|
fn state_inc_dec() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![];
|
|
int_inc(&mut test_state);
|
|
let empty_vec: Vec<i128> = vec![];
|
|
assert_eq!(empty_vec, test_state.int);
|
|
|
|
drop(empty_vec);
|
|
|
|
test_state.int = vec![-2, 1];
|
|
int_inc(&mut test_state);
|
|
assert_eq!(vec![-2, 2], test_state.int);
|
|
|
|
test_state.int = vec![-2, 1];
|
|
int_dec(&mut test_state);
|
|
assert_eq!(vec![-2, 0], test_state.int);
|
|
|
|
test_state.float = vec![dec!(1.1)];
|
|
float_inc(&mut test_state);
|
|
assert_eq!(vec![dec!(2.1)], test_state.float);
|
|
|
|
test_state.float = vec![dec!(1.1)];
|
|
float_dec(&mut test_state);
|
|
assert_eq!(vec![dec!(0.1)], test_state.float);
|
|
}
|
|
|
|
/// Tests the lt, gt, lte, gte functions in the state
|
|
#[test]
|
|
fn state_lt_gt_lte_gte() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![2, 3];
|
|
int_lt(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
|
|
test_state.int = vec![4, 1];
|
|
test_state.boolean = vec![];
|
|
int_lt(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 3];
|
|
test_state.boolean = vec![];
|
|
int_lt(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 2];
|
|
test_state.boolean = vec![];
|
|
int_gt(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
|
|
test_state.int = vec![1, 4];
|
|
test_state.boolean = vec![];
|
|
int_gt(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 3];
|
|
test_state.boolean = vec![];
|
|
int_gt(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![2, 3];
|
|
test_state.boolean = vec![];
|
|
int_lte(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
|
|
test_state.int = vec![4, 1];
|
|
test_state.boolean = vec![];
|
|
int_lte(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 3];
|
|
test_state.boolean = vec![];
|
|
int_lte(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 2];
|
|
test_state.boolean = vec![];
|
|
int_gte(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
|
|
test_state.int = vec![1, 4];
|
|
test_state.boolean = vec![];
|
|
int_gte(&mut test_state);
|
|
assert_eq!(vec![false], test_state.boolean);
|
|
|
|
test_state.int = vec![3, 3];
|
|
test_state.boolean = vec![];
|
|
int_gte(&mut test_state);
|
|
assert_eq!(vec![true], test_state.boolean);
|
|
}
|
|
|
|
/// Tests the various trig functions when they should revert.
|
|
#[test]
|
|
fn state_trig() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.float = vec![Decimal::HALF_PI];
|
|
float_tan(&mut test_state);
|
|
assert_eq!(vec![Decimal::HALF_PI], test_state.float);
|
|
|
|
test_state.float = vec![Decimal::HALF_PI];
|
|
float_arccos(&mut test_state);
|
|
assert_eq!(vec![Decimal::HALF_PI], test_state.float);
|
|
|
|
test_state.float = vec![dec!(3.4), Decimal::PI];
|
|
float_arcsin(&mut test_state);
|
|
assert_eq!(vec![dec!(3.4), Decimal::PI], test_state.float);
|
|
}
|
|
|
|
/// Tests the int and float casting functions
|
|
#[test]
|
|
fn state_cast() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0, 1];
|
|
float_from_int(&mut test_state);
|
|
assert_eq!(vec![dec!(1.0)], test_state.float);
|
|
test_state.int.clear();
|
|
|
|
test_state.float = vec![dec!(2.1)];
|
|
int_from_float(&mut test_state);
|
|
assert_eq!(vec![2], test_state.int);
|
|
}
|
|
|
|
/// Tests the log function
|
|
#[test]
|
|
fn state_log() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![1];
|
|
int_log(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
test_state.int.clear();
|
|
|
|
test_state.float = vec![dec!(2)];
|
|
float_log(&mut test_state);
|
|
assert_eq!(vec![dec!(0.3010299956639811952137388949)], test_state.float);
|
|
test_state.float.clear();
|
|
|
|
test_state.int = vec![6, 7, 0];
|
|
int_log(&mut test_state);
|
|
assert_eq!(vec![6, 7, 0], test_state.int);
|
|
|
|
test_state.float = vec![dec!(-4.5)];
|
|
float_log(&mut test_state);
|
|
assert_eq!(vec![dec!(0.6532125137753436793763169119)], test_state.float);
|
|
}
|
|
|
|
/// Tests the exp function
|
|
#[test]
|
|
fn state_exp() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![0];
|
|
int_exp(&mut test_state);
|
|
assert_eq!(vec![1], test_state.int);
|
|
|
|
test_state.int = vec![0, 2];
|
|
int_exp(&mut test_state);
|
|
assert_eq!(vec![0, 7], test_state.int);
|
|
|
|
test_state.int.clear();
|
|
test_state.float = vec![dec!(1.2)];
|
|
float_exp(&mut test_state);
|
|
assert_eq!(vec![dec!(3.3201169022444051948051948052)], test_state.float);
|
|
}
|
|
|
|
/// Tests the sqrt function
|
|
#[test]
|
|
fn state_sqrt() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![4];
|
|
int_sqrt(&mut test_state);
|
|
assert_eq!(vec![2], test_state.int);
|
|
|
|
test_state.int = vec![5];
|
|
int_sqrt(&mut test_state);
|
|
assert_eq!(vec![2], test_state.int);
|
|
|
|
test_state.float = vec![dec!(4.84)];
|
|
float_sqrt(&mut test_state);
|
|
assert_eq!(vec![dec!(2.2)], test_state.float);
|
|
|
|
test_state.int = vec![-1];
|
|
int_sqrt(&mut test_state);
|
|
assert_eq!(vec![1], test_state.int);
|
|
|
|
test_state.float = vec![dec!(-1.0)];
|
|
float_sqrt(&mut test_state);
|
|
assert_eq!(vec![dec!(1.0)], test_state.float);
|
|
}
|
|
|
|
/// Tests the inv function
|
|
#[test]
|
|
fn state_inv() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![-1, 10];
|
|
int_inv(&mut test_state);
|
|
assert_eq!(vec![-1, 0], test_state.int);
|
|
|
|
test_state.float = vec![dec!(-10)];
|
|
float_inv(&mut test_state);
|
|
assert_eq!(vec![dec!(-0.1)], test_state.float);
|
|
|
|
test_state.int = vec![0];
|
|
int_inv(&mut test_state);
|
|
assert_eq!(vec![0], test_state.int);
|
|
}
|
|
|
|
/// Tests the abs function
|
|
#[test]
|
|
fn state_abs() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![-1];
|
|
int_abs(&mut test_state);
|
|
assert_eq!(vec![1], test_state.int);
|
|
|
|
test_state.float = vec![dec!(-2.7)];
|
|
float_abs(&mut test_state);
|
|
assert_eq!(vec![dec!(2.7)], test_state.float);
|
|
}
|
|
|
|
/// Tests the sign reverse function
|
|
#[test]
|
|
fn state_sign_reverse() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![-2];
|
|
int_sign_reverse(&mut test_state);
|
|
assert_eq!(vec![2], test_state.int);
|
|
|
|
test_state.int = vec![3];
|
|
int_sign_reverse(&mut test_state);
|
|
assert_eq!(vec![-3], test_state.int);
|
|
|
|
test_state.float = vec![dec!(3.0), dec!(-2.0)];
|
|
float_sign_reverse(&mut test_state);
|
|
assert_eq!(vec![dec!(3.0), dec!(2.0)], test_state.float);
|
|
|
|
test_state.float = vec![dec!(3.0)];
|
|
float_sign_reverse(&mut test_state);
|
|
assert_eq!(vec![dec!(-3.0)], test_state.float);
|
|
}
|
|
|
|
/// Tests the square function
|
|
#[test]
|
|
fn state_square() {
|
|
let mut test_state = EMPTY_STATE;
|
|
|
|
test_state.int = vec![2, 3];
|
|
int_square(&mut test_state);
|
|
assert_eq!(vec![2, 9], test_state.int);
|
|
|
|
test_state.float = vec![dec!(-4.0)];
|
|
float_square(&mut test_state);
|
|
assert_eq!(vec![dec!(16.0)], test_state.float);
|
|
}
|
|
}
|