diff --git a/Sources/OTCore/Extensions/Darwin/FloatingPoint and Darwin.swift b/Sources/OTCore/Extensions/Darwin/FloatingPoint and Darwin.swift index fc278cf..5593c91 100644 --- a/Sources/OTCore/Extensions/Darwin/FloatingPoint and Darwin.swift +++ b/Sources/OTCore/Extensions/Darwin/FloatingPoint and Darwin.swift @@ -113,22 +113,21 @@ extension FloatingPoint { /// **OTCore:** /// Similar to `Int.quotientAndRemainder(dividingBy:)` from the standard Swift library. - /// - /// - Note: Internally, employs `trunc()` and `.truncatingRemainder(dividingBy:)`. - public func quotientAndRemainder(dividingBy: Self) -> (quotient: Self, remainder: Self) { + public func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: Self) { - let calculation = (self / dividingBy) + let calculation = self / rhs let integral = trunc(calculation) - let fraction = self.truncatingRemainder(dividingBy: dividingBy) + let fraction = self - (integral * rhs) return (quotient: integral, remainder: fraction) } /// **OTCore:** /// Returns both integral part and fractional part. - /// This method is more computationally efficient than calling `.integral` and .`fraction` properties separately unless you only require one or the other. /// - /// Note: this can result in a non-trivial loss of precision for the fractional part. + /// - Note: This method is more computationally efficient than calling both `.integral` and .`fraction` properties separately unless you only require one or the other. + /// + /// This method can result in a non-trivial loss of precision for the fractional part. @inlinable public var integralAndFraction: (integral: Self, fraction: Self) { let integral = trunc(self) @@ -148,7 +147,7 @@ extension FloatingPoint { /// **OTCore:** /// Returns the fractional part (digits after the decimal point) /// - /// Note: this can result in a non-trivial loss of precision for the fractional part. + /// - Note: this method can result in a non-trivial loss of precision for the fractional part. @inlinable public var fraction: Self { integralAndFraction.fraction diff --git a/Sources/OTCore/Extensions/Foundation/Decimal.swift b/Sources/OTCore/Extensions/Foundation/Decimal.swift index 51bd3d3..a285260 100644 --- a/Sources/OTCore/Extensions/Foundation/Decimal.swift +++ b/Sources/OTCore/Extensions/Foundation/Decimal.swift @@ -250,4 +250,49 @@ extension Decimal { } +extension Decimal { + + /// **OTCore:** + /// Similar to `Int.quotientAndRemainder(dividingBy:)` from the standard Swift library. + public func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: Self) { + + let calculation = self / rhs + let integral = calculation.truncated(decimalPlaces: 0) + let fraction = self - (integral * rhs) + return (quotient: integral, remainder: fraction) + + } + + /// **OTCore:** + /// Returns both integral part and fractional part. + /// + /// - Note: This method is more computationally efficient than calling both `.integral` and .`fraction` properties separately unless you only require one or the other. + @inlinable public var integralAndFraction: (integral: Self, fraction: Self) { + + let integral = truncated(decimalPlaces: 0) + let fraction = self - integral + return (integral: integral, fraction: fraction) + + } + + /// **OTCore:** + /// Returns the integral part (digits before the decimal point) + @inlinable public var integral: Self { + + integralAndFraction.integral + + } + + /// **OTCore:** + /// Returns the fractional part (digits after the decimal point) + /// + /// Note: this can result in a non-trivial loss of precision for the fractional part. + @inlinable public var fraction: Self { + + integralAndFraction.fraction + + } + +} + #endif diff --git a/Tests/OTCoreTests/Extensions/Darwin/FloatingPoint and Darwin Tests.swift b/Tests/OTCoreTests/Extensions/Darwin/FloatingPoint and Darwin Tests.swift index 992b578..cf577d6 100644 --- a/Tests/OTCoreTests/Extensions/Darwin/FloatingPoint and Darwin Tests.swift +++ b/Tests/OTCoreTests/Extensions/Darwin/FloatingPoint and Darwin Tests.swift @@ -96,7 +96,6 @@ class Extensions_Darwin_FloatingPointAndDarwin_Tests: XCTestCase { XCTAssertEqual(iaf.fraction, 0.5) XCTAssertEqual(17.5.integral, 17) - XCTAssertEqual(17.5.fraction, 0.5) } diff --git a/Tests/OTCoreTests/Extensions/Foundation/Decimal Tests.swift b/Tests/OTCoreTests/Extensions/Foundation/Decimal Tests.swift index 46d8342..d35cde2 100644 --- a/Tests/OTCoreTests/Extensions/Foundation/Decimal Tests.swift +++ b/Tests/OTCoreTests/Extensions/Foundation/Decimal Tests.swift @@ -40,7 +40,7 @@ class Extensions_Foundation_Decimal_Tests: XCTestCase { func testPower() { - XCTAssertEqual(Decimal(2.0).power(3) , 8.0) + XCTAssertEqual(Decimal(string: "2.0")!.power(3) , 8.0) } @@ -56,15 +56,15 @@ class Extensions_Foundation_Decimal_Tests: XCTestCase { let str = "1.0" - XCTAssertEqual(str.decimal, 1.0) - XCTAssertEqual(str.decimal(locale: .init(identifier: "en_US")), 1.0) + XCTAssertEqual(str.decimal, Decimal(string: "1.0")!) + XCTAssertEqual(str.decimal(locale: .init(identifier: "en_US")), Decimal(string: "1.0")!) // Substring let subStr = str.prefix(3) - XCTAssertEqual(subStr.decimal, 1.0) - XCTAssertEqual(subStr.decimal(locale: .init(identifier: "en_US")), 1.0) + XCTAssertEqual(subStr.decimal, Decimal(string: "1.0")!) + XCTAssertEqual(subStr.decimal(locale: .init(identifier: "en_US")), Decimal(string: "1.0")!) } @@ -126,6 +126,27 @@ class Extensions_Foundation_Decimal_Tests: XCTestCase { } + func testQuotientAndRemainder() { + + let qr = Decimal(string: "17.5")!.quotientAndRemainder(dividingBy: 5.0) + + XCTAssertEqual(qr.quotient, Decimal(string: "3")!) + XCTAssertEqual(qr.remainder, Decimal(string: "2.5")!) + + } + + func testIntegralAndFraction() { + + let iaf = Decimal(string: "17.5")!.integralAndFraction + + XCTAssertEqual(iaf.integral, Decimal(string: "17")!) + XCTAssertEqual(iaf.fraction, Decimal(string: "0.5")!) + + XCTAssertEqual(Decimal(string: "17.5")!.integral, Decimal(string: "17")!) + XCTAssertEqual(Decimal(string: "17.5")!.fraction, Decimal(string: "0.5")!) + + } + } #endif