feat(*): Approximations + fix print
This commit is contained in:
parent
0628e54d6e
commit
36362458c8
|
@ -10,16 +10,16 @@ pub mod maths;
|
|||
|
||||
pub fn format(v: &Vec<GaussianRational>) -> String {
|
||||
let mut format;
|
||||
format = v[0].format();
|
||||
format = v[0].format(false);
|
||||
if v.len() > 1 {
|
||||
if format == "" {
|
||||
format = format!("{}x", v[1].format());
|
||||
format = format!("{}x", v[1].format(true));
|
||||
} else {
|
||||
format = format!("{format} + {}x", v[1].format());
|
||||
format = format!("{format} + {}x", v[1].format(true));
|
||||
}
|
||||
}
|
||||
for i in 2..v.len() {
|
||||
let tmp = v[i].format();
|
||||
let tmp = v[i].format(true);
|
||||
if tmp != "" {
|
||||
if format == ""{
|
||||
format = format!("{tmp}x^{i}");
|
||||
|
|
|
@ -20,6 +20,7 @@ fn main() {
|
|||
println!("{} = 0", computorv1::format(&evaluated));
|
||||
computorv1::maths::solver::solve(evaluated);
|
||||
} else {
|
||||
println!("{} is equal to:", args[1]);
|
||||
println!("{}", computorv1::format(&evaluated));
|
||||
}
|
||||
}
|
||||
|
|
52
src/maths.rs
52
src/maths.rs
|
@ -16,6 +16,34 @@ fn one() -> GaussianRational {
|
|||
GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1))
|
||||
}
|
||||
|
||||
fn approx_sqrt_f64(n: f64) -> f64 {
|
||||
let n = n as f64;
|
||||
let mut result = n + 1.;
|
||||
let mut factor = 1.;
|
||||
while factor > f64::EPSILON {
|
||||
while result * result > n {
|
||||
result /= 1. + factor;
|
||||
}
|
||||
result *= 1. + factor;
|
||||
factor /= 2.;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn approx_sqrt(n: i128) -> f64 {
|
||||
let n = n as f64;
|
||||
let mut result = n;
|
||||
let mut factor = 1.;
|
||||
while factor > f64::EPSILON {
|
||||
while result * result > n {
|
||||
result /= 1. + factor;
|
||||
}
|
||||
result *= 1. + factor;
|
||||
factor /= 2.;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn get_prime_factors(mut n: i128) -> Vec<i128> {
|
||||
if n == 0 {
|
||||
return [0].to_vec();
|
||||
|
@ -106,6 +134,9 @@ impl Rational {
|
|||
copy.denominator *= 5;
|
||||
five_count += 1;
|
||||
}
|
||||
if copy.numerator < 0 {
|
||||
copy.numerator *= -1;
|
||||
}
|
||||
format!("{}.{}", copy.numerator / copy.denominator, copy.numerator % copy.denominator)
|
||||
}
|
||||
|
||||
|
@ -249,12 +280,13 @@ impl GaussianRational {
|
|||
GaussianRational::new(self.real, -1 * self.imaginary)
|
||||
}
|
||||
|
||||
pub fn format(&self) -> String {
|
||||
match (self.real().is_zero(), self.imaginary.is_zero()) {
|
||||
(true, true) => format!(""),
|
||||
(true, false) => format!("{}i", self.imaginary.format()),
|
||||
(false, true) => format!("{}", self.real.format()),
|
||||
(false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format())
|
||||
pub fn format(&self, parenthesis: bool) -> String {
|
||||
match (self.real().is_zero(), self.imaginary.is_zero(), parenthesis) {
|
||||
(true, true, _) => format!(""),
|
||||
(true, false, _) => format!("{}i", self.imaginary.format()),
|
||||
(false, true, _) => format!("{}", self.real.format()),
|
||||
(false, false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format()),
|
||||
(false, false, true) => format!("({} + {}i)", self.real.format(), self.imaginary.format())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,10 +521,10 @@ mod tests {
|
|||
let b = GaussianRational::new(zero, rational);
|
||||
let c = GaussianRational::new(whole, zero);
|
||||
let d = GaussianRational::new(whole, rational);
|
||||
assert_eq!(a.format(), String::from(""));
|
||||
assert_eq!(b.format(), String::from("5/3i"));
|
||||
assert_eq!(c.format(), String::from("5"));
|
||||
assert_eq!(d.format(), String::from("5 + 5/3i"));
|
||||
assert_eq!(a.format(false), String::from(""));
|
||||
assert_eq!(b.format(false), String::from("5/3i"));
|
||||
assert_eq!(c.format(false), String::from("5"));
|
||||
assert_eq!(d.format(false), String::from("5 + 5/3i"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -13,7 +13,7 @@ fn degree_one(equation: Vec<GaussianRational>) {
|
|||
println!("Polynomial degree: 1");
|
||||
let x = minus_one() * equation[0] / equation[1];
|
||||
println!("The solution is");
|
||||
let mut format = x.format();
|
||||
let mut format = x.format(false);
|
||||
if format == "" {
|
||||
format = String::from("0");
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ fn simplify_sqrt(n: i128) -> (i128, i128) {
|
|||
(natural, irrational)
|
||||
}
|
||||
|
||||
// Eric Naslund for the math https://math.stackexchange.com/questions/44406/how-do-i-get-the-square-root-of-a-complex-number
|
||||
fn comp_sqrt(c: GaussianRational) -> MyCompSqrt {
|
||||
let real = c.real();
|
||||
let imag = c.imaginary();
|
||||
|
@ -107,7 +108,7 @@ fn comp_sqrt(c: GaussianRational) -> MyCompSqrt {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_strings(left_part: Rational, sqrt_delta: MySqrt) -> (String, String, String, String, String, String) {
|
||||
fn get_strings(left_part: Rational, sqrt_delta: &MySqrt) -> (String, String, String, String, String, String) {
|
||||
let mut a = left_part.numerator;
|
||||
let mut b = sqrt_delta.numerator_natural;
|
||||
if b < 0 {
|
||||
|
@ -191,12 +192,12 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
|||
|
||||
let b = b / GaussianRational::new(Rational::new(-2, 1), Rational::new(0, 1));
|
||||
|
||||
let mut sign = '+';
|
||||
let mut sign = '±';
|
||||
if sqrt_delta.sign < 0 {
|
||||
sign = '-';
|
||||
sign = '∓';
|
||||
}
|
||||
|
||||
let (s1, s2, s3, s4, s5, s6) = get_strings(sqrt_delta.rational, sqrt_delta.sqrt);
|
||||
let (s1, s2, s3, s4, s5, s6) = get_strings(sqrt_delta.rational, &sqrt_delta.sqrt);
|
||||
let mut string1 = String::from("");
|
||||
let mut string2 = String::from("");
|
||||
let mut string3 = String::from("");
|
||||
|
@ -218,7 +219,7 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
|||
}
|
||||
|
||||
string1 = format!("{string1} /{s1}\\ ");
|
||||
string2 = format!("{string2} + sqrt | {s2} | ");
|
||||
string2 = format!("{string2} ± sqrt | {s2} | ");
|
||||
string3 = format!("{string3} \\{s3}/ ");
|
||||
|
||||
if b.imaginary.numerator != 0 {
|
||||
|
@ -241,9 +242,19 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio
|
|||
string2 = format!("{string2}{sign} sqrt | {s5} | i");
|
||||
string3 = format!("{string3} \\{s6}/ ");
|
||||
|
||||
println!("The two solutions are:");
|
||||
println!("{string1}");
|
||||
println!("{string2}");
|
||||
println!("{string3}");
|
||||
println!("Approximations:");
|
||||
let sqrt = sqrt_delta.sqrt.numerator_natural as f64 * approx_sqrt(sqrt_delta.sqrt.numerator_irrational);
|
||||
let left = b.real.numerator as f64 / b.real.denominator as f64;
|
||||
let left_sqrt = approx_sqrt_f64((sqrt_delta.rational.numerator as f64 + sqrt) / sqrt_delta.rational.denominator as f64);
|
||||
|
||||
let right = b.imaginary.numerator as f64 / b.imaginary.denominator as f64;
|
||||
let right_sqrt = sqrt_delta.sign as f64 * approx_sqrt_f64((-sqrt_delta.rational.numerator as f64 + sqrt) / sqrt_delta.rational.denominator as f64);
|
||||
println!("{}", format!("{} + {}i", left + left_sqrt, right + right_sqrt).split("+ -").collect::<Vec<_>>().join("- "));
|
||||
println!("{}", format!("{} + {}i", left - left_sqrt, right - right_sqrt).split("+ -").collect::<Vec<_>>().join("- "));
|
||||
}
|
||||
|
||||
fn sqrt(n: Rational, a: Rational) -> MySqrt {
|
||||
|
@ -320,6 +331,20 @@ fn print_degree_two_real(left_part: Rational, sqrt_delta: MySqrt, imaginary: boo
|
|||
println!("{}{string}", " ".repeat(4 + (len - string.chars().count()) / 2));
|
||||
println!("x = {}", "-".repeat(len));
|
||||
println!("{}{d}", " ".repeat(4 + (len - d.to_string().len()) / 2));
|
||||
let mut right = (sqrt_delta.numerator_natural as f64 * approx_sqrt(sqrt_delta.numerator_irrational)) / left_part.denominator as f64;
|
||||
let left = left_part.numerator as f64 / left_part.denominator as f64;
|
||||
if right < 0. {
|
||||
right *= -1.;
|
||||
}
|
||||
println!("Approximations:");
|
||||
if imaginary == true {
|
||||
println!("{} - {}i", left, right);
|
||||
println!("{} + {}i", left, right);
|
||||
} else {
|
||||
println!("{}", left - right);
|
||||
println!("{}", left + right);
|
||||
|
||||
}
|
||||
} else if string.len() > 0 {
|
||||
println!("x = {string}");
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue