Sped up sin/cos/tan by calculating factorials using match statement

This commit is contained in:
Kasper 2019-12-28 06:34:53 +01:00
parent 26992c9e32
commit 1e00714cf0
3 changed files with 1017 additions and 13 deletions

View File

@ -7,6 +7,7 @@ use crate::Constant::{Pi, E};
use crate::UnaryOperator::{Percent, Factorial}; use crate::UnaryOperator::{Percent, Factorial};
use crate::TextOperator::{To, Of}; use crate::TextOperator::{To, Of};
use crate::FunctionIdentifier::*; use crate::FunctionIdentifier::*;
use crate::lookup::lookup_factorial;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Answer { pub struct Answer {
@ -28,12 +29,8 @@ pub fn evaluate(ast: &AstNode) -> Result<Answer, String> {
Ok(answer) Ok(answer)
} }
fn factorial(n: d128, one: d128, two: d128) -> d128 { fn factorial(input: d128) -> d128 {
if n < two { return lookup_factorial(input.into());
one
} else {
n * factorial(n - one, one, two)
}
} }
fn sqrt(input: d128) -> d128 { fn sqrt(input: d128) -> d128 {
@ -78,7 +75,7 @@ fn sin(mut input: d128) -> d128 {
for i_int in 0..precision { for i_int in 0..precision {
let i = d128::from(i_int); let i = d128::from(i_int);
let calc_result = two*i+one; let calc_result = two*i+one;
result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result, one, two)); result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result));
} }
return negative_correction * result; return negative_correction * result;
@ -217,13 +214,11 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Answer, String> {
Ok(Answer::new(child_answer.value / d128!(100), child_answer.unit)) Ok(Answer::new(child_answer.value / d128!(100), child_answer.unit))
}, },
Factorial => { Factorial => {
if child_answer.value.is_negative() || child_answer.value.is_signed() { let result = factorial(child_answer.value);
Err("Cannot perform factorial of floats or negative".to_string()) if result.is_nan() {
} else if child_answer.value > d128!(1000) { return Err("Can only perform factorial on integers from 0 to 1000".to_string());
Err("Cannot perform factorial of numbers above 1000".to_string())
} else {
Ok(Answer::new(factorial(child_answer.value, d128!(1), d128!(2)), child_answer.unit))
} }
Ok(Answer::new(result, child_answer.unit))
}, },
} }
}, },

1008
src/lookup.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -72,6 +72,7 @@ pub type TokenVector = Vec<Token>;
mod lexer; mod lexer;
mod parser; mod parser;
mod evaluator; mod evaluator;
mod lookup;
fn main() { fn main() {
let lex_start = Instant::now(); let lex_start = Instant::now();