@@ -12,6 +12,7 @@ namespace System.Numerics
1212 /// A complex number z is a number of the form z = x + yi, where x and y
1313 /// are real numbers, and i is the imaginary unit, with the property i2= -1.
1414 /// </summary>
15+ [ Serializable ]
1516 public struct Complex : IEquatable < Complex > , IFormattable
1617 {
1718 public static readonly Complex Zero = new Complex ( 0.0 , 0.0 ) ;
@@ -29,20 +30,21 @@ public struct Complex : IEquatable<Complex>, IFormattable
2930 // This value is used inside Asin and Acos.
3031 private static readonly double s_log2 = Math . Log ( 2.0 ) ;
3132
32- private double _real ;
33- private double _imaginary ;
33+ // Do not rename, these fields are needed for binary serialization
34+ private double m_real ;
35+ private double m_imaginary ;
3436
3537 public Complex ( double real , double imaginary )
3638 {
37- _real = real ;
38- _imaginary = imaginary ;
39+ m_real = real ;
40+ m_imaginary = imaginary ;
3941 }
4042
41- public double Real { get { return _real ; } }
42- public double Imaginary { get { return _imaginary ; } }
43+ public double Real { get { return m_real ; } }
44+ public double Imaginary { get { return m_imaginary ; } }
4345
4446 public double Magnitude { get { return Abs ( this ) ; } }
45- public double Phase { get { return Math . Atan2 ( _imaginary , _real ) ; } }
47+ public double Phase { get { return Math . Atan2 ( m_imaginary , m_real ) ; } }
4648
4749 public static Complex FromPolarCoordinates ( double magnitude , double phase )
4850 {
@@ -76,34 +78,34 @@ public static Complex Divide(Complex dividend, Complex divisor)
7678
7779 public static Complex operator - ( Complex value ) /* Unary negation of a complex number */
7880 {
79- return new Complex ( - value . _real , - value . _imaginary ) ;
81+ return new Complex ( - value . m_real , - value . m_imaginary ) ;
8082 }
8183
8284 public static Complex operator + ( Complex left , Complex right )
8385 {
84- return new Complex ( left . _real + right . _real , left . _imaginary + right . _imaginary ) ;
86+ return new Complex ( left . m_real + right . m_real , left . m_imaginary + right . m_imaginary ) ;
8587 }
8688
8789 public static Complex operator - ( Complex left , Complex right )
8890 {
89- return new Complex ( left . _real - right . _real , left . _imaginary - right . _imaginary ) ;
91+ return new Complex ( left . m_real - right . m_real , left . m_imaginary - right . m_imaginary ) ;
9092 }
9193
9294 public static Complex operator * ( Complex left , Complex right )
9395 {
9496 // Multiplication: (a + bi)(c + di) = (ac -bd) + (bc + ad)i
95- double result_Realpart = ( left . _real * right . _real ) - ( left . _imaginary * right . _imaginary ) ;
96- double result_Imaginarypart = ( left . _imaginary * right . _real ) + ( left . _real * right . _imaginary ) ;
97- return new Complex ( result_Realpart , result_Imaginarypart ) ;
97+ double result_realpart = ( left . m_real * right . m_real ) - ( left . m_imaginary * right . m_imaginary ) ;
98+ double result_imaginarypart = ( left . m_imaginary * right . m_real ) + ( left . m_real * right . m_imaginary ) ;
99+ return new Complex ( result_realpart , result_imaginarypart ) ;
98100 }
99101
100102 public static Complex operator / ( Complex left , Complex right )
101103 {
102104 // Division : Smith's formula.
103- double a = left . _real ;
104- double b = left . _imaginary ;
105- double c = right . _real ;
106- double d = right . _imaginary ;
105+ double a = left . m_real ;
106+ double b = left . m_imaginary ;
107+ double c = right . m_real ;
108+ double d = right . m_imaginary ;
107109
108110 if ( Math . Abs ( d ) < Math . Abs ( c ) )
109111 {
@@ -119,7 +121,7 @@ public static Complex Divide(Complex dividend, Complex divisor)
119121
120122 public static double Abs ( Complex value )
121123 {
122- return Hypot ( value . _real , value . _imaginary ) ;
124+ return Hypot ( value . m_real , value . m_imaginary ) ;
123125 }
124126
125127 private static double Hypot ( double a , double b )
@@ -191,13 +193,13 @@ private static double Log1P(double x)
191193 public static Complex Conjugate ( Complex value )
192194 {
193195 // Conjugate of a Complex number: the conjugate of x+i*y is x-i*y
194- return new Complex ( value . _real , - value . _imaginary ) ;
196+ return new Complex ( value . m_real , - value . m_imaginary ) ;
195197 }
196198
197199 public static Complex Reciprocal ( Complex value )
198200 {
199201 // Reciprocal of a Complex number : the reciprocal of x+i*y is 1/(x+i*y)
200- if ( value . _real == 0 && value . _imaginary == 0 )
202+ if ( value . m_real == 0 && value . m_imaginary == 0 )
201203 {
202204 return Zero ;
203205 }
@@ -206,12 +208,12 @@ public static Complex Reciprocal(Complex value)
206208
207209 public static bool operator == ( Complex left , Complex right )
208210 {
209- return left . _real == right . _real && left . _imaginary == right . _imaginary ;
211+ return left . m_real == right . m_real && left . m_imaginary == right . m_imaginary ;
210212 }
211213
212214 public static bool operator != ( Complex left , Complex right )
213215 {
214- return left . _real != right . _real || left . _imaginary != right . _imaginary ;
216+ return left . m_real != right . m_real || left . m_imaginary != right . m_imaginary ;
215217 }
216218
217219 public override bool Equals ( object obj )
@@ -222,47 +224,47 @@ public override bool Equals(object obj)
222224
223225 public bool Equals ( Complex value )
224226 {
225- return _real . Equals ( value . _real ) && _imaginary . Equals ( value . _imaginary ) ;
227+ return m_real . Equals ( value . m_real ) && m_imaginary . Equals ( value . m_imaginary ) ;
226228 }
227229
228230 public override int GetHashCode ( )
229231 {
230232 int n1 = 99999997 ;
231- int realHash = _real . GetHashCode ( ) % n1 ;
232- int imaginaryHash = _imaginary . GetHashCode ( ) ;
233+ int realHash = m_real . GetHashCode ( ) % n1 ;
234+ int imaginaryHash = m_imaginary . GetHashCode ( ) ;
233235 int finalHash = realHash ^ imaginaryHash ;
234236 return finalHash ;
235237 }
236238
237239 public override string ToString ( )
238240 {
239- return string . Format ( CultureInfo . CurrentCulture , "({0}, {1})" , _real , _imaginary ) ;
241+ return string . Format ( CultureInfo . CurrentCulture , "({0}, {1})" , m_real , m_imaginary ) ;
240242 }
241243
242244 public string ToString ( string format )
243245 {
244- return string . Format ( CultureInfo . CurrentCulture , "({0}, {1})" , _real . ToString ( format , CultureInfo . CurrentCulture ) , _imaginary . ToString ( format , CultureInfo . CurrentCulture ) ) ;
246+ return string . Format ( CultureInfo . CurrentCulture , "({0}, {1})" , m_real . ToString ( format , CultureInfo . CurrentCulture ) , m_imaginary . ToString ( format , CultureInfo . CurrentCulture ) ) ;
245247 }
246248
247249 public string ToString ( IFormatProvider provider )
248250 {
249- return string . Format ( provider , "({0}, {1})" , _real , _imaginary ) ;
251+ return string . Format ( provider , "({0}, {1})" , m_real , m_imaginary ) ;
250252 }
251253
252254 public string ToString ( string format , IFormatProvider provider )
253255 {
254- return string . Format ( provider , "({0}, {1})" , _real . ToString ( format , provider ) , _imaginary . ToString ( format , provider ) ) ;
256+ return string . Format ( provider , "({0}, {1})" , m_real . ToString ( format , provider ) , m_imaginary . ToString ( format , provider ) ) ;
255257 }
256258
257259 public static Complex Sin ( Complex value )
258260 {
259261 // We need both sinh and cosh of imaginary part. To avoid multiple calls to Math.Exp with the same value,
260262 // we compute them both here from a single call to Math.Exp.
261- double p = Math . Exp ( value . _imaginary ) ;
263+ double p = Math . Exp ( value . m_imaginary ) ;
262264 double q = 1.0 / p ;
263265 double sinh = ( p - q ) * 0.5 ;
264266 double cosh = ( p + q ) * 0.5 ;
265- return new Complex ( Math . Sin ( value . _real ) * cosh , Math . Cos ( value . _real ) * sinh ) ;
267+ return new Complex ( Math . Sin ( value . m_real ) * cosh , Math . Cos ( value . m_real ) * sinh ) ;
266268 // There is a known limitation with this algorithm: inputs that cause sinh and cosh to overflow, but for
267269 // which sin or cos are small enough that sin * cosh or cos * sinh are still representable, nonetheless
268270 // produce overflow. For example, Sin((0.01, 711.0)) should produce (~3.0E306, PositiveInfinity), but
@@ -273,8 +275,8 @@ public static Complex Sin(Complex value)
273275 public static Complex Sinh ( Complex value )
274276 {
275277 // Use sinh(z) = -i sin(iz) to compute via sin(z).
276- Complex sin = Sin ( new Complex ( - value . _imaginary , value . _real ) ) ;
277- return new Complex ( sin . _imaginary , - sin . _real ) ;
278+ Complex sin = Sin ( new Complex ( - value . m_imaginary , value . m_real ) ) ;
279+ return new Complex ( sin . m_imaginary , - sin . m_real ) ;
278280 }
279281
280282 public static Complex Asin ( Complex value )
@@ -299,18 +301,18 @@ public static Complex Asin(Complex value)
299301 }
300302
301303 public static Complex Cos ( Complex value ) {
302- double p = Math . Exp ( value . _imaginary ) ;
304+ double p = Math . Exp ( value . m_imaginary ) ;
303305 double q = 1.0 / p ;
304306 double sinh = ( p - q ) * 0.5 ;
305307 double cosh = ( p + q ) * 0.5 ;
306- return new Complex ( Math . Cos ( value . _real ) * cosh , - Math . Sin ( value . _real ) * sinh ) ;
308+ return new Complex ( Math . Cos ( value . m_real ) * cosh , - Math . Sin ( value . m_real ) * sinh ) ;
307309 }
308310
309311 [ SuppressMessage ( "Microsoft.Naming" , "CA1704:IdentifiersShouldBeSpelledCorrectly" , MessageId = "Cosh" , Justification = "Cosh is the name of a mathematical function." ) ]
310312 public static Complex Cosh ( Complex value )
311313 {
312314 // Use cosh(z) = cos(iz) to compute via cos(z).
313- return Cos ( new Complex ( - value . _imaginary , value . _real ) ) ;
315+ return Cos ( new Complex ( - value . m_imaginary , value . m_real ) ) ;
314316 }
315317
316318 public static Complex Acos ( Complex value )
@@ -345,12 +347,12 @@ public static Complex Tan(Complex value)
345347 // tan z = (sin(2x) / cosh(2y) + i \tanh(2y)) / (1 + cos(2x) / cosh(2y))
346348 // which correctly computes the (tiny) real part and the (normal-sized) imaginary part.
347349
348- double x2 = 2.0 * value . _real ;
349- double y2 = 2.0 * value . _imaginary ;
350+ double x2 = 2.0 * value . m_real ;
351+ double y2 = 2.0 * value . m_imaginary ;
350352 double p = Math . Exp ( y2 ) ;
351353 double q = 1.0 / p ;
352354 double cosh = ( p + q ) * 0.5 ;
353- if ( Math . Abs ( value . _imaginary ) <= 4.0 )
355+ if ( Math . Abs ( value . m_imaginary ) <= 4.0 )
354356 {
355357 double sinh = ( p - q ) * 0.5 ;
356358 double D = Math . Cos ( x2 ) + cosh ;
@@ -367,8 +369,8 @@ public static Complex Tan(Complex value)
367369 public static Complex Tanh ( Complex value )
368370 {
369371 // Use tanh(z) = -i tan(iz) to compute via tan(z).
370- Complex tan = Tan ( new Complex ( - value . _imaginary , value . _real ) ) ;
371- return new Complex ( tan . _imaginary , - tan . _real ) ;
372+ Complex tan = Tan ( new Complex ( - value . m_imaginary , value . m_real ) ) ;
373+ return new Complex ( tan . m_imaginary , - tan . m_real ) ;
372374 }
373375
374376 public static Complex Atan ( Complex value )
@@ -497,7 +499,7 @@ private static void Asin_Internal (double x, double y, out double b, out double
497499
498500 public static Complex Log ( Complex value )
499501 {
500- return new Complex ( Math . Log ( Abs ( value ) ) , Math . Atan2 ( value . _imaginary , value . _real ) ) ;
502+ return new Complex ( Math . Log ( Abs ( value ) ) , Math . Atan2 ( value . m_imaginary , value . m_real ) ) ;
501503 }
502504
503505 public static Complex Log ( Complex value , double baseValue )
@@ -513,26 +515,26 @@ public static Complex Log10(Complex value)
513515
514516 public static Complex Exp ( Complex value )
515517 {
516- double expReal = Math . Exp ( value . _real ) ;
517- double cosImaginary = expReal * Math . Cos ( value . _imaginary ) ;
518- double sinImaginary = expReal * Math . Sin ( value . _imaginary ) ;
518+ double expReal = Math . Exp ( value . m_real ) ;
519+ double cosImaginary = expReal * Math . Cos ( value . m_imaginary ) ;
520+ double sinImaginary = expReal * Math . Sin ( value . m_imaginary ) ;
519521 return new Complex ( cosImaginary , sinImaginary ) ;
520522 }
521523
522524 [ SuppressMessage ( "Microsoft.Naming" , "CA1704:IdentifiersShouldBeSpelledCorrectly" , MessageId = "Sqrt" , Justification = "Sqrt is the name of a mathematical function." ) ]
523525 public static Complex Sqrt ( Complex value )
524526 {
525527
526- if ( value . _imaginary == 0.0 )
528+ if ( value . m_imaginary == 0.0 )
527529 {
528530 // Handle the trivial case quickly.
529- if ( value . _real < 0.0 )
531+ if ( value . m_real < 0.0 )
530532 {
531- return new Complex ( 0.0 , Math . Sqrt ( - value . _real ) ) ;
533+ return new Complex ( 0.0 , Math . Sqrt ( - value . m_real ) ) ;
532534 }
533535 else
534536 {
535- return new Complex ( Math . Sqrt ( value . _real ) , 0.0 ) ;
537+ return new Complex ( Math . Sqrt ( value . m_real ) , 0.0 ) ;
536538 }
537539 }
538540 else
@@ -565,35 +567,35 @@ public static Complex Sqrt(Complex value)
565567 // make the result representable. To avoid this, we re-scale (by exact powers of 2 for accuracy)
566568 // when we encounter very large components to avoid intermediate infinities.
567569 bool rescale = false ;
568- if ( ( Math . Abs ( value . _real ) >= s_sqrtRescaleThreshold ) || ( Math . Abs ( value . _imaginary ) >= s_sqrtRescaleThreshold ) )
570+ if ( ( Math . Abs ( value . m_real ) >= s_sqrtRescaleThreshold ) || ( Math . Abs ( value . m_imaginary ) >= s_sqrtRescaleThreshold ) )
569571 {
570- if ( double . IsInfinity ( value . _imaginary ) && ! double . IsNaN ( value . _real ) )
572+ if ( double . IsInfinity ( value . m_imaginary ) && ! double . IsNaN ( value . m_real ) )
571573 {
572574 // We need to handle infinite imaginary parts specially because otherwise
573575 // our formulas below produce inf/inf = NaN. The NaN test is necessary
574576 // so that we return NaN rather than (+inf,inf) for (NaN,inf).
575- return ( new Complex ( double . PositiveInfinity , value . _imaginary ) ) ;
577+ return ( new Complex ( double . PositiveInfinity , value . m_imaginary ) ) ;
576578 }
577579 else
578580 {
579- value . _real *= 0.25 ;
580- value . _imaginary *= 0.25 ;
581+ value . m_real *= 0.25 ;
582+ value . m_imaginary *= 0.25 ;
581583 rescale = true ;
582584 }
583585 }
584586
585587 // This is the core of the algorithm. Everything else is special case handling.
586588 double x , y ;
587- if ( value . _real >= 0.0 )
589+ if ( value . m_real >= 0.0 )
588590 {
589- x = Math . Sqrt ( ( Hypot ( value . _real , value . _imaginary ) + value . _real ) * 0.5 ) ;
590- y = value . _imaginary / ( 2.0 * x ) ;
591+ x = Math . Sqrt ( ( Hypot ( value . m_real , value . m_imaginary ) + value . m_real ) * 0.5 ) ;
592+ y = value . m_imaginary / ( 2.0 * x ) ;
591593 }
592594 else
593595 {
594- y = Math . Sqrt ( ( Hypot ( value . _real , value . _imaginary ) - value . _real ) * 0.5 ) ;
595- if ( value . _imaginary < 0.0 ) y = - y ;
596- x = value . _imaginary / ( 2.0 * y ) ;
596+ y = Math . Sqrt ( ( Hypot ( value . m_real , value . m_imaginary ) - value . m_real ) * 0.5 ) ;
597+ if ( value . m_imaginary < 0.0 ) y = - y ;
598+ x = value . m_imaginary / ( 2.0 * y ) ;
597599 }
598600
599601 if ( rescale )
@@ -620,10 +622,10 @@ public static Complex Pow(Complex value, Complex power)
620622 return Zero ;
621623 }
622624
623- double valueReal = value . _real ;
624- double valueImaginary = value . _imaginary ;
625- double powerReal = power . _real ;
626- double powerImaginary = power . _imaginary ;
625+ double valueReal = value . m_real ;
626+ double valueImaginary = value . m_imaginary ;
627+ double powerReal = power . m_real ;
628+ double powerImaginary = power . m_imaginary ;
627629
628630 double rho = Abs ( value ) ;
629631 double theta = Math . Atan2 ( valueImaginary , valueReal ) ;
@@ -641,8 +643,8 @@ public static Complex Pow(Complex value, double power)
641643
642644 private static Complex Scale ( Complex value , double factor )
643645 {
644- double realResult = factor * value . _real ;
645- double imaginaryResuilt = factor * value . _imaginary ;
646+ double realResult = factor * value . m_real ;
647+ double imaginaryResuilt = factor * value . m_imaginary ;
646648 return new Complex ( realResult , imaginaryResuilt ) ;
647649 }
648650
0 commit comments