Skip to content

Commit

Permalink
Decimal: Added integralDigitPlaces and fractionDigitPlaces prop…
Browse files Browse the repository at this point in the history
…erties
  • Loading branch information
orchetect committed Nov 21, 2023
1 parent 98217c7 commit 7e44c39
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Sources/OTCore/Extensions/Foundation/Decimal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,28 @@ extension Decimal {
}
}

// MARK: - Digit Places

extension Decimal {
/// **OTCore:**
/// Returns the number of digit places of the ``integral`` portion (left of the decimal).
@inlinable @_disfavoredOverload
public var integralDigitPlaces: Int {
// this works but may be brittle.
// not sure if some locales will localize the number differently than expected.
// on English systems the `significand` string interpolation produces
// a string of digits with no thousands separators or other characters.

if abs(self) <= 1 { return 0 }
return "\(abs(significand))".count + exponent
}

/// **OTCore:**
/// Returns the number of digit places of the ``fraction`` portion (right of the decimal).
@inlinable @_disfavoredOverload
public var fractionDigitPlaces: Int {
return max(-exponent, 0)
}
}

#endif
40 changes: 40 additions & 0 deletions Tests/OTCoreTests/Extensions/Foundation/Decimal Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,46 @@ class Extensions_Foundation_Decimal_Tests: XCTestCase {
XCTAssertEqual(Decimal(string: "17.5")!.integral, Decimal(string: "17")!)
XCTAssertEqual(Decimal(string: "17.5")!.fraction, Decimal(string: "0.5")!)
}

func testIntegralDigitPlaces_and_fractionDigitPlaces() {
// we'll cast the number literals as Double to see if Decimal converts them and results are
// still as expected

XCTAssertEqual(Decimal(0.05 as Double).integralDigitPlaces, 0)
XCTAssertEqual(Decimal(0.05 as Double).fractionDigitPlaces, 2)
XCTAssertEqual(Decimal(-0.05 as Double).integralDigitPlaces, 0)
XCTAssertEqual(Decimal(-0.05 as Double).fractionDigitPlaces, 2)

XCTAssertEqual(Decimal(10.0 as Double).integralDigitPlaces, 2)
XCTAssertEqual(Decimal(10.0 as Double).fractionDigitPlaces, 0)
XCTAssertEqual(Decimal(-10.0 as Double).integralDigitPlaces, 2)
XCTAssertEqual(Decimal(-10.0 as Double).fractionDigitPlaces, 0)

XCTAssertEqual(Decimal(10.123 as Double).integralDigitPlaces, 2)
XCTAssertEqual(Decimal(10.123 as Double).fractionDigitPlaces, 3)
XCTAssertEqual(Decimal(-10.123 as Double).integralDigitPlaces, 2)
XCTAssertEqual(Decimal(-10.123 as Double).fractionDigitPlaces, 3)

XCTAssertEqual(Decimal(10_000.123 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(10_000.123 as Double).fractionDigitPlaces, 3)
XCTAssertEqual(Decimal(-10_000.123 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(-10_000.123 as Double).fractionDigitPlaces, 3)

XCTAssertEqual(Decimal(10_000.0 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(10_000.0 as Double).fractionDigitPlaces, 0)
XCTAssertEqual(Decimal(-10_000.0 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(-10_000.0 as Double).fractionDigitPlaces, 0)

XCTAssertEqual(Decimal(12_345.0 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(12_345.0 as Double).fractionDigitPlaces, 0)
XCTAssertEqual(Decimal(-12_345.0 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(-12_345.0 as Double).fractionDigitPlaces, 0)

XCTAssertEqual(Decimal(12_345.67 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(12_345.67 as Double).fractionDigitPlaces, 2)
XCTAssertEqual(Decimal(-12_345.67 as Double).integralDigitPlaces, 5)
XCTAssertEqual(Decimal(-12_345.67 as Double).fractionDigitPlaces, 2)
}
}

#endif

0 comments on commit 7e44c39

Please sign in to comment.