tft每日頭條

 > 生活

 > c語言兩數相減怎麼寫

c語言兩數相減怎麼寫

生活 更新时间:2024-07-26 13:21:56

複數稱Complex Number,從英文上來看似乎它是“複雜的數”。其實并不然,它實際上指的是複合數,即由實部和虛部複合而成的數。它可以用下面的公式表示:

c語言兩數相減怎麼寫(從一維到二維C複數運算總結)1

這裡,純實數a是實部,ib是虛部,其中,a b都是實數,i是虛數。

如果我們将實部作為x軸,虛部作為y軸,複數就可以在坐标軸上表示了,這樣的坐标系我們稱作複數坐标系。它和複平面上原點的連線可以表示一個向量,向量和x軸的夾角為複數的輻角theta。

c語言兩數相減怎麼寫(從一維到二維C複數運算總結)2

實數我們大家都很熟悉,在平時生活中,常用的也都是一些實數。那麼,虛數是什麼呢?

虛數并不是單純的數字,如果x^2=-1,我們就将它們的解定義為 /-i,這裡的i就是虛數,很顯然虛數似乎并不是我們平時所使用的數,因為在我們所理解的實數領裡任何一個數進行平方之後都不可能是小于0的,但這并代表它沒有意義,我們可以換一個角度來理解虛數,我們通過它可将實數擴展到複數域。

要理解虛數我們就需要先複習一下之前學習的歐拉公式:

如果,

則,

相信這裡大家應該有了發現:

在複數域中,

複數與複指數相乘,相當于複數對應的向量旋轉對應的角度。

這裡就相當于我們把1逆時針旋轉90度,就可以得到i,如果我們再逆時針旋轉90度就是-1,也就是i*i。

所以,大家也就明白了i的含義,以及為什麼i的平方等于-1了。

c語言兩數相減怎麼寫(從一維到二維C複數運算總結)3

因此,虛數i的幾何意義上是一個旋轉量。

數學是一個偉大的工具,從實數到複數的擴展是一個裡程碑的進步。數學家雅克·阿達馬說,在實數域中,連接兩個真理的最短的路徑是通過複數域。

c語言兩數相減怎麼寫(從一維到二維C複數運算總結)4

程序中如何定義複數?

在C 中,complex頭文件中定義了一個complex模闆類型,用來處理複數。格式如下:

template <class T> class complex; template<> class complex<float>; template<> class complex<double>; template<> class complex<long double>;

T是實部和虛部的數字的數據類型,它可以支持float、double、long double這幾種類型。

複數這個類模闆有多個構造函數:

complex( const T& re = T(), const T& im = T() ); complex( const complex& other ); template<class X > complex( const complex<X>& other);

從上面複數的構造函數可以看出,我們可以用下面的幾種方法來定義一個複數:

  • 根據實部和虛部的值來構造一個複數;
  • 根據一個複數的值來構造一個複數;
  • 從不同類型的複數構造一個複數。

#include <iostream> #include <complex> int main () { std::complex<float> z1(1.2, 2.3); std::complex<float> z2(z1); std::complex<double> z3(z2); std::cout << z3 << '\n'; return 0; }

結果輸出:

(1.2,2.3)

複數的運算

複數和實數一樣是可以進行 - × /等算術運算的。假如有兩個複數z1和z2,如下:

複數的加法是将兩個複數的實部和實部相加,虛部和虛部相加:

同樣的,複數的減法是将兩個複數的實部和實部相減,虛部和虛部相減:

複數的乘法呢?因為複數也是滿足實數域的交換律、結合律以及分配律這些定理,因此,我們可以對乘法進行分解。

除法就會複雜一些,我們需要考慮将分母的複數轉成實數。該怎麼進行轉換呢?在這之前,我們需要先了解共轭複數,如果有兩個複數z2=c di和z3=c-di,他們實部相同,虛部互為相反數,我們稱它們互為共轭,z2是z3的共轭複數,z3也是z2的共轭複數。

c語言兩數相減怎麼寫(從一維到二維C複數運算總結)5

共轭

共轭複數有這樣的一個特性,如果兩個共轭複數相乘,它們的結果是一個實數。

因此,我們可以利用共轭複數的這個特性進行複數的除法運算。

實際上,我們在使用C 寫程序時不需要這麼複雜的公式計算,complex類實際上已經進行重載了這些操作。

