Last active
October 16, 2020 17:34
-
-
Save kieranb662/21579432280dbf918fb8bc9877d81d35 to your computer and use it in GitHub Desktop.
[Rational Number Type] Rational number implementation in swift #Math
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct RationalNumber { | |
let numerator: Int | |
let denominator: Int | |
// todo: fix this so that infinities are handled properly | |
var decimal: Double { | |
denominator != 0 ? Double(numerator)/Double(denominator) : .infinity | |
} | |
var magnitude: Double { | |
return abs(decimal) | |
} | |
public init(_ numerator: Int, _ denominator: Int) { | |
self.numerator = numerator | |
self.denominator = denominator | |
} | |
/// Need to test and refactor this to be more robust. | |
var isNegative: Bool { | |
if numerator >= 0 && denominator > 0 { | |
return false | |
} else if numerator <= 0 && denominator < 0 { | |
return false | |
} else { | |
return true | |
} | |
} | |
} | |
// MARK: - Equatable Conformance | |
extension RationalNumber: Equatable { | |
// todo: come back and adjust this because using the decimal is a bit of a naive | |
// approach to checking equivalence. | |
static func == (lhs: RationalNumber, rhs: RationalNumber) -> Bool { | |
return lhs.decimal == rhs.decimal | |
} | |
} | |
// MARK: - Comparable Conformance | |
extension RationalNumber: Comparable { | |
// todo: Come back and fix for same reason as Equatable. | |
static func < (lhs: RationalNumber, rhs: RationalNumber) -> Bool { | |
return lhs.decimal < rhs.decimal | |
} | |
} | |
// MARK: - Int and Rational Math | |
/// Compute the value of a rational number to the power of an integer. | |
/// The three main cases are handled | |
/// * power greater than 0 | |
/// * power less than 0 | |
/// * power equal to 0 | |
/// - important- Relies on a for loop to multiply the numerator and denominator by its self (power-1) times. This could be very slow for large powers. | |
func pow(base: RationalNumber, power: Int) -> RationalNumber { | |
if power == 0 { | |
return 1 | |
} else { | |
var num = base.numerator | |
var denom = base.denominator | |
for _ in 1...abs(power)-1 { | |
num *= base.numerator | |
denom *= base.denominator | |
} | |
return power > 0 ? RationalNumber(num, denom) : RationalNumber(denom, num) | |
} | |
} | |
// MARK: AdditiveArithmetic Conformance | |
extension RationalNumber: AdditiveArithmetic { | |
static var zero: RationalNumber = 0 | |
static func += (lhs: inout RationalNumber, rhs: RationalNumber) { | |
lhs = lhs+rhs | |
} | |
static func -= (lhs: inout RationalNumber, rhs: RationalNumber) { | |
lhs = lhs-rhs | |
} | |
} | |
// MARK: - (Rational, Rational) Math | |
extension RationalNumber { | |
static func *(lhs: RationalNumber, rhs: RationalNumber) -> RationalNumber { | |
return RationalNumber(lhs.numerator*rhs.numerator, | |
lhs.denominator*rhs.denominator) | |
} | |
static func /(lhs: RationalNumber, rhs: RationalNumber) -> RationalNumber { | |
return RationalNumber(lhs.numerator*rhs.denominator, | |
lhs.denominator*rhs.numerator) | |
} | |
static func +(lhs: RationalNumber, rhs: RationalNumber) -> RationalNumber { | |
return RationalNumber(lhs.numerator*rhs.denominator + lhs.denominator*rhs.numerator, | |
lhs.denominator*rhs.denominator) | |
} | |
static func -(lhs: RationalNumber, rhs: RationalNumber) -> RationalNumber { | |
return RationalNumber(lhs.numerator*rhs.denominator - lhs.denominator*rhs.numerator, | |
lhs.denominator*rhs.denominator) | |
} | |
static func ^(lhs: RationalNumber, rhs: Int) -> RationalNumber { | |
return pow(base: lhs, power: rhs) | |
} | |
static prefix func -(input: RationalNumber) -> RationalNumber { | |
return RationalNumber(-input.numerator, input.denominator) | |
} | |
} | |
// MARK: - ExpressibleByIntegerLiteral Conformance | |
extension RationalNumber: ExpressibleByIntegerLiteral { | |
init(integerLiteral value: Int) { | |
numerator = value | |
denominator = 1 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment