| Uutiset | Koodikirjasto | Wiki | Keskustelut | FAQ | Info |
C# Kompleksiluku luokkagummikana 10.05.04 20:14 Esittelee miten C#:ssä tehdään operaattorien overloadaus ja on myös ihan toimiva kompleksiluku luokka
//////////////////////////////////////////////////////////////////////// // CComplex luokka. // // 10.5.2004 Petri Purho pete@markkupurho.fi // // // Kompleksiluku luokka joka myös esittelee miten C#:ssä tehdään // operaattorien overloadaus. // // Koodi löytynee myös täältä: // // http://koti.mbnet.fi/kumikana/soodaus/cs/CComplex/ // //////////////////////////////////////////////////////////////////////// using System; namespace Matikka { // Kompleksiluku luokka... public class CComplex { ///////////////////////////////////////////////////////////////// public CComplex() { myReal = 0; myImg = 0; } public CComplex( double real, double img ) { myReal = real; myImg = img; } // Toisin kuin C++:ssa niin C#:ssä ei konstruktoreista tehdä // sijoitus-operaattoreita. Itseasiassa sijoitus-operaattoreita // ( operator= ) ei C#:ssä ole samaan tyyliin kuin C++:ssa. Jos jotain // kopioidaan ( esim. CComplex x = u; ) niin tehdä aina bittikopio. // // Implisiittisiä kopioita voi kyllä tehdä seuraavaan tyyliin: /* public static implicit operator CComplex( double s ) { return new CComplex( s, s ); } */ // kyseistä funktiota kutsuttaisiin esim seuraavassa skenaariossa: /* CComplex z = 1.5; */ // Mutta koska kompleksilukuihin ei suoranaisesti sovi implisiittiset // konvertiot, niin olen sen jättänyt pois, mutta jos jotain kiinnostaa // niin siellä se on. // // Konstruktorin voi tehdä omasta tyypistään, mutta se on vähän turhaa // koska sitä kutsuttaisiin vain seuraavanlaisessa skenaariossa: /* CComplex z = new CComplex( 10, 10 ); CComplex u = new CComplex( z ); */ public CComplex( CComplex other ) { Console.WriteLine( "jees box" ); myReal = other.real; myImg = other.img; } //-------------------------------------------------------------- // operaattori-overloadausta.... // ============================================================= // Näitä käytetään esim seuraavassa tapauksessa: /* CComplex z = new CComplex( 3, 6 ); CComplex u = new CComplex( -9, 3 ); CComplex sum = z + u; // Tai epäsuorasti näin... z -= u; */ public static CComplex operator+ ( CComplex one, CComplex two ) { CComplex sum; sum = new CComplex( one.real + two.real, one.img + two.img ); return sum; } public static CComplex operator- ( CComplex one, CComplex two ) { CComplex sum; sum = new CComplex( one.real - two.real, one.img - two.img ); return sum; } // operator+ ( CComplex other ) ei oikeastaan tee juuri mitään... // mutta operator- ( CComplex other ) kääntää luvun negatiiviseksi // Näitä taas käytetään esim seuraavassa tapauksessa: /* CComplex z = new CComplex( 4, 5 ); z = -z; */ public static CComplex operator+ ( CComplex other ) { return other; } public static CComplex operator- ( CComplex other ) { CComplex sum; sum = new CComplex( - other.real, - other.img ); return sum; } // Näitä käytetään esim seuraavissa tapauksissa: /* CComplex z = new CComplex( 4, 6 ); CComplex u = new CComplex( -9, 2 ); CComplex sum = z * u; z /= u; */ public static CComplex operator* ( CComplex one, CComplex two ) { CComplex sum; double real; double img; real = ( ( one.real * two.real ) - ( one.img * two.img ) ); img = ( ( one.real * two.img ) + ( one.img * two.real ) ); sum = new CComplex( real, img ); return sum; } public static CComplex operator/ ( CComplex one, CComplex two ) { CComplex sum; double real; double img; real = ( one.real * two.real + one.img * two.img ) / ( Math.Pow( two.real, 2 ) + Math.Pow( two.img, 2 ) ); img = ( one.img * two.real - one.real * two.img ) / ( Math.Pow( two.real, 2 ) + Math.Pow( two.img, 2 ) ); sum = new CComplex( real, img ); return sum; } // Vertailu operaattorit... // Nämä, kuten muutkin bittioperaattorit ( <, > <=, => ) pitää // aina kirjoittaa pareittaan. Eli jos teet overloadaad < // operaattorin, täytyy sinun myös kirjoittaa koodi > operaattorille. // // Jos overloadaad vertailu operaattorit pitää sinun overridettaa // int GetHashCode() ja bool Equals( object o ) funktiot. // // Nämä kyseiset funktiot on overridetettu alempana. // // Vertailu operaattoreita käytetään esim seuraavassa tapauksessa: /* CComplex z = new CComplex( 1, 1 ); CComplex u = new CComplex( 1, 0 ); if ( z == u ) Console.WriteLine( "Ovat yhtäsuuret" ); */ public static bool operator==( CComplex one, CComplex two ) { return ( one.real == two.real && one.img == two.img ); } public static bool operator!=( CComplex one, CComplex two ) { return ( one.real != two.real || one.img != two.img ); } //-------------------------------------------------------------- // Nämä kaksi Equals ja GetHashCode pitää overridettaa, jotta // vertailu operaattoreita voisi käyttää... public override bool Equals(object o) { return this==(CComplex)o; } public override int GetHashCode() { return (int)( myReal + myImg ); } // Tätä metodia kutsutaan kun olio printataan consoliin. // esim /* CComplex z = new CComplex( 1, 0 ); Console.WriteLine( z ); */ public override string ToString() { return "" + real + ", " + img + "i"; } //-------------------------------------------------------------- // ainut varsinainen normaali metodi... public bool IsZero() { return ( myReal == 0 && myImg == 0 ); } //-------------------------------------------------------------- // Tässä on esimerkki C#:än tavasta käsitellä julkisia muuttujia. // C++:ssa koodattiin hyviä GetReal() ja SetReal( double real ) // funktioita käsittelemään tämä sama asia. C#:ssa homma hoidetaan // puoli automaattisesti. btw. value on sitten varattu sana, jos se // pistää ihmetyttämään. // // Esimerkki käytöstä: /* CComplex z = new CComplex( 1, 0 ); z.real = z.img; */ public double real { get{ return myReal; } set{ myReal = value; } } public double img { get{ return myImg; } set{ myImg = value; } } // Tämä antaa kompleksiluvun pituuden ja tällä voi määrittää // kompleksiluvulle jonkun pituuden. // Näppärä vaikka eksponenttimuotoisen esityksen tekemiseen. public double r { get { return ( Math.Sqrt( ( Math.Pow( myReal, 2 ) + Math.Pow( myImg, 2 ) ) ) ); } set { double ilength = value * ( 1 / this.r ); myReal *= ilength; myImg *= ilength; } } // Tämä taas antaa ja antaa muuttaa kompeksiluvun vaihekulmaa // imaginäriakselin suhteen. // Näppärä eksponenttimuotoisen esityksen tekemiseen. // Kulmat muuten ovat sitten radeaaneja, ettei tarvi ihmetellä. public double arg { get { double real = ( Math.Acos( myReal / this.r ) ); double img = ( Math.Asin( myImg / this.r ) ); if ( real == img ) return real; if ( real < 0 ) return real; if ( img < 0 ) return img; return real; } set { double r = this.r; myReal = Math.Cos( value ) * r; myImg = Math.Sin( value ) * r; } } //-------------------------------------------------------------- // // Luokan private muuttujat... private double myReal; private double myImg; ///////////////////////////////////////////////////////////////// } // Esimerkki ohjelma... class CMain { static void Main(string[] args) { CComplex z = new CComplex( 1, 1 ); z.r = Math.Sqrt( 13 ); z.arg = -0.588; Console.WriteLine( z ); } } } Anylo 21:26 11.5.04 Esittelee hyvin operaattorien toimintaa c#:ssa. |
![]() Haku
|