-
Notifications
You must be signed in to change notification settings - Fork 6
/
Math.swift
491 lines (427 loc) · 14.4 KB
/
Math.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
//
// Math.swift
// NumericAnnex
//
// Created by Xiaodi Wu on 3/31/17.
//
/// A signed numeric type that supports elementary functions.
///
/// The `Math` protocol provides a suitable basis for writing functions that
/// work on any real or complex floating-point type that supports the required
/// functions.
public protocol Math : SignedNumeric {
/// The mathematical constant pi (π).
///
/// This value should be rounded toward zero to keep user computations with
/// angles from inadvertently ending up in the wrong quadrant. A type that
/// conforms to the `Math` protocol provides the value for `pi` at its best
/// possible precision.
static var pi: Self { get }
/// The mathematical constant _e_, or Euler's number.
static var e: Self { get }
/// The mathematical constant phi (φ), or golden ratio.
static var phi: Self { get }
/// Returns the quotient obtained by dividing the first value by the second,
/// rounded to a representable value.
///
/// - Parameters:
/// - lhs: The value to divide.
/// - rhs: The value by which to divide `lhs`.
static func / (lhs: Self, rhs: Self) -> Self
/// Divides the left-hand side by the right-hand side and stores the quotient
/// in the left-hand side, rounded to a representable value.
///
/// - Parameters:
/// - lhs: The value to divide.
/// - rhs: The value by which to divide `lhs`.
static func /= (lhs: inout Self, rhs: Self)
/// Returns the result of raising the first value to the power of the second,
/// rounded to a representable value.
///
/// - Parameters:
/// - lhs: The value to be raised to the power of `rhs`.
/// - rhs: The value by which to raise `lhs`.
static func ** (lhs: Self, rhs: Self) -> Self
/// Raises the left-hand side to the power of the right-hand side and stores
/// the result in the left-hand side, rounded to a representable value.
///
/// - Parameters:
/// - lhs: The value to be raised to the power of `rhs`.
/// - rhs: The value by which to raise `lhs`.
static func **= (lhs: inout Self, rhs: Self)
/// Returns the natural exponential of the value, rounded to a representable
/// value.
///
/// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the
/// power of `x`.
///
/// - SeeAlso: `exp(_:)`
func naturalExponential() -> Self
/// Returns the binary exponential of the value, rounded to a representable
/// value.
///
/// The binary exponential of a value `x` is 2 raised to the power of `x`.
///
/// - SeeAlso: `exp2(_:)`
func binaryExponential() -> Self
/// Returns the common exponential of the value, rounded to a representable
/// value.
///
/// The common exponential of a value `x` is 10 raised to the power of `x`.
///
/// - SeeAlso: `exp10(_:)`
func commonExponential() -> Self
/// Returns the result of subtracting one from the natural exponential of the
/// value, rounded to a representable value.
///
/// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the
/// power of `x`.
///
/// This function is more accurate than `x.naturalExponential() - 1` for
/// values of `x` close to zero.
///
/// - SeeAlso: `expm1(_:)`
func naturalExponentialMinusOne() -> Self
/// Returns the natural (base _e_) logarithm of the value, rounded to a
/// representable value.
///
/// - SeeAlso: `log(_:)`
func naturalLogarithm() -> Self
/// Returns the binary (base 2) logarithm of the value, rounded to a
/// representable value.
///
/// - SeeAlso: `log2(_:)`
func binaryLogarithm() -> Self
/// Returns the common (base 10) logarithm of the value, rounded to a
/// representable value.
///
/// - SeeAlso: `log10(_:)`
func commonLogarithm() -> Self
/// Returns the natural (base _e_) logarithm of the result of adding one to
/// the value, rounded to a representable value.
///
/// - SeeAlso: `log1p(_:)`
func naturalLogarithmOnePlus() -> Self
/// Returns the square root of the value, rounded to a representable value.
///
/// - SeeAlso: `sqrt(_:)`
func squareRoot() -> Self
/// Returns the cube root of the value, rounded to a representable value.
///
/// - SeeAlso: `cbrt(_:)`
func cubeRoot() -> Self
/// Returns the sine of the value (given in radians), rounded to a
/// representable value.
///
/// - SeeAlso: `sin(_:)`
func sine() -> Self
/// Returns the cosine of the value (given in radians), rounded to a
/// representable value.
///
/// - SeeAlso: `cos(_:)`
func cosine() -> Self
/// Returns the tangent of the value (given in radians), rounded to a
/// representable value.
///
/// - SeeAlso: `tan(_:)`
func tangent() -> Self
/// Returns the principal value of the inverse sine of the value, rounded to a
/// representable value.
///
/// - SeeAlso: `asin(_:)`
func inverseSine() -> Self
/// Returns the principal value of the inverse cosine of the value, rounded to
/// a representable value.
///
/// - SeeAlso: `acos(_:)`
func inverseCosine() -> Self
/// Returns the principal value of the inverse tangent of the value, rounded
/// to a representable value.
///
/// - SeeAlso: `atan(_:)`
func inverseTangent() -> Self
/// Returns the hyperbolic sine of the value, rounded to a representable
/// value.
///
/// - SeeAlso: `sinh(_:)`
func hyperbolicSine() -> Self
/// Returns the hyperbolic cosine of the value, rounded to a representable
/// value.
///
/// - SeeAlso: `cosh(_:)`
func hyperbolicCosine() -> Self
/// Returns the hyperbolic tangent of the value, rounded to a representable
/// value.
///
/// - SeeAlso: `tanh(_:)`
func hyperbolicTangent() -> Self
/// Returns the principal value of the inverse hyperbolic sine of the value,
/// rounded to a representable value.
///
/// - SeeAlso: `asinh(_:)`
func inverseHyperbolicSine() -> Self
/// Returns the principal value of the inverse hyperbolic cosine of the value,
/// rounded to a representable value.
///
/// - SeeAlso: `acosh(_:)`
func inverseHyperbolicCosine() -> Self
/// Returns the principal value of the inverse hyperbolic tangent of the
/// value, rounded to a representable value.
///
/// - SeeAlso: `atanh(_:)`
func inverseHyperbolicTangent() -> Self
}
extension Math {
/// The mathematical constant _e_, or Euler's number (default implementation).
public static var e: Self {
return Self.exp(1 as Self)
}
/// The mathematical constant phi (φ), or golden ratio (default
/// implementation).
public static var phi: Self {
return ((1 as Self) + Self.sqrt(5 as Self)) / (2 as Self)
}
#if false
/// Returns the quotient obtained by dividing the first value by the second,
/// rounded to a representable value (default implementation).
///
/// - Parameters:
/// - lhs: The value to divide.
/// - rhs: The value by which to divide `lhs`.
@_transparent
public static func / (lhs: Self, rhs: Self) -> Self {
var lhs = lhs
lhs /= rhs
return lhs
}
/// Returns the result of raising the first value to the power of the second,
/// rounded to a representable value (default implementation).
///
/// - Parameters:
/// - lhs: The value to be raised to the power of `rhs`.
/// - rhs: The value by which to raise `lhs`.
@_transparent
public static func ** (lhs: Self, rhs: Self) -> Self {
var lhs = lhs
lhs **= rhs
return lhs
}
#endif
public func binaryExponential() -> Self {
return Self.exp(self * Self.log(2 as Self))
}
public func commonExponential() -> Self {
return Self.exp(self * Self.log(10 as Self))
}
public func naturalExponentialMinusOne() -> Self {
return Self.exp(self) - (1 as Self)
}
public func binaryLogarithm() -> Self {
return Self.log(self) / Self.log(2 as Self)
}
public func commonLogarithm() -> Self {
return Self.log(self) / Self.log(10 as Self)
}
public func naturalLogarithmOnePlus() -> Self {
return Self.log(self + (1 as Self))
}
public func tangent() -> Self {
return sine() / cosine()
}
public func hyperbolicTangent() -> Self {
return hyperbolicSine() / hyperbolicCosine()
}
}
extension Math {
/// Returns the result of raising `base` to the power of `exponent`, rounded
/// to a representable value (deprecated).
///
/// - Parameters:
/// - base: The base to be raised to the power of `exponent`.
/// - exponent: The exponent by which to raise `base`.
@available(*, deprecated, message: "Use operator instead")
public static func pow(_ base: Self, _ exponent: Self) -> Self {
return base ** exponent
}
/// Returns the natural exponential of `x`, rounded to a representable value.
///
/// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the
/// power of `x`.
///
/// - SeeAlso: `naturalExponential()`
@_transparent // @_inlineable
public static func exp(_ x: Self) -> Self {
return x.naturalExponential()
}
/// Returns the binary exponential of `x`, rounded to a representable value.
///
/// The binary exponential of a value `x` is 2 raised to the power of `x`.
///
/// - SeeAlso: `binaryExponential()`
@_transparent // @_inlineable
public static func exp2(_ x: Self) -> Self {
return x.binaryExponential()
}
/// Returns the common exponential of `x`, rounded to a representable value.
///
/// The common exponential of a value `x` is 10 raised to the power of `x`.
///
/// - SeeAlso: `commonExponential()`
@_transparent // @_inlineable
public static func exp10(_ x: Self) -> Self {
return x.commonExponential()
}
/// Returns the result of subtracting one from the natural exponential of `x`,
/// rounded to a representable value.
///
/// The natural exponential of a value `x` is _e_ (2.7182818...) raised to the
/// power of `x`.
///
/// This function is more accurate than `.exp(x) - 1` for values of `x` close
/// to zero.
///
/// - SeeAlso: `naturalExponentialMinusOne()`
@_transparent // @_inlineable
public static func expm1(_ x: Self) -> Self {
return x.naturalExponentialMinusOne()
}
/// Returns the natural (base _e_) logarithm of `x`, rounded to a
/// representable value.
///
/// - SeeAlso: `naturalLogarithm()`
@_transparent // @_inlineable
public static func log(_ x: Self) -> Self {
return x.naturalLogarithm()
}
/// Returns the binary (base 2) logarithm of `x`, rounded to a representable
/// value.
///
/// - SeeAlso: `binaryLogarithm()`
@_transparent // @_inlineable
public static func log2(_ x: Self) -> Self {
return x.binaryLogarithm()
}
/// Returns the common (base 10) logarithm of `x`, rounded to a representable
/// value.
///
/// - SeeAlso: `commonLogarithm()`
@_transparent // @_inlineable
public static func log10(_ x: Self) -> Self {
return x.commonLogarithm()
}
/// Returns the natural (base _e_) logarithm of the result of adding one to
/// `x`, rounded to a representable value.
///
/// - SeeAlso: `naturalLogarithmOnePlus()`
@_transparent // @_inlineable
public static func log1p(_ x: Self) -> Self {
return x.naturalLogarithmOnePlus()
}
/// Returns the square root of `x`, rounded to a representable value.
///
/// - SeeAlso: `squareRoot()`
@_transparent // @_inlineable
public static func sqrt(_ x: Self) -> Self {
return x.squareRoot()
}
/// Returns the cube root of `x`, rounded to a representable value.
///
/// - SeeAlso: `cubeRoot()`
@_transparent // @_inlineable
public static func cbrt(_ x: Self) -> Self {
return x.cubeRoot()
}
/// Returns the sine of `x` (given in radians), rounded to a representable
/// value.
///
/// - SeeAlso: `sine()`
@_transparent // @_inlineable
public static func sin(_ x: Self) -> Self {
return x.sine()
}
/// Returns the cosine of `x` (given in radians), rounded to a representable
/// value.
///
/// - SeeAlso: `cosine()`
@_transparent // @_inlineable
public static func cos(_ x: Self) -> Self {
return x.cosine()
}
/// Returns the tangent of `x` (given in radians), rounded to a representable
/// value.
///
/// - SeeAlso: `tangent()`
@_transparent // @_inlineable
public static func tan(_ x: Self) -> Self {
return x.tangent()
}
/// Returns the principal value of the inverse sine of `x`, rounded to a
/// representable value.
///
/// - SeeAlso: `inverseSine()`
@_transparent // @_inlineable
public static func asin(_ x: Self) -> Self {
return x.inverseSine()
}
/// Returns the principal value of the inverse cosine of `x`, rounded to a
/// representable value.
///
/// - SeeAlso: `inverseCosine()`
@_transparent // @_inlineable
public static func acos(_ x: Self) -> Self {
return x.inverseCosine()
}
/// Returns the principal value of the inverse tangent of `x`, rounded to a
/// representable value.
///
/// - SeeAlso: `inverseTangent()`
@_transparent // @_inlineable
public static func atan(_ x: Self) -> Self {
return x.inverseTangent()
}
/// Returns the hyperbolic sine of `x`, rounded to a representable value.
///
/// - SeeAlso: `hyperbolicSine()`
@_transparent // @_inlineable
public static func sinh(_ x: Self) -> Self {
return x.hyperbolicSine()
}
/// Returns the hyperbolic cosine of `x`, rounded to a representable value.
///
/// - SeeAlso: `hyperbolicCosine()`
@_transparent // @_inlineable
public static func cosh(_ x: Self) -> Self {
return x.hyperbolicCosine()
}
/// Returns the hyperbolic tangent of `x`, rounded to a representable value.
///
/// - SeeAlso: `hyperbolicTangent()`
@_transparent // @_inlineable
public static func tanh(_ x: Self) -> Self {
return x.hyperbolicTangent()
}
/// Returns the principal value of the inverse hyperbolic sine of `x`, rounded
/// to a representable value.
///
/// - SeeAlso: `inverseHyperbolicSine()`
@_transparent // @_inlineable
public static func asinh(_ x: Self) -> Self {
return x.inverseHyperbolicSine()
}
/// Returns the principal value of the inverse hyperbolic cosine of `x`,
/// rounded to a representable value.
///
/// - SeeAlso: `inverseHyperbolicCosine()`
@_transparent // @_inlineable
public static func acosh(_ x: Self) -> Self {
return x.inverseHyperbolicCosine()
}
/// Returns the principal value of the inverse hyperbolic tangent of `x`,
/// rounded to a representable value.
///
/// - SeeAlso: `inverseHyperbolicTangent()`
@_transparent // @_inlineable
public static func atanh(_ x: Self) -> Self {
return x.inverseHyperbolicTangent()
}
}