complex& operator= (const T& val); template<class X> complex& operator= (const complex<X>& rhs); template<class T> complex<T> operator (const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator (const complex<T>& lhs, const T& val); template<class T> complex<T> operator (const T& val, const complex<T>& rhs); template<class T> complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator-(const complex<T>& lhs, const T& val); template<class T> complex<T> operator-(const T& val, const complex<T>& rhs); template<class T> complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator*(const complex<T>& lhs, const T& val); template<class T> complex<T> operator*(const T& val, const complex<T>& rhs); template<class T> complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator/(const complex<T>& lhs, const T& val); template<class T> complex<T> operator/(const T& val, const complex<T>& rhs); template<class T> complex<T> operator (const complex<T>& rhs); template<class T> complex<T> operator-(const complex<T>& rhs);

complex頭文件中已經包含了常見的運算操作,我們通過下面的的例子來加深了解。

#include <iostream> #include <complex> int main () { std::complex<double> z1(1, 2); std::complex<double> z2 = std::complex<double>(3, 4); std::cout << "z1: " << z1 << std::endl; std::cout << "z2: " << z2 << std::endl; std::cout << "z1 z2: " << z1 z2 << std::endl; std::cout << "z1-z2: " << z1-z2 << std::endl; std::cout << "z1*z2: " << z1*z2 << std::endl; std::cout << "z1/z2: " << z1/z2 << std::endl; std::cout << "z1 2: " <<z1 2.0<< std::endl; return 0; }

上面的例子中,我們可以使用=直接對複數進行賦值操作,還可以使用運算符對複數進行運算,而且也支持實數和複數之間的運算,其輸出結果如下:

z1: (1,2) z2: (3,4) z1 z2: (4,6) z1-z2: (-2,-2) z1*z2: (-5,10) z1/z2: (0.44,0.08) z1 2: (3,2)

當然,除了上面的運算,還支持 = -= *= /=等這些運算。

complex& operator = (const T& val); complex& operator-= (const T& val); complex& operator*= (const T& val); complex& operator/= (const T& val); template<class X> complex& operator = (const complex<X>& rhs); template<class X> complex& operator-= (const complex<X>& rhs); template<class X> complex& operator*= (const complex<X>& rhs); template<class X> complex& operator/= (const complex<X>& rhs);

同樣的,我們看下面的代碼:

#include <iostream> #include <complex> int main () { std::complex<double> z1(1, 2); std::complex<double> z2 = std::complex<double>(3, 4); z1 = 2.0; z2 -= z1; std::cout << "z1: " << z1 << std::endl; std::cout << "z2: " << z2 << std::endl; return 0; }

上面的代碼執行結果:

z1: (3,2) z2: (0,2)

一些其他函數

除了上面的一些運算,complex頭文件裡還有一些函數,我們選擇一些常見的函數來進行介紹。

  • real和imag函數
  • abs函數
  • conj函數
  • arg和polar函數
  • norm函數
  • exp函數
real和imag函數

我們知道了複數有實部和虛部組成,當我們需要分開對實部和虛部處理的時候,如何取得實部和虛部的值呢?

complex頭文件定義了獲取實部(real函數)和虛部(imag函數)的函數:

template<class T> T real (const complex<T>& x); template<class T> T imag (const complex<T>& x);

示例:

#include <iostream> #include <complex> int main () { std::complex<double> z1 (1,2); std::cout << "real part: " << std::real(z1) << '\n'; std::cout << "imag part: " << std::imag(z1) << '\n'; return 0; }

結果:

real part: 1 imag part: 2

abs函數

複數的模也就是向量的長度,它可以根據複數的實部與虛部數值的平方和的平方根的值求出。我們常利用abs函數計算信号的幅度大小。

complex頭文件中取模函數是abs,其定義:

template<class T> T abs (const complex<T>& x);

示例:

#include <iostream> #include <complex> int main () { std::complex<double> z1 (3.0,4.0); std::cout << "Absolute value: "<< std::abs(z1) << std::endl; return 0; }

結果:

Absolute value: 5

conj函數

在上面的除法運算中,我們知道,如果實部相同,虛部互為相反數,那麼它們互為共轭複數。complex也提供了一個函數conj便于我們求解一個複數的共轭複數。

template<class T> complex<T> conj (const complex<T>& x);

示例:

#include <iostream> #include <complex> int main () { std::complex<double> z1 (2.0,3.0); std::cout << "z1: " << z1 << std::endl; std::cout << "z1 conjugate: " << std::conj(z1) << std::endl; return 0; }

結果:

z1: (2,3) z1 conjugate: (2,-3)

arg函數與polar函數

arg和polar是兩個”相反“的函數,這兩個函數可以進行相互轉換。arg函數作用是根據一個複數返回一個角度,而polar函數可以根據角度返回一個複數。它們在計算相位或者根據相位計算其對應的IQ時較為常用。

template<class T> T arg (const complex<T>& x); template<class T> complex<T> polar (const T& rho, const T& theta = 0);

示例:

#include <iostream> #include <complex> int main () { std::complex<double> z1 (3,4); double theta = std::arg(z1); std::complex<double> z2 = std::polar(5.0, theta); std::cout << "angle:" << theta << std::endl; std::cout << "polar:" << z2 << std::endl; return 0; }

上面的示例先用arg函數求出對應的theta角,然後,再用polar函數根據求出的theta角以及幅值r返回相應的複數,結果如下:

angle:0.927295 polar:(3,4)

norm函數

norm函數可以計算複數的平方和,即實部和虛部平方的和,可用于計算IQ數據的功率大小。其定義如下:

template<class T> T norm (const complex<T>& x);

示例:

#include <iostream> #include <complex> int main () { std::complex<double> z1 (3.0,4.0); std::cout << "z1 norm: " << std::norm(z1) << std::endl; return 0; }

結果:

z1 norm: 25

exp函數

complex也支持自然指數,我們可以使用exp函數。通過這個函數,我們就可以生成我們想要的複指數信号了。

template<class T> complex<T> exp (const complex<T>& x);

我們可以利用這個函數生成一個theta角為pi的複指數數據,示例代碼:

#include <complex> #include <iostream> int main() { double pi = std::acos(-1); std::complex<double> i(0, 1); std::cout << std::fixed << " exp(i*pi) = " << std::exp(i * pi) << '\n'; }

運行結果如下:

exp(i*pi) = (-1.000000,0.000000)

最後

毋庸置疑,複數的提出對數學界來說是一個全新的發展,複數擴展了數的概念,讓數從一維變成了二維。複數也是現代數字通信行業發展的必要條件,它是數字信号處理的基礎。數字信号處理是一個極為抽象和複雜的學科,掌握複數的處理方法對數字信号處理應用實為必要,因此大家一定要熟練掌握這些方法的應用。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved