@@ -79,11 +79,31 @@ public protocol RationalNumber: SignedNumeric,
79
79
80
80
/// Raises this rational value to the power of `exp`.
81
81
func toPower( of exp: Integer ) -> Self
82
+
83
+ /// Adds `rhs` to `self` and reports the result together with a boolean indicating an overflow.
84
+ func addingReportingOverflow( _ rhs: Self ) -> ( partialValue: Self , overflow: Bool )
85
+
86
+ /// Subtracts `rhs` from `self` and reports the result together with a boolean indicating
87
+ /// an overflow.
88
+ func subtractingReportingOverflow( _ rhs: Self ) -> ( partialValue: Self , overflow: Bool )
89
+
90
+ /// Multiplies `rhs` with `self` and reports the result together with a boolean indicating
91
+ /// an overflow.
92
+ func multipliedReportingOverflow( by rhs: Self ) -> ( partialValue: Self , overflow: Bool )
93
+
94
+ /// Divides `self` by `rhs` and reports the result together with a boolean indicating
95
+ /// an overflow.
96
+ func dividedReportingOverflow( by rhs: Self ) -> ( partialValue: Self , overflow: Bool )
97
+
98
+ /// Returns the greatest common denominator for `self` and `y` and a boolean which indicates
99
+ /// whether there was an overflow.
100
+ func gcdReportingOverflow( with y: Self ) -> ( partialValue: Self , overflow: Bool )
101
+
102
+ /// Returns the least common multiplier for `self` and `y` and a boolean which indicates
103
+ /// whether there was an overflow.
104
+ func lcmReportingOverflow( with y: Self ) -> ( partialValue: Self , overflow: Bool )
82
105
}
83
106
84
- // TODO: make this a static member of `Rational` once this is supported
85
- private let rationalSeparator : Character = " / "
86
-
87
107
88
108
/// Struct `Rational<T>` implements the `RationalNumber` interface on top of the
89
109
/// integer type `T`. `Rational<T>` always represents rational numbers in normalized
@@ -354,79 +374,81 @@ extension Rational: ExpressibleByStringLiteral {
354
374
let ( dn, overflow4) = dp. multipliedReportingOverflow ( by: div)
355
375
return ( n1, n2, dn, overflow1 || overflow2 || overflow3 || overflow4)
356
376
}
357
-
358
- /// Add `lhs` and `rhs` and return a tuple consisting of the result and a boolean which
377
+
378
+ /// Compute the greatest common divisor for `x` and `y`.
379
+ public static func gcdWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
380
+ var ( x, y, ( rest, overflow) ) = ( x, y, x. remainderReportingOverflow ( dividingBy: y) )
381
+ while rest > 0 {
382
+ x = y
383
+ y = rest
384
+ let ( rem, overflow1) = x. remainderReportingOverflow ( dividingBy: y)
385
+ rest = rem
386
+ overflow = overflow || overflow1
387
+ }
388
+ return ( y, overflow)
389
+ }
390
+
391
+ /// Compute the least common multiplier of `x` and `y`.
392
+ public static func lcmWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
393
+ let ( abs, overflow1) = x. multipliedReportingOverflow ( by: y)
394
+ let ( gcd, overflow2) = Rational . gcdWithOverflow ( x, y)
395
+ return ( ( abs < 0 ? - abs : abs) / gcd, overflow1 || overflow2)
396
+ }
397
+
398
+ /// Add `self` and `rhs` and return a tuple consisting of the result and a boolean which
359
399
/// indicates whether there was an overflow.
360
- public static func addWithOverflow ( _ lhs : Rational < T > , _ rhs: Rational < T > )
361
- -> ( Rational < T > , Bool ) {
362
- let ( n1, n2, denom, overflow1) = Rational . commonDenomWithOverflow ( lhs , rhs)
400
+ public func addingReportingOverflow ( _ rhs: Rational < T > )
401
+ -> ( partialValue : Rational < T > , overflow : Bool ) {
402
+ let ( n1, n2, denom, overflow1) = Rational . commonDenomWithOverflow ( self , rhs)
363
403
let ( numer, overflow2) = n1. addingReportingOverflow ( n2)
364
404
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
365
405
return ( res, overflow1 || overflow2 || overflow3)
366
406
}
367
-
368
- /// Subtract `rhs` from `lhs ` and return a tuple consisting of the result and a boolean which
407
+
408
+ /// Subtract `rhs` from `self ` and return a tuple consisting of the result and a boolean which
369
409
/// indicates whether there was an overflow.
370
- public static func subtractWithOverflow ( _ lhs : Rational < T > , _ rhs: Rational < T > )
371
- -> ( Rational < T > , Bool ) {
372
- let ( n1, n2, denom, overflow1) = Rational . commonDenomWithOverflow ( lhs , rhs)
410
+ public func subtractingReportingOverflow ( _ rhs: Rational < T > )
411
+ -> ( partialValue : Rational < T > , overflow : Bool ) {
412
+ let ( n1, n2, denom, overflow1) = Rational . commonDenomWithOverflow ( self , rhs)
373
413
let ( numer, overflow2) = n1. subtractingReportingOverflow ( n2)
374
414
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
375
415
return ( res, overflow1 || overflow2 || overflow3)
376
416
}
377
-
378
- /// Multiply `lhs ` and `rhs` and return a tuple consisting of the result and a boolean which
417
+
418
+ /// Multiply `self ` and `rhs` and return a tuple consisting of the result and a boolean which
379
419
/// indicates whether there was an overflow.
380
- public static func multiplyWithOverflow ( _ lhs : Rational < T > , _ rhs: Rational < T > )
381
- -> ( Rational < T > , Bool ) {
382
- let ( numer, overflow1) = lhs . numerator. multipliedReportingOverflow ( by: rhs. numerator)
383
- let ( denom, overflow2) = lhs . denominator. multipliedReportingOverflow ( by: rhs. denominator)
420
+ public func multipliedReportingOverflow ( by rhs: Rational < T > )
421
+ -> ( partialValue : Rational < T > , overflow : Bool ) {
422
+ let ( numer, overflow1) = self . numerator. multipliedReportingOverflow ( by: rhs. numerator)
423
+ let ( denom, overflow2) = self . denominator. multipliedReportingOverflow ( by: rhs. denominator)
384
424
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
385
425
return ( res, overflow1 || overflow2 || overflow3)
386
426
}
387
427
388
428
/// Divide `lhs` by `rhs` and return a tuple consisting of the result and a boolean which
389
429
/// indicates whether there was an overflow.
390
- public static func divideWithOverflow ( _ lhs : Rational < T > , _ rhs: Rational < T > )
391
- -> ( Rational < T > , Bool ) {
392
- let ( numer, overflow1) = lhs . numerator. multipliedReportingOverflow ( by: rhs. denominator)
393
- let ( denom, overflow2) = lhs . denominator. multipliedReportingOverflow ( by: rhs. numerator)
430
+ public func dividedReportingOverflow ( by rhs: Rational < T > )
431
+ -> ( partialValue : Rational < T > , overflow : Bool ) {
432
+ let ( numer, overflow1) = self . numerator. multipliedReportingOverflow ( by: rhs. denominator)
433
+ let ( denom, overflow2) = self . denominator. multipliedReportingOverflow ( by: rhs. numerator)
394
434
let ( res, overflow3) = Rational . rationalWithOverflow ( numer, denom)
395
435
return ( res, overflow1 || overflow2 || overflow3)
396
436
}
397
-
398
- /// Compute the greatest common divisor for `x` and `y`.
399
- public static func gcdWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
400
- var ( x, y, ( rest, overflow) ) = ( x, y, x. remainderReportingOverflow ( dividingBy: y) )
401
- while rest > 0 {
402
- x = y
403
- y = rest
404
- let ( rem, overflow1) = x. remainderReportingOverflow ( dividingBy: y)
405
- rest = rem
406
- overflow = overflow || overflow1
407
- }
408
- return ( y, overflow)
409
- }
410
-
411
- /// Compute the least common multiplier of `x` and `y`.
412
- public static func lcmWithOverflow( _ x: T , _ y: T ) -> ( T , Bool ) {
413
- let ( abs, overflow1) = x. multipliedReportingOverflow ( by: y)
414
- let ( gcd, overflow2) = Rational . gcdWithOverflow ( x, y)
415
- return ( ( abs < 0 ? - abs : abs) / gcd, overflow1 || overflow2)
416
- }
417
-
418
- /// Returns the greatest common denominator for the two given rational numbers and a boolean
419
- /// which indicates whether there was an overflow.
420
- public static func gcdWithOverflow( _ x: Rational < T > , _ y: Rational < T > ) -> ( Rational < T > , Bool ) {
421
- let ( numer, overflow1) = Rational . gcdWithOverflow ( x. numerator, y. numerator)
422
- let ( denom, overflow2) = Rational . lcmWithOverflow ( x. denominator, y. denominator)
437
+
438
+ /// Returns the greatest common denominator for `self` and `y` and a boolean which indicates
439
+ /// whether there was an overflow.
440
+ public func gcdReportingOverflow( with y: Rational < T > )
441
+ -> ( partialValue: Rational < T > , overflow: Bool ) {
442
+ let ( numer, overflow1) = Rational . gcdWithOverflow ( self . numerator, y. numerator)
443
+ let ( denom, overflow2) = Rational . lcmWithOverflow ( self . denominator, y. denominator)
423
444
return ( Rational ( numer, denom) , overflow1 || overflow2)
424
445
}
425
-
426
- /// Returns the least common multiplier for the two given rational numbers and a boolean
427
- /// which indicates whether there was an overflow.
428
- public static func lcmWithOverflow( _ x: Rational < T > , _ y: Rational < T > ) -> ( Rational < T > , Bool ) {
429
- let ( xn, yn, denom, overflow1) = Rational . commonDenomWithOverflow ( x, y)
446
+
447
+ /// Returns the least common multiplier for `self` and `y` and a boolean which indicates
448
+ /// whether there was an overflow.
449
+ public func lcmReportingOverflow( with y: Rational < T > )
450
+ -> ( partialValue: Rational < T > , overflow: Bool ) {
451
+ let ( xn, yn, denom, overflow1) = Rational . commonDenomWithOverflow ( self , y)
430
452
let ( numer, overflow2) = Rational . lcmWithOverflow ( xn, yn)
431
453
return ( Rational ( numer, denom) , overflow1 || overflow2)
432
454
}
@@ -492,6 +514,21 @@ public func **= <R: RationalNumber>(lhs: inout R, exp: R.Integer) {
492
514
lhs = lhs. toPower ( of: exp)
493
515
}
494
516
517
+ /// Returns the sum of `lhs` and `rhs`.
518
+ public func &+ < R: RationalNumber > ( lhs: R , rhs: R ) -> R {
519
+ return lhs. addingReportingOverflow ( rhs) . partialValue
520
+ }
521
+
522
+ /// Returns the difference between `lhs` and `rhs`.
523
+ public func &- < R: RationalNumber > ( lhs: R , rhs: R ) -> R {
524
+ return lhs. subtractingReportingOverflow ( rhs) . partialValue
525
+ }
526
+
527
+ /// Multiplies `lhs` with `rhs` and returns the result.
528
+ public func &* < R: RationalNumber > ( lhs: R , rhs: R ) -> R {
529
+ return lhs. multipliedReportingOverflow ( by: rhs) . partialValue
530
+ }
531
+
495
532
/// Returns true if `lhs` is less than `rhs`, false otherwise.
496
533
public func < < R: RationalNumber > ( lhs: R , rhs: R ) -> Bool {
497
534
return lhs. compare ( to: rhs) < 0
@@ -522,3 +559,5 @@ public func != <R: RationalNumber>(lhs: R, rhs: R) -> Bool {
522
559
return lhs. compare ( to: rhs) != 0
523
560
}
524
561
562
+ // TODO: make this a static member of `Rational` once this is supported
563
+ private let rationalSeparator : Character = " / "
0 commit comments