Fix trig functions precision (#40)
This commit is contained in:
parent
be51ec4ff0
commit
0fb5241633
@ -46,15 +46,29 @@ pub fn cbrt(input: d128) -> d128 {
|
|||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pi() -> d128 {
|
||||||
|
d128!(3.141592653589793238462643383279503)
|
||||||
|
}
|
||||||
|
fn pi2() -> d128 {
|
||||||
|
d128!(6.283185307179586476925286766559006)
|
||||||
|
}
|
||||||
|
fn pi_half() -> d128 {
|
||||||
|
d128!(1.570796326794896619231321691639751)
|
||||||
|
}
|
||||||
|
fn eulers_number() -> d128 {
|
||||||
|
d128!(2.718281828459045235360287471352662)
|
||||||
|
}
|
||||||
|
fn rounding_base() -> d128 {
|
||||||
|
// DO NOT add a trailing zero here, it must be one less than the others
|
||||||
|
d128!(0.00000000000000000000000000000001)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the sine of a [`struct@d128`]
|
/// Returns the sine of a [`struct@d128`]
|
||||||
pub fn sin(mut input: d128) -> d128 {
|
pub fn sin(mut input: d128) -> d128 {
|
||||||
let pi = d128!(3.141592653589793238462643383279503);
|
input %= pi2();
|
||||||
let pi2 = d128!(6.283185307179586476925286766559006);
|
|
||||||
|
|
||||||
input %= pi2;
|
|
||||||
|
|
||||||
let negative_correction = if input.is_negative() {
|
let negative_correction = if input.is_negative() {
|
||||||
input -= pi;
|
input -= pi();
|
||||||
d128!(-1)
|
d128!(-1)
|
||||||
} else {
|
} else {
|
||||||
d128!(1)
|
d128!(1)
|
||||||
@ -72,13 +86,16 @@ pub fn sin(mut input: d128) -> d128 {
|
|||||||
result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result));
|
result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
negative_correction * result
|
let unrounded_result = negative_correction * result;
|
||||||
|
|
||||||
|
// This uses bankers rounding, but I *think* it's fine
|
||||||
|
let result = unrounded_result.quantize(rounding_base());
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the cosine of a [`struct@d128`]
|
/// Returns the cosine of a [`struct@d128`]
|
||||||
pub fn cos(input: d128) -> d128 {
|
pub fn cos(input: d128) -> d128 {
|
||||||
let half_pi = d128!(1.570796326794896619231321691639751);
|
sin(pi_half() - input)
|
||||||
sin(half_pi - input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the tangent of a [`struct@d128`]
|
/// Returns the tangent of a [`struct@d128`]
|
||||||
@ -94,11 +111,11 @@ fn evaluate_node(ast_node: &AstNode) -> Result<Number, String> {
|
|||||||
Token::Number(number) => Ok(Number::new(*number, Unit::NoUnit)),
|
Token::Number(number) => Ok(Number::new(*number, Unit::NoUnit)),
|
||||||
Token::Constant(constant) => match constant {
|
Token::Constant(constant) => match constant {
|
||||||
Pi => Ok(Number::new(
|
Pi => Ok(Number::new(
|
||||||
d128!(3.141592653589793238462643383279503),
|
pi(),
|
||||||
Unit::NoUnit,
|
Unit::NoUnit,
|
||||||
)),
|
)),
|
||||||
E => Ok(Number::new(
|
E => Ok(Number::new(
|
||||||
d128!(2.718281828459045235360287471352662),
|
eulers_number(),
|
||||||
Unit::NoUnit,
|
Unit::NoUnit,
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user