@@ -29,55 +29,55 @@ public protocol RationalNumber: SignedNumber,
29
29
ExpressibleByIntegerLiteral ,
30
30
Comparable ,
31
31
Hashable {
32
-
32
+
33
33
/// The integer type on which this rational number is based.
34
34
associatedtype Integer : SignedInteger
35
-
35
+
36
36
/// The numerator of this rational number.
37
37
var numerator : Integer { get }
38
-
38
+
39
39
/// The denominator of this rational number.
40
40
var denominator : Integer { get }
41
-
41
+
42
42
/// Returns the `Rational` as a value of type `Integer` if this is possible. If the number
43
43
/// cannot be expressed as a `Integer`, this property returns `nil`.
44
44
var intValue : Integer ? { get }
45
-
45
+
46
46
/// Returns the `Rational` value as a float value
47
47
var floatValue : Float { get }
48
-
48
+
49
49
/// Returns the `Rational` value as a double value
50
50
var doubleValue : Double { get }
51
-
51
+
52
52
/// Is true if the rational value is negative.
53
53
var isNegative : Bool { get }
54
-
54
+
55
55
/// Is true if the rational value is zero.
56
56
var isZero : Bool { get }
57
-
57
+
58
58
/// The absolute rational value (without sign).
59
59
var abs : Self { get }
60
-
60
+
61
61
/// The negated rational value.
62
62
var negate : Self { get }
63
-
63
+
64
64
/// Returns -1 if `self` is less than `rhs`,
65
65
/// 0 if `self` is equals to `rhs`,
66
66
/// +1 if `self` is greater than `rhs`
67
67
func compare( to rhs: Self ) -> Int
68
-
68
+
69
69
/// Returns the sum of this rational value and `rhs`.
70
70
func plus( _ rhs: Self ) -> Self
71
-
71
+
72
72
/// Returns the difference between this rational value and `rhs`.
73
73
func minus( _ rhs: Self ) -> Self
74
-
74
+
75
75
/// Multiplies this rational value with `rhs` and returns the result.
76
76
func times( _ rhs: Self ) -> Self
77
-
77
+
78
78
/// Divides this rational value by `rhs` and returns the result.
79
79
func divided( by rhs: Self ) -> Self
80
-
80
+
81
81
/// Raises this rational value to the power of `exp`.
82
82
func toPower( of exp: Integer ) -> Self
83
83
}
@@ -93,20 +93,20 @@ private let rationalSeparator: Character = "/"
93
93
/// numerator. The denominator is always positive.
94
94
public struct Rational < T: SignedInteger > : RationalNumber ,
95
95
CustomStringConvertible {
96
-
96
+
97
97
/// The numerator of this rational number. This is a signed integer.
98
98
public let numerator : T
99
-
99
+
100
100
/// The denominator of this rational number. This integer is always positive.
101
101
public let denominator : T
102
-
102
+
103
103
/// Sets numerator and denominator without normalization. This function must not be called
104
104
/// outside of the NumberKit framework.
105
105
fileprivate init ( numerator: T , denominator: T ) {
106
106
self . numerator = numerator
107
107
self . denominator = denominator
108
108
}
109
-
109
+
110
110
/// Creates a rational number from a numerator and a denominator.
111
111
public init ( _ numerator: T , _ denominator: T ) {
112
112
precondition ( denominator != 0 , " rational with zero denominator " )
@@ -117,20 +117,20 @@ public struct Rational<T: SignedInteger>: RationalNumber,
117
117
self . numerator = negative ? - ( anum / div) : ( anum / div)
118
118
self . denominator = adenom / div
119
119
}
120
-
120
+
121
121
/// Creates a `Rational` from the given integer value of type `T`
122
122
public init ( _ value: T ) {
123
123
self . init ( numerator: value, denominator: T ( 1 ) )
124
124
}
125
-
125
+
126
126
/// Create an instance initialized to `value`.
127
127
public init ( integerLiteral value: T ) {
128
128
self . init ( value)
129
129
}
130
-
130
+
131
131
/// Creates a `Rational` from a string containing a rational number using the base
132
132
/// defined by parameter `radix`. The syntax of the rational number is defined as follows:
133
- ///
133
+ ///
134
134
/// Rational = Numerator '/' Denominator
135
135
/// | SignedInteger
136
136
/// Numerator = SignedInteger
@@ -152,7 +152,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
152
152
return nil
153
153
}
154
154
}
155
-
155
+
156
156
/// Returns the `Rational` as a value of type `T` if this is possible. If the number
157
157
/// cannot be expressed as a `T`, this property returns `nil`.
158
158
public var intValue : T ? {
@@ -161,23 +161,23 @@ public struct Rational<T: SignedInteger>: RationalNumber,
161
161
}
162
162
return numerator
163
163
}
164
-
164
+
165
165
/// Returns the `Rational` value as a float value
166
166
public var floatValue : Float {
167
167
return Float ( doubleValue)
168
168
}
169
-
169
+
170
170
/// Returns the `Rational` value as a double value
171
171
public var doubleValue : Double {
172
172
return Double ( numerator. toIntMax ( ) ) / Double( denominator. toIntMax ( ) )
173
173
}
174
-
174
+
175
175
/// Returns a string representation of this `Rational<T>` number using base 10.
176
176
public var description : String {
177
177
return denominator == 1 ? numerator. description
178
178
: numerator. description + String( rationalSeparator) + denominator. description
179
179
}
180
-
180
+
181
181
/// Compute the greatest common divisor for `x` and `y`.
182
182
public static func gcd( _ x: T , _ y: T ) -> T {
183
183
var ( x, y, rest) = ( x, y, x % y)
@@ -188,7 +188,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
188
188
}
189
189
return y
190
190
}
191
-
191
+
192
192
/// Compute the least common multiplier of `x` and `y`.
193
193
public static func lcm( _ x: T , _ y: T ) -> T {
194
194
var abs = x * y
@@ -197,7 +197,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
197
197
}
198
198
return abs / Rational. gcd ( x, y)
199
199
}
200
-
200
+
201
201
/// Determine the smallest common denominator between `self` and `other` and return
202
202
/// the corresponding numerators and the common denominator.
203
203
private func commonDenomWith( _ other: Rational < T > ) -> ( num1: T , num2: T , denom: T ) {
@@ -206,73 +206,77 @@ public struct Rational<T: SignedInteger>: RationalNumber,
206
206
let t2 = other. denominator / div
207
207
return ( self . numerator * t2, other. numerator * t1, t1 * t2 * div)
208
208
}
209
-
209
+
210
210
/// The hash value of this rational value.
211
211
public var hashValue : Int {
212
212
return 31 &* denominator. hashValue &+ numerator. hashValue
213
213
}
214
-
214
+
215
215
/// The absolute rational value (without sign).
216
216
public var abs : Rational < T > {
217
217
return Rational ( numerator < 0 ? - numerator : numerator, denominator)
218
218
}
219
-
219
+
220
220
/// The negated rational value.
221
221
public var negate : Rational < T > {
222
222
return Rational ( - numerator, denominator)
223
223
}
224
-
224
+
225
225
/// Is true if the rational value is negative.
226
226
public var isNegative : Bool {
227
227
return numerator < 0
228
228
}
229
-
229
+
230
230
/// Is true if the rational value is zero.
231
231
public var isZero : Bool {
232
232
return numerator == 0
233
233
}
234
-
234
+
235
235
/// Returns -1 if `self` is less than `rhs`,
236
236
/// 0 if `self` is equals to `rhs`,
237
237
/// +1 if `self` is greater than `rhs`
238
238
public func compare( to rhs: Rational < T > ) -> Int {
239
239
let ( n1, n2, _) = self . commonDenomWith ( rhs)
240
240
return n1 == n2 ? 0 : ( n1 < n2 ? - 1 : 1 )
241
241
}
242
-
242
+
243
243
/// Returns the sum of this rational value and `rhs`.
244
244
public func plus( _ rhs: Rational < T > ) -> Rational < T > {
245
245
let ( n1, n2, denom) = self . commonDenomWith ( rhs)
246
246
return Rational ( n1 + n2, denom)
247
247
}
248
-
248
+
249
249
/// Returns the difference between this rational value and `rhs`.
250
250
public func minus( _ rhs: Rational < T > ) -> Rational < T > {
251
251
let ( n1, n2, denom) = self . commonDenomWith ( rhs)
252
252
return Rational ( n1 - n2, denom)
253
253
}
254
-
254
+
255
255
/// Multiplies this rational value with `rhs` and returns the result.
256
256
public func times( _ rhs: Rational < T > ) -> Rational < T > {
257
257
return Rational ( self . numerator * rhs. numerator, self . denominator * rhs. denominator)
258
258
}
259
-
259
+
260
260
/// Divides this rational value by `rhs` and returns the result.
261
261
public func divided( by rhs: Rational < T > ) -> Rational < T > {
262
262
return Rational ( self . numerator * rhs. denominator, self . denominator * rhs. numerator)
263
263
}
264
264
265
265
/// Raises this rational value to the power of `exp`.
266
266
public func toPower( of exp: T ) -> Rational < T > {
267
- return Rational ( pow ( numerator, exp) , pow ( denominator, exp) )
267
+ if ( exp < 0 ) {
268
+ return Rational ( pow ( denominator, - exp) , pow ( numerator, - exp) )
269
+ } else {
270
+ return Rational ( pow ( numerator, exp) , pow ( denominator, exp) )
271
+ }
268
272
}
269
-
273
+
270
274
/// Returns the greatest common denominator for the two given rational numbers
271
275
public static func gcd( _ x: Rational < T > , _ y: Rational < T > ) -> Rational < T > {
272
276
return Rational ( Rational . gcd ( x. numerator, y. numerator) ,
273
277
Rational . lcm ( x. denominator, y. denominator) )
274
278
}
275
-
279
+
276
280
/// Returns the least common multiplier for the two given rational numbers
277
281
public static func lcm( _ x: Rational < T > , _ y: Rational < T > ) -> Rational < T > {
278
282
let ( xn, yn, denom) = x. commonDenomWith ( y)
@@ -293,21 +297,21 @@ extension Rational: ExpressibleByStringLiteral {
293
297
self . init ( 0 )
294
298
}
295
299
}
296
-
300
+
297
301
public init ( extendedGraphemeClusterLiteral value: String ) {
298
302
self . init ( stringLiteral: value)
299
303
}
300
-
304
+
301
305
public init ( unicodeScalarLiteral value: String ) {
302
306
self . init ( stringLiteral: value)
303
307
}
304
-
308
+
305
309
/// Compute absolute number of `num` and return a tuple consisting of the result and a
306
310
/// boolean indicating whether there was an overflow.
307
311
private static func absWithOverflow( _ num: T ) -> ( T , Bool ) {
308
312
return num < 0 ? T . subtractWithOverflow ( 0 , num) : ( num, false )
309
313
}
310
-
314
+
311
315
/// Creates a rational number from a numerator and a denominator.
312
316
public static func rationalWithOverflow( _ numerator: T , _ denominator: T )
313
317
-> ( Rational < T > , Bool ) {
@@ -324,7 +328,7 @@ extension Rational: ExpressibleByStringLiteral {
324
328
return ( Rational ( numerator: numer, denominator: denom) ,
325
329
overflow1 || overflow2 || overflow3 || overflow4 || overflow5)
326
330
}
327
-
331
+
328
332
/// Compute the smalles common denominator of `this` and `that` and return it together
329
333
/// with the corresponding numerators.
330
334
private static func commonDenomWithOverflow( _ this: Rational < T > , _ that: Rational < T > )
@@ -338,7 +342,7 @@ extension Rational: ExpressibleByStringLiteral {
338
342
let ( dn, overflow4) = T . multiplyWithOverflow ( dp, div)
339
343
return ( n1, n2, dn, overflow1 || overflow2 || overflow3 || overflow4)
340
344
}
341
-
345
+
342
346
/// Add `lhs` and `rhs` and return a tuple consisting of the result and a boolean which
343
347
/// indicates whether there was an overflow.
344
348
public static func addWithOverflow( _ lhs: Rational < T > , _ rhs: Rational < T > )
@@ -348,7 +352,7 @@ extension Rational: ExpressibleByStringLiteral {
348
352
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
349
353
return ( res, overflow1 || overflow2 || overflow3)
350
354
}
351
-
355
+
352
356
/// Subtract `rhs` from `lhs` and return a tuple consisting of the result and a boolean which
353
357
/// indicates whether there was an overflow.
354
358
public static func subtractWithOverflow( _ lhs: Rational < T > , _ rhs: Rational < T > )
@@ -358,7 +362,7 @@ extension Rational: ExpressibleByStringLiteral {
358
362
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
359
363
return ( res, overflow1 || overflow2 || overflow3)
360
364
}
361
-
365
+
362
366
/// Multiply `lhs` and `rhs` and return a tuple consisting of the result and a boolean which
363
367
/// indicates whether there was an overflow.
364
368
public static func multiplyWithOverflow( _ lhs: Rational < T > , _ rhs: Rational < T > )
@@ -368,7 +372,7 @@ extension Rational: ExpressibleByStringLiteral {
368
372
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
369
373
return ( res, overflow1 || overflow2 || overflow3)
370
374
}
371
-
375
+
372
376
/// Divide `lhs` by `rhs` and return a tuple consisting of the result and a boolean which
373
377
/// indicates whether there was an overflow.
374
378
public static func divideWithOverflow( _ lhs: Rational < T > , _ rhs: Rational < T > )
@@ -378,7 +382,7 @@ extension Rational: ExpressibleByStringLiteral {
378
382
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
379
383
return ( res, overflow1 || overflow2 || overflow3)
380
384
}
381
-
385
+
382
386
/// Compute the greatest common divisor for `x` and `y`.
383
387
public static func gcdWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
384
388
var ( x, y, ( rest, overflow) ) = ( x, y, T . remainderWithOverflow ( x, y) )
@@ -391,22 +395,22 @@ extension Rational: ExpressibleByStringLiteral {
391
395
}
392
396
return ( y, overflow)
393
397
}
394
-
398
+
395
399
/// Compute the least common multiplier of `x` and `y`.
396
400
public static func lcmWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
397
401
let ( abs, overflow1) = T . multiplyWithOverflow ( x, y)
398
402
let ( gcd, overflow2) = Rational . gcdWithOverflow ( x, y)
399
403
return ( ( abs < 0 ? - abs : abs) / gcd, overflow1 || overflow2)
400
404
}
401
-
405
+
402
406
/// Returns the greatest common denominator for the two given rational numbers and a boolean
403
407
/// which indicates whether there was an overflow.
404
408
public static func gcdWithOverflow( _ x: Rational < T > , _ y: Rational < T > ) -> ( Rational < T > , Bool ) {
405
409
let ( numer, overflow1) = Rational . gcdWithOverflow ( x. numerator, y. numerator)
406
410
let ( denom, overflow2) = Rational . lcmWithOverflow ( x. denominator, y. denominator)
407
411
return ( Rational ( numer, denom) , overflow1 || overflow2)
408
412
}
409
-
413
+
410
414
/// Returns the least common multiplier for the two given rational numbers and a boolean
411
415
/// which indicates whether there was an overflow.
412
416
public static func lcmWithOverflow( _ x: Rational < T > , _ y: Rational < T > ) -> ( Rational < T > , Bool ) {
0 commit comments