Skip to content

Commit

Permalink
Add: Division/exactly() (#70).
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Aug 22, 2024
1 parent fca2cf4 commit 6ad64f1
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
6 changes: 4 additions & 2 deletions Sources/CoreKit/Models/Division+Rounding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ extension Division where Quotient: BinaryInteger, Remainder: BinaryInteger {
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Increments the `quotient` if the `remainder` is positive.
/// Increments the `quotient` when the `remainder` is positive.
@inlinable public consuming func ceil() -> Fallible<Quotient> {
let instance: Self = consume self
let increment: Quotient = instance.remainder > 0 ? 1 : 0
return instance.quotient.plus(increment)
}

/// Decrements the `quotient` if the `remainder` is negative.
/// Decrements the `quotient` when the `remainder` is negative.
@inlinable public consuming func floor() -> Fallible<Quotient> {
let instance: Self = consume self
let increment: Quotient = instance.remainder.isNegative ? 1 : 0
Expand All @@ -42,10 +42,12 @@ extension Fallible {
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Increments the `quotient` when the `remainder` is positive.
@inlinable public consuming func ceil<Quotient, Remainder>() -> Fallible<Quotient> where Value == Division<Quotient, Remainder> {
self.value.ceil().veto(self.error)
}

/// Decrements the `quotient` when the `remainder` is negative.
@inlinable public consuming func floor<Quotient, Remainder>() -> Fallible<Quotient> where Value == Division<Quotient, Remainder> {
self.value.floor().veto(self.error)
}
Expand Down
46 changes: 46 additions & 0 deletions Sources/CoreKit/Models/Division+Validation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

//*============================================================================*
// MARK: * Division x Validation
//*============================================================================*

extension Division {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Returns the `quotient` and an `error` indicator.
///
/// The `error` is set when the `remainder` is nonzero.
///
@inlinable public consuming func exactly() -> Fallible<Quotient> {
self.quotient.veto(!self.remainder.isZero)
}
}

//=----------------------------------------------------------------------------=
// MARK: + Recoverable
//=----------------------------------------------------------------------------=

extension Fallible {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Returns the `quotient` and an `error` indicator.
///
/// The `error` is set when the `remainder` is nonzero.
///
@inlinable public consuming func exactly<Quotient, Remainder>() -> Fallible<Quotient> where Value == Division<Quotient, Remainder> {
self.value.exactly().veto(self.error)
}
}
43 changes: 43 additions & 0 deletions Tests/CoreKitTests/Division+Validation.swift.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit
import TestKit

//*============================================================================*
// MARK: * Division x Validation
//*============================================================================*

extension DivisionTests {

//=------------------------------------------------------------------------=
// MARK: Tests
//=------------------------------------------------------------------------=

func testExactly() {
func whereIs<Q, R>(_ quotient: Q.Type, _ remainder: R.Type) where Q: SystemsInteger, R: SystemsInteger {
let patterns = I8(-2)...I8(2)
for quotient in patterns.lazy.map(Q.init(load:)) {
for remainder in patterns.lazy.map(R.init(load:)) {
let error = !remainder.isZero
let division = Division(quotient: quotient, remainder: remainder)
Test().same(division .exactly(), Fallible(quotient, error: error))
Test().same(division.veto(false).exactly(), Fallible(quotient, error: error))
Test().same(division.veto(true ).exactly(), Fallible(quotient, error: true ))
}
}
}

for quotient in coreSystemsIntegers {
for remainder in coreSystemsIntegers {
whereIs(quotient, remainder)
}
}
}
}
6 changes: 5 additions & 1 deletion Tests/UltimathnumTests/BinaryInteger+Division.swift
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,13 @@ extension BinaryIntegerTestsOnDivision {
let floor: Fallible<T> = division.floor()
success &+= IX(Bit(division.veto(false).floor() == floor))
success &+= IX(Bit(division.veto(true ).floor() == floor.veto()))

let exactly: Fallible<T> = division.exactly()
success &+= IX(Bit(division.veto(false).exactly() == exactly))
success &+= IX(Bit(division.veto(true ).exactly() == exactly.veto()))
}

Test().same(success, rounds &* 10)
Test().same(success, rounds &* 12)
}

func whereIsUnsignedSystemsInteger<T>(_ type: T.Type, rounds: IX, randomness: consuming FuzzerInt) where T: SystemsInteger & UnsignedInteger {
Expand Down

0 comments on commit 6ad64f1

Please sign in to comment.