Rust重載運(yùn)算符之復(fù)數(shù)四則運(yùn)算的實(shí)現(xiàn)
基本概念
復(fù)數(shù)定義
由實(shí)數(shù)部分和虛數(shù)部分所組成的數(shù),形如a+bi 。
其中a、b為實(shí)數(shù),i 為“虛數(shù)單位”,i² = -1,即虛數(shù)單位的平方等于-1。
a、b分別叫做復(fù)數(shù)a+bi的實(shí)部和虛部。
- 當(dāng)b=0時(shí),a+bi=a 為實(shí)數(shù);
- 當(dāng)b≠0時(shí),a+bi 又稱虛數(shù);
- 當(dāng)b≠0、a=0時(shí),bi 稱為純虛數(shù)。
實(shí)數(shù)和虛數(shù)都是復(fù)數(shù)的子集。如同實(shí)數(shù)可以在數(shù)軸上表示一樣復(fù)數(shù)也可以在平面上表示,復(fù)數(shù)x+yi以坐標(biāo)點(diǎn)(x,y)來(lái)表示。表示復(fù)數(shù)的平面稱為“復(fù)平面”。
復(fù)數(shù)相等
兩個(gè)復(fù)數(shù)不能比較大小,但當(dāng)個(gè)兩個(gè)復(fù)數(shù)的實(shí)部和虛部分別相等時(shí),即表示兩個(gè)復(fù)數(shù)相等。
共軛復(fù)數(shù)
如果兩個(gè)復(fù)數(shù)的實(shí)部相等,虛部互為相反數(shù),那么這兩個(gè)復(fù)數(shù)互為共軛復(fù)數(shù)。
復(fù)數(shù)的模
復(fù)數(shù)的實(shí)部與虛部的平方和的正的平方根的值稱為該復(fù)數(shù)的模,數(shù)學(xué)上用與絕對(duì)值“|z|”相同的符號(hào)來(lái)表示。雖然從定義上是不相同的,但兩者的物理意思都表示“到原點(diǎn)的距離”。
復(fù)數(shù)的四則運(yùn)算
加法(減法)法則
復(fù)數(shù)的加法法則:設(shè)z1=a+bi,z2 =c+di是任意兩個(gè)復(fù)數(shù)。兩者和的實(shí)部是原來(lái)兩個(gè)復(fù)數(shù)實(shí)部的和,它的虛部是原來(lái)兩個(gè)虛部的和。兩個(gè)復(fù)數(shù)的和依然是復(fù)數(shù)。
即(a+bi)±(c+di)=(a±c)+(b±d)
乘法法則
復(fù)數(shù)的乘法法則:把兩個(gè)復(fù)數(shù)相乘,類似兩個(gè)多項(xiàng)式相乘,結(jié)果中i²=-1,把實(shí)部與虛部分別合并。兩個(gè)復(fù)數(shù)的積仍然是一個(gè)復(fù)數(shù)。
即(a+bi)(c+di)=(ac-bd)+(bc+ad)i
除法法則
數(shù)除法法則:滿足(c+di)(x+yi)=(a+bi)的復(fù)數(shù)x+yi(x,y∈R)叫復(fù)數(shù)a+bi除以復(fù)數(shù)c+di的商。
運(yùn)算方法:可以把除法換算成乘法做,將分子分母同時(shí)乘上分母的共軛復(fù)數(shù),再用乘法運(yùn)算。
即(a+bi)/(c+di)=(a+bi)(c-di)/(c*c+d*d)=[(ac+bd)+(bc-ad)i]/(c*c+d*d)
復(fù)數(shù)的Rust代碼實(shí)現(xiàn)
結(jié)構(gòu)定義
Rust語(yǔ)言中,沒有像python一樣內(nèi)置complex復(fù)數(shù)數(shù)據(jù)類型,我們可以用兩個(gè)浮點(diǎn)數(shù)分別表示復(fù)數(shù)的實(shí)部和虛部,自定義一個(gè)結(jié)構(gòu)數(shù)據(jù)類型,表示如下:
struct Complex {
real: f64,
imag: f64,
}
示例代碼:
#[derive(Debug)]
struct Complex {
real: f64,
imag: f64,
}
impl Complex {
fn new(real: f64, imag: f64) -> Self {
Complex { real, imag }
}
}
fn main() {
let z = Complex::new(3.0, 4.0);
println!("{:?}", z);
println!("{} + {}i", z.real, z.imag);
}注意:#[derive(Debug)] 自動(dòng)定義了復(fù)數(shù)結(jié)構(gòu)的輸出格式,如以上代碼輸出如下:
Complex { real: 3.0, imag: 4.0 }
3 + 4i
重載四則運(yùn)算
復(fù)數(shù)數(shù)據(jù)結(jié)構(gòu)不能直接用加減乘除來(lái)做復(fù)數(shù)運(yùn)算,需要導(dǎo)入標(biāo)準(zhǔn)庫(kù)ops的運(yùn)算符:
use std::ops::{Add, Sub, Mul, Div, Neg};
Add, Sub, Mul, Div, Neg 分別表示加減乘除以及相反數(shù),類似C++或者python語(yǔ)言中“重載運(yùn)算符”的概念。
根據(jù)復(fù)數(shù)的運(yùn)算法則,寫出對(duì)應(yīng)代碼:
fn add(self, other: Complex) -> Complex {
Complex {
real: self.real + other.real,
imag: self.imag + other.imag,
}
}
fn sub(self, other: Complex) -> Complex {
Complex {
real: self.real - other.real,
imag: self.imag - other.imag,
}
}
fn mul(self, other: Complex) -> Complex {
let real = self.real * other.real - self.imag * other.imag;
let imag = self.real * other.imag + self.imag * other.real;
Complex { real, imag }
}
fn div(self, other: Complex) -> Complex {
let real = (self.real * other.real + self.imag * other.imag) / (other.real * other.real + other.imag * other.imag);
let imag = (self.imag * other.real - self.real * other.imag) / (other.real * other.real + other.imag * other.imag);
Complex { real, imag }
}
fn neg(self) -> Complex {
Complex {
real: -self.real,
imag: -self.imag,
}
}Rust 重載運(yùn)算的格式,請(qǐng)見如下示例代碼:
use std::ops::{Add, Sub, Mul, Div, Neg};
#[derive(Clone, Debug, PartialEq)]
struct Complex {
real: f64,
imag: f64,
}
impl Complex {
fn new(real: f64, imag: f64) -> Self {
Complex { real, imag }
}
fn conj(&self) -> Self {
Complex { real: self.real, imag: -self.imag }
}
fn abs(&self) -> f64 {
(self.real * self.real + self.imag * self.imag).sqrt()
}
}
fn abs(z: Complex) -> f64 {
(z.real * z.real + z.imag * z.imag).sqrt()
}
impl Add<Complex> for Complex {
type Output = Complex;
fn add(self, other: Complex) -> Complex {
Complex {
real: self.real + other.real,
imag: self.imag + other.imag,
}
}
}
impl Sub<Complex> for Complex {
type Output = Complex;
fn sub(self, other: Complex) -> Complex {
Complex {
real: self.real - other.real,
imag: self.imag - other.imag,
}
}
}
impl Mul<Complex> for Complex {
type Output = Complex;
fn mul(self, other: Complex) -> Complex {
let real = self.real * other.real - self.imag * other.imag;
let imag = self.real * other.imag + self.imag * other.real;
Complex { real, imag }
}
}
impl Div<Complex> for Complex {
type Output = Complex;
fn div(self, other: Complex) -> Complex {
let real = (self.real * other.real + self.imag * other.imag) / (other.real * other.real + other.imag * other.imag);
let imag = (self.imag * other.real - self.real * other.imag) / (other.real * other.real + other.imag * other.imag);
Complex { real, imag }
}
}
impl Neg for Complex {
type Output = Complex;
fn neg(self) -> Complex {
Complex {
real: -self.real,
imag: -self.imag,
}
}
}
fn main() {
let z1 = Complex::new(2.0, 3.0);
let z2 = Complex::new(3.0, 4.0);
let z3 = Complex::new(3.0, -4.0);
// 復(fù)數(shù)的四則運(yùn)算
let complex_add = z1.clone() + z2.clone();
println!("{:?} + {:?} = {:?}", z1, z2, complex_add);
let complex_sub = z1.clone() - z2.clone();
println!("{:?} - {:?} = {:?}", z1, z2, complex_sub);
let complex_mul = z1.clone() * z2.clone();
println!("{:?} * {:?} = {:?}", z1, z2, complex_mul);
let complex_div = z2.clone() / z3.clone();
println!("{:?} / {:?} = {:?}", z1, z2, complex_div);
// 對(duì)比兩個(gè)復(fù)數(shù)是否相等
println!("{:?}", z1 == z2);
// 共軛復(fù)數(shù)
println!("{:?}", z2 == z3.conj());
// 復(fù)數(shù)的相反數(shù)
println!("{:?}", z2 == -z3.clone() + Complex::new(6.0,0.0));
// 復(fù)數(shù)的模
println!("{}", z1.abs());
println!("{}", z2.abs());
println!("{}", abs(z3));
}輸出:
Complex { real: 2.0, imag: 3.0 } + Complex { real: 3.0, imag: 4.0 } = Complex { real: 5.0, imag: 7.0 }
Complex { real: 2.0, imag: 3.0 } - Complex { real: 3.0, imag: 4.0 } = Complex { real: -1.0, imag: -1.0 }
Complex { real: 2.0, imag: 3.0 } * Complex { real: 3.0, imag: 4.0 } = Complex { real: -6.0, imag: 17.0 }
Complex { real: 2.0, imag: 3.0 } / Complex { real: 3.0, imag: 4.0 } = Complex { real: -0.28, imag: 0.96 }
false
true
true
3.605551275463989
5
5
示例代碼中,同時(shí)還定義了復(fù)數(shù)的模 abs(),共軛復(fù)數(shù) conj()。
兩個(gè)復(fù)數(shù)的相等比較 z1 == z2,需要 #[derive(PartialEq)] 支持。
自定義 trait Display
復(fù)數(shù)結(jié)構(gòu)的原始 Debug trait 表達(dá)的輸出格式比較繁復(fù),如:
Complex { real: 2.0, imag: 3.0 } + Complex { real: 3.0, imag: 4.0 } = Complex { real: 5.0, imag: 7.0 }
想要輸出和數(shù)學(xué)中相同的表達(dá)(如 a + bi),需要自定義一個(gè) Display trait,代碼如下:
impl std::fmt::Display for Complex {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.imag == 0.0 {
formatter.write_str(&format!("{}", self.real))
} else {
let (abs, sign) = if self.imag > 0.0 {
(self.imag, "+" )
} else {
(-self.imag, "-" )
};
if abs == 1.0 {
formatter.write_str(&format!("({} {} i)", self.real, sign))
} else {
formatter.write_str(&format!("({} {} {}i)", self.real, sign, abs))
}
}
}
}輸出格式分三種情況:虛部為0,正數(shù)和負(fù)數(shù)。另外當(dāng)虛部絕對(duì)值為1時(shí)省略1僅輸出i虛數(shù)單位。
完整代碼如下:
use std::ops::{Add, Sub, Mul, Div, Neg};
#[derive(Clone, PartialEq)]
struct Complex {
real: f64,
imag: f64,
}
impl std::fmt::Display for Complex {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.imag == 0.0 {
formatter.write_str(&format!("{}", self.real))
} else {
let (abs, sign) = if self.imag > 0.0 {
(self.imag, "+" )
} else {
(-self.imag, "-" )
};
if abs == 1.0 {
formatter.write_str(&format!("({} {} i)", self.real, sign))
} else {
formatter.write_str(&format!("({} {} {}i)", self.real, sign, abs))
}
}
}
}
impl Complex {
fn new(real: f64, imag: f64) -> Self {
Complex { real, imag }
}
fn conj(&self) -> Self {
Complex { real: self.real, imag: -self.imag }
}
fn abs(&self) -> f64 {
(self.real * self.real + self.imag * self.imag).sqrt()
}
}
fn abs(z: Complex) -> f64 {
(z.real * z.real + z.imag * z.imag).sqrt()
}
impl Add<Complex> for Complex {
type Output = Complex;
fn add(self, other: Complex) -> Complex {
Complex {
real: self.real + other.real,
imag: self.imag + other.imag,
}
}
}
impl Sub<Complex> for Complex {
type Output = Complex;
fn sub(self, other: Complex) -> Complex {
Complex {
real: self.real - other.real,
imag: self.imag - other.imag,
}
}
}
impl Mul<Complex> for Complex {
type Output = Complex;
fn mul(self, other: Complex) -> Complex {
let real = self.real * other.real - self.imag * other.imag;
let imag = self.real * other.imag + self.imag * other.real;
Complex { real, imag }
}
}
impl Div<Complex> for Complex {
type Output = Complex;
fn div(self, other: Complex) -> Complex {
let real = (self.real * other.real + self.imag * other.imag) / (other.real * other.real + other.imag * other.imag);
let imag = (self.imag * other.real - self.real * other.imag) / (other.real * other.real + other.imag * other.imag);
Complex { real, imag }
}
}
impl Neg for Complex {
type Output = Complex;
fn neg(self) -> Complex {
Complex {
real: -self.real,
imag: -self.imag,
}
}
}
fn main() {
let z1 = Complex::new(2.0, 3.0);
let z2 = Complex::new(3.0, 4.0);
let z3 = Complex::new(3.0, -4.0);
// 復(fù)數(shù)的四則運(yùn)算
let complex_add = z1.clone() + z2.clone();
println!("{} + {} = {}", z1, z2, complex_add);
let z = Complex::new(1.5, 0.5);
println!("{} + {} = {}", z, z, z.clone() + z.clone());
let complex_sub = z1.clone() - z2.clone();
println!("{} - {} = {}", z1, z2, complex_sub);
let complex_sub = z1.clone() - z1.clone();
println!("{} - {} = {}", z1, z1, complex_sub);
let complex_mul = z1.clone() * z2.clone();
println!("{} * {} = {}", z1, z2, complex_mul);
let complex_mul = z2.clone() * z3.clone();
println!("{} * {} = {}", z2, z3, complex_mul);
let complex_div = z2.clone() / z3.clone();
println!("{} / {} = {}", z1, z2, complex_div);
let complex_div = Complex::new(1.0,0.0) / z2.clone();
println!("1 / {} = {}", z2, complex_div);
// 對(duì)比兩個(gè)復(fù)數(shù)是否相等
println!("{:?}", z1 == z2);
// 共軛復(fù)數(shù)
println!("{:?}", z2 == z3.conj());
// 復(fù)數(shù)的相反數(shù)
println!("{:?}", z2 == -z3.clone() + Complex::new(6.0,0.0));
// 復(fù)數(shù)的模
println!("{}", z1.abs());
println!("{}", z2.abs());
println!("{}", abs(z3));
}輸出:
(2 + 3i) + (3 + 4i) = (5 + 7i)
(1.5 + 0.5i) + (1.5 + 0.5i) = (3 + i)
(2 + 3i) - (3 + 4i) = (-1 - i)
(2 + 3i) - (2 + 3i) = 0
(2 + 3i) * (3 + 4i) = (-6 + 17i)
(3 + 4i) * (3 - 4i) = 25
(2 + 3i) / (3 + 4i) = (-0.28 + 0.96i)
1 / (3 + 4i) = (0.12 - 0.16i)
false
true
true
3.605551275463989
5
5
小結(jié)
如此,復(fù)數(shù)的四則運(yùn)算基本都實(shí)現(xiàn)了,當(dāng)然復(fù)數(shù)還有三角表示式和指數(shù)表示式,根據(jù)它們的數(shù)學(xué)定義寫出相當(dāng)代碼應(yīng)該不是很難。有了復(fù)數(shù)三角式,就能方便地定義出復(fù)數(shù)的開方運(yùn)算,有空可以寫寫這方面的代碼。
到此這篇關(guān)于Rust重載運(yùn)算符之復(fù)數(shù)四則運(yùn)算的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Rust運(yùn)算符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Rust中三種循環(huán)(loop,while,for)的使用
我們常常需要重復(fù)執(zhí)行同一段代碼,針對(duì)這種場(chǎng)景,Rust?提供了多種循環(huán)(loop)工具。一個(gè)循環(huán)會(huì)執(zhí)行循環(huán)體中的代碼直到結(jié)尾,并緊接著回到開頭繼續(xù)執(zhí)行。而?Rust?提供了?3?種循環(huán):loop、while?和?for,下面逐一講解2022-09-09
Rust調(diào)用Windows API 如何獲取正在運(yùn)行的全部進(jìn)程信息
本文介紹了如何使用Rust調(diào)用WindowsAPI獲取正在運(yùn)行的全部進(jìn)程信息,通過引入winapi依賴并添加相應(yīng)的features,可以實(shí)現(xiàn)對(duì)不同API集的調(diào)用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11

