From 26992c9e32b25b7881acb20c677578da0e52d37a Mon Sep 17 00:00:00 2001 From: Kasper Date: Sat, 28 Dec 2019 06:31:50 +0100 Subject: [PATCH] Evaluation of sin, cos, tan --- src/evaluator.rs | 72 ++++++++++++++++++++++++++++++++++-------------- src/lexer.rs | 11 +------- src/main.rs | 9 ------ 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/evaluator.rs b/src/evaluator.rs index 1735d18..f7c87e6 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -10,8 +10,8 @@ use crate::FunctionIdentifier::*; #[derive(Clone, Debug)] pub struct Answer { - value: d128, - unit: Unit, + pub value: d128, + pub unit: Unit, } impl Answer { @@ -56,6 +56,44 @@ fn cbrt(input: d128) -> d128 { return n } +fn sin(mut input: d128) -> d128 { + let pi = d128!(3.141592653589793238462643383279503); + let pi2 = d128!(6.283185307179586476925286766559006); + + input %= pi2; + + let negative_correction = if input.is_negative() { + input -= pi; + d128!(-1) + } else { + d128!(1) + }; + + let one = d128!(1); + let two = d128!(2); + let neg_one = -one; + + let precision = 37; + let mut result = d128!(0); + for i_int in 0..precision { + let i = d128::from(i_int); + let calc_result = two*i+one; + result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result, one, two)); + } + + return negative_correction * result; + +} + +fn cos(input: d128) -> d128 { + let half_pi = d128!(1.570796326794896619231321691639751); + return sin(half_pi - input); +} + +fn tan(input: d128) -> d128 { + return sin(input) / cos(input); +} + fn evaluate_node(ast_node: &AstNode) -> Result { let token = &ast_node.token; let children = &ast_node.children; @@ -143,25 +181,17 @@ fn evaluate_node(ast_node: &AstNode) -> Result { if rounding_change == d128!(-0.5) { result += d128!(1); } return Ok(Answer::new(result, child_answer.unit)) }, - - // Sin, - // Cos, - // Tan, - // Asin, - // Acos, - // Atan, - // Sinh, - // Cosh, - // Tanh, - // Asinh, - // Acosh, - // Atanh, - // Sin - // Sinh - // Tan - // Tanh - _ => { - return Err(format!("EVAL UNSUPPORTED FUNC").to_string()) + Sin => { + let result = sin(child_answer.value); + return Ok(Answer::new(result, child_answer.unit)) + }, + Cos => { + let result = cos(child_answer.value); + return Ok(Answer::new(result, child_answer.unit)) + }, + Tan => { + let result = tan(child_answer.value); + return Ok(Answer::new(result, child_answer.unit)) }, } } diff --git a/src/lexer.rs b/src/lexer.rs index 8fece60..91aa075 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -5,7 +5,7 @@ use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, R use crate::UnaryOperator::{Percent, Factorial}; use crate::TextOperator::{Of, To}; use crate::Constant::{E, Pi}; -use crate::FunctionIdentifier::{Acos, Acosh, Asin, Asinh, Atan, Atanh, Cbrt, Ceil, Cos, Cosh, Exp, Abs, Floor, Ln, Log, Round, Sin, Sinh, Sqrt, Tan, Tanh}; +use crate::FunctionIdentifier::{Cbrt, Ceil, Cos, Exp, Abs, Floor, Ln, Log, Round, Sin, Sqrt, Tan}; use crate::units::Unit::*; pub fn lex(input: &str) -> Result { @@ -84,15 +84,6 @@ pub fn lex(input: &str) -> Result { "sin" => tokens.push(Token::FunctionIdentifier(Sin)), "cos" => tokens.push(Token::FunctionIdentifier(Cos)), "tan" => tokens.push(Token::FunctionIdentifier(Tan)), - "asin" => tokens.push(Token::FunctionIdentifier(Asin)), - "acos" => tokens.push(Token::FunctionIdentifier(Acos)), - "atan" => tokens.push(Token::FunctionIdentifier(Atan)), - "sinh" => tokens.push(Token::FunctionIdentifier(Sinh)), - "cosh" => tokens.push(Token::FunctionIdentifier(Cosh)), - "tanh" => tokens.push(Token::FunctionIdentifier(Tanh)), - "asinh" => tokens.push(Token::FunctionIdentifier(Asinh)), - "acosh" => tokens.push(Token::FunctionIdentifier(Acosh)), - "atanh" => tokens.push(Token::FunctionIdentifier(Atanh)), "ns" | "nanosecond" | "nanoseconds" => tokens.push(Token::Unit(Nanosecond)), "μs" | "us" | "microsecond" | "microseconds" => tokens.push(Token::Unit(Microsecond)), diff --git a/src/main.rs b/src/main.rs index 4076d76..4c97d5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,15 +50,6 @@ pub enum FunctionIdentifier { Sin, Cos, Tan, - Asin, - Acos, - Atan, - Sinh, - Cosh, - Tanh, - Asinh, - Acosh, - Atanh, } mod units;