patternswiftMinor
Fraction (rational number) structure with custom operators
Viewed 0 times
numberwithrationalcustomstructurefractionoperators
Problem
First, the struct itself:
The GCD function the struct's
An extension on
And now for the operators. First, your basic add, subtract, multiply, and divide:
```
@infix func + (first: Fraction, second: Fraction) -> Fraction {
let numerator = (first.numerator second.denominator) + (first.denominator second.numerator)
let denominator = (first.denominator * second.denominator)
var frac = Fraction(numerator: numerator, denominator: denominator)
frac.reduce()
return frac
}
@infix func - (first: Fraction, second: Fraction) -> Fraction {
let subtractor = Fraction(numerator: -second.numerator, denominator: second.denominator)
return first + subtracto
struct Fraction {
var numerator: Int
var denominator: Int {
didSet (oldDenominator) {
if self.denominator == 0 {
self.denominator = oldDenominator
}
}
}
init() {
self.init(numerator: 0, denominator: 1)
}
init(numerator: Int) {
self.init(numerator: numerator, denominator: 1)
}
init(reciprocalOf denominator: Int) {
self.init(numerator: 1, denominator: denominator)
}
init(numerator: Int, denominator: Int) {
self.numerator = numerator;
self.denominator = denominator;
}
mutating func reduce() {
let gcd = greatestCommonDenominator(self.numerator,self.denominator)
self.numerator /= gcd
self.denominator /= gcd
}
func fraction() -> (numerator:Int,denominator:Int) {
return (self.numerator,self.denominator)
}
}The GCD function the struct's
reduce() function uses:func greatestCommonDenominator(first: Int, second: Int) -> Int {
return second == 0 ? first : greatestCommonDenominator(second, first % second)
}An extension on
Int to conveniently make some of these fractions:extension Int {
var fraction: Fraction {
return Fraction(numerator: self)
}
var reciprocalOf: Fraction {
return Fraction(reciprocalOf: self)
}
}And now for the operators. First, your basic add, subtract, multiply, and divide:
```
@infix func + (first: Fraction, second: Fraction) -> Fraction {
let numerator = (first.numerator second.denominator) + (first.denominator second.numerator)
let denominator = (first.denominator * second.denominator)
var frac = Fraction(numerator: numerator, denominator: denominator)
frac.reduce()
return frac
}
@infix func - (first: Fraction, second: Fraction) -> Fraction {
let subtractor = Fraction(numerator: -second.numerator, denominator: second.denominator)
return first + subtracto
Solution
The most of your code looks nice to me, too. Here are some remarks:
Personally, I would make Fraction an immutable structure. Then you could test for 0 on creation like this
and also reduce on creation.
And one more thing, how about this addition?
With it you can simply write
- Your definition of / is wrong. It should use the divisor.
- Maybe make the creation of Fractions more lightweight by using
init(_ numerator: Int, _ denominator: Int)so that you could writeFration(3,4)?
- By your definition by didSet it is possible to have
Fraction(1,0)which might not be intended.
Personally, I would make Fraction an immutable structure. Then you could test for 0 on creation like this
init?(_ numerator: Int, _ denominator: Int) {
if denominator == 0 { return nil }
...
}and also reduce on creation.
And one more thing, how about this addition?
extension Fraction : IntegerLiteralConvertible {
init(integerLiteral value: IntegerLiteralType) {
self.init(numerator:value)
}
}With it you can simply write
12 instead of 12.fraction.Code Snippets
init?(_ numerator: Int, _ denominator: Int) {
if denominator == 0 { return nil }
...
}extension Fraction : IntegerLiteralConvertible {
init(integerLiteral value: IntegerLiteralType) {
self.init(numerator:value)
}
}Context
StackExchange Code Review Q#56872, answer score: 5
Revisions (0)
No revisions yet.