@@ -30,7 +30,8 @@ import Foundation
30
30
/// the complex type implementation is based on.
31
31
/// - Todo: Implement the `Arithmetic` protocol. This requires that complex numbers are
32
32
/// mutable.
33
- public protocol ComplexNumber : Equatable {
33
+ public protocol ComplexNumber : Hashable ,
34
+ CustomStringConvertible {
34
35
35
36
/// The floating point number type on which this complex number is based.
36
37
associatedtype Float : FloatingPoint
@@ -153,14 +154,29 @@ public struct Complex<T: FloatingPointNumber>: ComplexNumber,
153
154
154
155
/// Creates a complex number with the given real and imaginary parts.
155
156
public init ( _ re: T , _ im: T ) {
156
- self . re = re
157
- self . im = im
157
+ // Normalize complex numbers involving NaN
158
+ if re. isNaN {
159
+ self . re = re
160
+ self . im = T ( 0 )
161
+ } else if im. isNaN {
162
+ self . re = im
163
+ self . im = T ( 0 )
164
+ // Normalize infinite complex numbers
165
+ } else if re. isInfinite {
166
+ self . re = re
167
+ self . im = T ( 0 )
168
+ } else if im. isInfinite { // imaginary parts are never infinity
169
+ self . re = . nan
170
+ self . im = T ( 0 )
171
+ } else {
172
+ self . re = re
173
+ self . im = im
174
+ }
158
175
}
159
176
160
177
/// Creates a complex number from polar coordinates
161
178
public init ( abs: T , arg: T ) {
162
- self . re = abs * arg. cos
163
- self . im = abs * arg. sin
179
+ self . init ( abs * arg. cos, abs * arg. sin)
164
180
}
165
181
166
182
/// Creates a real number initialized to integer `value`.
@@ -175,7 +191,7 @@ public struct Complex<T: FloatingPointNumber>: ComplexNumber,
175
191
176
192
/// Returns a textual representation of this complex number
177
193
public var description : String {
178
- if im. isZero {
194
+ if im. isZero || re . isNaN || re . isInfinite {
179
195
return String ( describing: re)
180
196
} else if re. isZero {
181
197
return String ( describing: im) + " i "
@@ -224,7 +240,9 @@ public struct Complex<T: FloatingPointNumber>: ComplexNumber,
224
240
/// Returns the ∞-norm of this complex number. Use `norm` if the Euclidean norm
225
241
/// is needed.
226
242
public var magnitude : T {
227
- if self . isFinite {
243
+ if self . isNaN {
244
+ return . nan
245
+ } else if self . isFinite {
228
246
return max ( self . re. abs, self . im. abs)
229
247
} else {
230
248
return . infinity
@@ -258,8 +276,16 @@ public struct Complex<T: FloatingPointNumber>: ComplexNumber,
258
276
259
277
/// Returns the reciprocal of this complex number.
260
278
public var reciprocal : Complex < T > {
261
- let s = re * re + im * im
262
- return Complex ( re / s, - im / s)
279
+ if self . isNaN {
280
+ return self
281
+ } else if self . isZero {
282
+ return . infinity
283
+ } else if self . isInfinite {
284
+ return . zero
285
+ } else {
286
+ let s = re * re + im * im
287
+ return Complex ( re / s, - im / s)
288
+ }
263
289
}
264
290
265
291
/// Returns the norm of this complex number.
0 commit comments