Created
October 18, 2019 21:01
-
-
Save AK-10/98e9108b61084c5c3ccc1001b2bf02b1 to your computer and use it in GitHub Desktop.
分数型
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 Fractional: CustomStringConvertible, Equatable { | |
let value: (Int, Int) | |
var num: Int { | |
return value.0 | |
} | |
var den: Int { | |
return value.1 | |
} | |
var description: String { | |
return "\(num)/\(den)" | |
} | |
var reciprocal: Self { | |
return Fractional(den, num) | |
} | |
init(_ fraction: Int, _ denominator: Int) { | |
if denominator == 0 { | |
fatalError("zero denominator") | |
} | |
let isNegative = fraction * denominator < 0 | |
let absFraction = abs(fraction) | |
let absDenominator = abs(denominator) | |
let gcd = Self.gcd(absDenominator, absFraction) | |
value = isNegative | |
? (-(absFraction/gcd), (absDenominator/gcd)) | |
: ((absFraction/gcd), (absDenominator/gcd)) | |
} | |
static func == (lhs: Fractional, rhs: Fractional) -> Bool { | |
let eqNum = lhs.num == rhs.num | |
let eqDen = rhs.den == rhs.den | |
return eqNum && eqDen | |
} | |
static func + (lhs: Self, rhs: Self) -> Self { | |
let denominator = Self.lcm(lhs.den, rhs.den) | |
let lFraction = lhs.num * (denominator / lhs.den) | |
let rFraction = rhs.num * (denominator / rhs.den) | |
return Fractional(lFraction + rFraction, denominator) | |
} | |
static func - (lhs: Self, rhs: Self) -> Self { | |
let denominator = Self.lcm(lhs.den, rhs.den) | |
let lFraction = lhs.num * (denominator / lhs.den) | |
let rFraction = rhs.num * (denominator / rhs.den) | |
return Fractional(lFraction - rFraction, denominator) | |
} | |
static func * (lhs: Self, rhs: Self) -> Self { | |
let numeric = lhs.num * rhs.num | |
let denominator = lhs.den * rhs.den | |
return Fractional(numeric, denominator) | |
} | |
static func / (lhs: Self, rhs: Self) -> Self { | |
return lhs * rhs.reciprocal | |
} | |
static private func gcd(_ x: Int, _ y: Int) -> Int { | |
// Euclidean Algorithm | |
if y > x { | |
return gcd(y, x) | |
} | |
return y != 0 ? gcd(y, x % y) : x | |
} | |
static private func lcm(_ x: Int, _ y: Int) -> Int { | |
// x*y = gcd(x, y) * lcm(x * y) | |
return x * y / gcd(x, y) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment