Skip to content

Commit 314a95e

Browse files
authored
Merge pull request #7 from thSoft/master
Make Rational.toPower(of exp: T) work with negative exponents.
2 parents a58424c + 72aedda commit 314a95e

File tree

1 file changed

+61
-57
lines changed

1 file changed

+61
-57
lines changed

Sources/NumberKit/Rational.swift

Lines changed: 61 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -29,55 +29,55 @@ public protocol RationalNumber: SignedNumber,
2929
ExpressibleByIntegerLiteral,
3030
Comparable,
3131
Hashable {
32-
32+
3333
/// The integer type on which this rational number is based.
3434
associatedtype Integer: SignedInteger
35-
35+
3636
/// The numerator of this rational number.
3737
var numerator: Integer { get }
38-
38+
3939
/// The denominator of this rational number.
4040
var denominator: Integer { get }
41-
41+
4242
/// Returns the `Rational` as a value of type `Integer` if this is possible. If the number
4343
/// cannot be expressed as a `Integer`, this property returns `nil`.
4444
var intValue: Integer? { get }
45-
45+
4646
/// Returns the `Rational` value as a float value
4747
var floatValue: Float { get }
48-
48+
4949
/// Returns the `Rational` value as a double value
5050
var doubleValue: Double { get }
51-
51+
5252
/// Is true if the rational value is negative.
5353
var isNegative: Bool { get }
54-
54+
5555
/// Is true if the rational value is zero.
5656
var isZero: Bool { get }
57-
57+
5858
/// The absolute rational value (without sign).
5959
var abs: Self { get }
60-
60+
6161
/// The negated rational value.
6262
var negate: Self { get }
63-
63+
6464
/// Returns -1 if `self` is less than `rhs`,
6565
/// 0 if `self` is equals to `rhs`,
6666
/// +1 if `self` is greater than `rhs`
6767
func compare(to rhs: Self) -> Int
68-
68+
6969
/// Returns the sum of this rational value and `rhs`.
7070
func plus(_ rhs: Self) -> Self
71-
71+
7272
/// Returns the difference between this rational value and `rhs`.
7373
func minus(_ rhs: Self) -> Self
74-
74+
7575
/// Multiplies this rational value with `rhs` and returns the result.
7676
func times(_ rhs: Self) -> Self
77-
77+
7878
/// Divides this rational value by `rhs` and returns the result.
7979
func divided(by rhs: Self) -> Self
80-
80+
8181
/// Raises this rational value to the power of `exp`.
8282
func toPower(of exp: Integer) -> Self
8383
}
@@ -93,20 +93,20 @@ private let rationalSeparator: Character = "/"
9393
/// numerator. The denominator is always positive.
9494
public struct Rational<T: SignedInteger>: RationalNumber,
9595
CustomStringConvertible {
96-
96+
9797
/// The numerator of this rational number. This is a signed integer.
9898
public let numerator: T
99-
99+
100100
/// The denominator of this rational number. This integer is always positive.
101101
public let denominator: T
102-
102+
103103
/// Sets numerator and denominator without normalization. This function must not be called
104104
/// outside of the NumberKit framework.
105105
fileprivate init(numerator: T, denominator: T) {
106106
self.numerator = numerator
107107
self.denominator = denominator
108108
}
109-
109+
110110
/// Creates a rational number from a numerator and a denominator.
111111
public init(_ numerator: T, _ denominator: T) {
112112
precondition(denominator != 0, "rational with zero denominator")
@@ -117,20 +117,20 @@ public struct Rational<T: SignedInteger>: RationalNumber,
117117
self.numerator = negative ? -(anum / div) : (anum / div)
118118
self.denominator = adenom / div
119119
}
120-
120+
121121
/// Creates a `Rational` from the given integer value of type `T`
122122
public init(_ value: T) {
123123
self.init(numerator: value, denominator: T(1))
124124
}
125-
125+
126126
/// Create an instance initialized to `value`.
127127
public init(integerLiteral value: T) {
128128
self.init(value)
129129
}
130-
130+
131131
/// Creates a `Rational` from a string containing a rational number using the base
132132
/// defined by parameter `radix`. The syntax of the rational number is defined as follows:
133-
///
133+
///
134134
/// Rational = Numerator '/' Denominator
135135
/// | SignedInteger
136136
/// Numerator = SignedInteger
@@ -152,7 +152,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
152152
return nil
153153
}
154154
}
155-
155+
156156
/// Returns the `Rational` as a value of type `T` if this is possible. If the number
157157
/// cannot be expressed as a `T`, this property returns `nil`.
158158
public var intValue: T? {
@@ -161,23 +161,23 @@ public struct Rational<T: SignedInteger>: RationalNumber,
161161
}
162162
return numerator
163163
}
164-
164+
165165
/// Returns the `Rational` value as a float value
166166
public var floatValue: Float {
167167
return Float(doubleValue)
168168
}
169-
169+
170170
/// Returns the `Rational` value as a double value
171171
public var doubleValue: Double {
172172
return Double(numerator.toIntMax())/Double(denominator.toIntMax())
173173
}
174-
174+
175175
/// Returns a string representation of this `Rational<T>` number using base 10.
176176
public var description: String {
177177
return denominator == 1 ? numerator.description
178178
: numerator.description + String(rationalSeparator) + denominator.description
179179
}
180-
180+
181181
/// Compute the greatest common divisor for `x` and `y`.
182182
public static func gcd(_ x: T, _ y: T) -> T {
183183
var (x, y, rest) = (x, y, x % y)
@@ -188,7 +188,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
188188
}
189189
return y
190190
}
191-
191+
192192
/// Compute the least common multiplier of `x` and `y`.
193193
public static func lcm(_ x: T, _ y: T) -> T {
194194
var abs = x * y
@@ -197,7 +197,7 @@ public struct Rational<T: SignedInteger>: RationalNumber,
197197
}
198198
return abs / Rational.gcd(x, y)
199199
}
200-
200+
201201
/// Determine the smallest common denominator between `self` and `other` and return
202202
/// the corresponding numerators and the common denominator.
203203
private func commonDenomWith(_ other: Rational<T>) -> (num1: T, num2: T, denom: T) {
@@ -206,73 +206,77 @@ public struct Rational<T: SignedInteger>: RationalNumber,
206206
let t2 = other.denominator / div
207207
return (self.numerator * t2, other.numerator * t1, t1 * t2 * div)
208208
}
209-
209+
210210
/// The hash value of this rational value.
211211
public var hashValue: Int {
212212
return 31 &* denominator.hashValue &+ numerator.hashValue
213213
}
214-
214+
215215
/// The absolute rational value (without sign).
216216
public var abs: Rational<T> {
217217
return Rational(numerator < 0 ? -numerator : numerator, denominator)
218218
}
219-
219+
220220
/// The negated rational value.
221221
public var negate: Rational<T> {
222222
return Rational(-numerator, denominator)
223223
}
224-
224+
225225
/// Is true if the rational value is negative.
226226
public var isNegative: Bool {
227227
return numerator < 0
228228
}
229-
229+
230230
/// Is true if the rational value is zero.
231231
public var isZero: Bool {
232232
return numerator == 0
233233
}
234-
234+
235235
/// Returns -1 if `self` is less than `rhs`,
236236
/// 0 if `self` is equals to `rhs`,
237237
/// +1 if `self` is greater than `rhs`
238238
public func compare(to rhs: Rational<T>) -> Int {
239239
let (n1, n2, _) = self.commonDenomWith(rhs)
240240
return n1 == n2 ? 0 : (n1 < n2 ? -1 : 1)
241241
}
242-
242+
243243
/// Returns the sum of this rational value and `rhs`.
244244
public func plus(_ rhs: Rational<T>) -> Rational<T> {
245245
let (n1, n2, denom) = self.commonDenomWith(rhs)
246246
return Rational(n1 + n2, denom)
247247
}
248-
248+
249249
/// Returns the difference between this rational value and `rhs`.
250250
public func minus(_ rhs: Rational<T>) -> Rational<T> {
251251
let (n1, n2, denom) = self.commonDenomWith(rhs)
252252
return Rational(n1 - n2, denom)
253253
}
254-
254+
255255
/// Multiplies this rational value with `rhs` and returns the result.
256256
public func times(_ rhs: Rational<T>) -> Rational<T> {
257257
return Rational(self.numerator * rhs.numerator, self.denominator * rhs.denominator)
258258
}
259-
259+
260260
/// Divides this rational value by `rhs` and returns the result.
261261
public func divided(by rhs: Rational<T>) -> Rational<T> {
262262
return Rational(self.numerator * rhs.denominator, self.denominator * rhs.numerator)
263263
}
264264

265265
/// Raises this rational value to the power of `exp`.
266266
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+
}
268272
}
269-
273+
270274
/// Returns the greatest common denominator for the two given rational numbers
271275
public static func gcd(_ x: Rational<T>, _ y: Rational<T>) -> Rational<T> {
272276
return Rational(Rational.gcd(x.numerator, y.numerator),
273277
Rational.lcm(x.denominator, y.denominator))
274278
}
275-
279+
276280
/// Returns the least common multiplier for the two given rational numbers
277281
public static func lcm(_ x: Rational<T>, _ y: Rational<T>) -> Rational<T> {
278282
let (xn, yn, denom) = x.commonDenomWith(y)
@@ -293,21 +297,21 @@ extension Rational: ExpressibleByStringLiteral {
293297
self.init(0)
294298
}
295299
}
296-
300+
297301
public init(extendedGraphemeClusterLiteral value: String) {
298302
self.init(stringLiteral: value)
299303
}
300-
304+
301305
public init(unicodeScalarLiteral value: String) {
302306
self.init(stringLiteral: value)
303307
}
304-
308+
305309
/// Compute absolute number of `num` and return a tuple consisting of the result and a
306310
/// boolean indicating whether there was an overflow.
307311
private static func absWithOverflow(_ num: T) -> (T, Bool) {
308312
return num < 0 ? T.subtractWithOverflow(0, num) : (num, false)
309313
}
310-
314+
311315
/// Creates a rational number from a numerator and a denominator.
312316
public static func rationalWithOverflow(_ numerator: T, _ denominator: T)
313317
-> (Rational<T>, Bool) {
@@ -324,7 +328,7 @@ extension Rational: ExpressibleByStringLiteral {
324328
return (Rational(numerator: numer, denominator: denom),
325329
overflow1 || overflow2 || overflow3 || overflow4 || overflow5)
326330
}
327-
331+
328332
/// Compute the smalles common denominator of `this` and `that` and return it together
329333
/// with the corresponding numerators.
330334
private static func commonDenomWithOverflow(_ this: Rational<T>, _ that: Rational<T>)
@@ -338,7 +342,7 @@ extension Rational: ExpressibleByStringLiteral {
338342
let (dn, overflow4) = T.multiplyWithOverflow(dp, div)
339343
return (n1, n2, dn, overflow1 || overflow2 || overflow3 || overflow4)
340344
}
341-
345+
342346
/// Add `lhs` and `rhs` and return a tuple consisting of the result and a boolean which
343347
/// indicates whether there was an overflow.
344348
public static func addWithOverflow(_ lhs: Rational<T>, _ rhs: Rational<T>)
@@ -348,7 +352,7 @@ extension Rational: ExpressibleByStringLiteral {
348352
let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
349353
return (res, overflow1 || overflow2 || overflow3)
350354
}
351-
355+
352356
/// Subtract `rhs` from `lhs` and return a tuple consisting of the result and a boolean which
353357
/// indicates whether there was an overflow.
354358
public static func subtractWithOverflow(_ lhs: Rational<T>, _ rhs: Rational<T>)
@@ -358,7 +362,7 @@ extension Rational: ExpressibleByStringLiteral {
358362
let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
359363
return (res, overflow1 || overflow2 || overflow3)
360364
}
361-
365+
362366
/// Multiply `lhs` and `rhs` and return a tuple consisting of the result and a boolean which
363367
/// indicates whether there was an overflow.
364368
public static func multiplyWithOverflow(_ lhs: Rational<T>, _ rhs: Rational<T>)
@@ -368,7 +372,7 @@ extension Rational: ExpressibleByStringLiteral {
368372
let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
369373
return (res, overflow1 || overflow2 || overflow3)
370374
}
371-
375+
372376
/// Divide `lhs` by `rhs` and return a tuple consisting of the result and a boolean which
373377
/// indicates whether there was an overflow.
374378
public static func divideWithOverflow(_ lhs: Rational<T>, _ rhs: Rational<T>)
@@ -378,7 +382,7 @@ extension Rational: ExpressibleByStringLiteral {
378382
let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
379383
return (res, overflow1 || overflow2 || overflow3)
380384
}
381-
385+
382386
/// Compute the greatest common divisor for `x` and `y`.
383387
public static func gcdWithOverflow(_ x: T, _ y: T) -> (T, Bool) {
384388
var (x, y, (rest, overflow)) = (x, y, T.remainderWithOverflow(x, y))
@@ -391,22 +395,22 @@ extension Rational: ExpressibleByStringLiteral {
391395
}
392396
return (y, overflow)
393397
}
394-
398+
395399
/// Compute the least common multiplier of `x` and `y`.
396400
public static func lcmWithOverflow(_ x: T, _ y: T) -> (T, Bool) {
397401
let (abs, overflow1) = T.multiplyWithOverflow(x, y)
398402
let (gcd, overflow2) = Rational.gcdWithOverflow(x, y)
399403
return ((abs < 0 ? -abs : abs) / gcd, overflow1 || overflow2)
400404
}
401-
405+
402406
/// Returns the greatest common denominator for the two given rational numbers and a boolean
403407
/// which indicates whether there was an overflow.
404408
public static func gcdWithOverflow(_ x: Rational<T>, _ y: Rational<T>) -> (Rational<T>, Bool) {
405409
let (numer, overflow1) = Rational.gcdWithOverflow(x.numerator, y.numerator)
406410
let (denom, overflow2) = Rational.lcmWithOverflow(x.denominator, y.denominator)
407411
return (Rational(numer, denom), overflow1 || overflow2)
408412
}
409-
413+
410414
/// Returns the least common multiplier for the two given rational numbers and a boolean
411415
/// which indicates whether there was an overflow.
412416
public static func lcmWithOverflow(_ x: Rational<T>, _ y: Rational<T>) -> (Rational<T>, Bool) {

0 commit comments

Comments
 (0)