calculator-rs/src/numbers.rs

84 lines
2.1 KiB
Rust

use std::ops::*;
pub trait Number: Add + Sub + Mul + Div + Neg + Clone + Sized { }
impl<T: Add + Sub + Mul + Div + Neg + Clone + Sized> Number for T {}
/// angles are assumed to always be in radians
pub type Angle = f64;
#[derive(Debug, Clone, PartialEq)]
pub struct Complex{
real: f64,
imaginary: f64,
}
impl Complex {
pub const IMAGINARY_UNIT: Self = Self { real:0.0, imaginary: 0.0};
/// computes the absolute value of a complex number
pub fn abs(&self) -> f64 {
(self.real.powi(2) + self.imaginary.powi(2)).sqrt()
}
/// returns a unit vector that is angle a away from the positive x axis
pub fn unit_angle(a: Angle) -> Self {
Self {
real: a.cos(),
imaginary: a.sin(),
}
}
}
impl From<f64> for Complex {
fn from(value: f64) -> Self {
Self { real: value, imaginary: 0.0 }
}
}
impl Add for Complex {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
real: self.real + rhs.real,
imaginary: self.imaginary + rhs.imaginary
}
}
}
impl AddAssign for Complex {
fn add_assign(&mut self, rhs: Self) {
*self = self.clone() + rhs;
}
}
impl Sub for Complex {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
real: self.real - rhs.real,
imaginary: self.imaginary - rhs.imaginary
}
}
}
impl SubAssign for Complex {
fn sub_assign(&mut self, rhs: Self) {
*self = self.clone() - rhs;
}
}
impl Mul for Complex {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self {
real: self.real * rhs.real - self.imaginary * rhs.imaginary,
imaginary: self.real * rhs.imaginary + self.imaginary * rhs.real,
}
}
}
impl Div for Complex {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self {
real: self.real / rhs.real - self.imaginary / rhs.imaginary,
imaginary: self.real / rhs.imaginary + self.imaginary / rhs.real,
}
}
}