-
Notifications
You must be signed in to change notification settings - Fork 1
/
ANKFullWidth+Division+Digit.swift
99 lines (81 loc) · 4.28 KB
/
ANKFullWidth+Division+Digit.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//=----------------------------------------------------------------------------=
// This source file is part of the AwesomeNumbersKit open source project.
//
// Copyright (c) 2022 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=
import ANKCoreKit
//*============================================================================*
// MARK: * ANK x Full Width x Division x Digit
//*============================================================================*
extension ANKFullWidth {
//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=
@_disfavoredOverload @_transparent public mutating func divideReportingOverflow(by other: Digit) -> Bool {
let pvo: PVO<Self> = self.dividedReportingOverflow(by: other)
self = pvo.partialValue
return pvo.overflow as Bool
}
@_disfavoredOverload @_transparent public func dividedReportingOverflow(by other: Digit) -> PVO<Self> {
let qro: PVO<QR<Self, Digit>> = self.quotientAndRemainderReportingOverflow(dividingBy: other)
return PVO(qro.partialValue.quotient, qro.overflow)
}
@_disfavoredOverload @_transparent public mutating func formRemainderReportingOverflow(dividingBy other: Digit) -> Bool {
let pvo: PVO<Digit> = self.remainderReportingOverflow(dividingBy: other)
self = Self(digit: pvo.partialValue)
return pvo.overflow as Bool
}
@_disfavoredOverload @_transparent public func remainderReportingOverflow(dividingBy other: Digit) -> PVO<Digit> {
let qro: PVO<QR<Self, Digit>> = self.quotientAndRemainderReportingOverflow(dividingBy: other)
return PVO(qro.partialValue.remainder, qro.overflow)
}
@_disfavoredOverload @inlinable public func quotientAndRemainderReportingOverflow(dividingBy other: Digit) -> PVO<QR<Self, Digit>> {
let lhsIsLessThanZero: Bool = self .isLessThanZero
let rhsIsLessThanZero: Bool = other.isLessThanZero
let minus = lhsIsLessThanZero != rhsIsLessThanZero
//=--------------------------------------=
var qro = ANK.bitCast(self.magnitude.quotientAndRemainderReportingOverflow(dividingBy: other.magnitude)) as PVO<QR<Self, Digit>>
//=--------------------------------------=
if minus {
qro.partialValue.quotient.formTwosComplement()
}
if lhsIsLessThanZero {
qro.partialValue.remainder.formTwosComplement()
}
if lhsIsLessThanZero, rhsIsLessThanZero, qro.partialValue.quotient.mostSignificantBit {
qro.overflow = true
}
//=--------------------------------------=
return qro as PVO<QR<Self, Digit>>
}
}
//=----------------------------------------------------------------------------=
// MARK: + Unsigned
//=----------------------------------------------------------------------------=
extension ANKFullWidth where High == High.Magnitude {
//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=
@inlinable func quotientAndRemainderReportingOverflow(dividingBy other: Digit) -> PVO<QR<Self, Digit>> {
var quotient = self
let remainder = quotient.formQuotientWithRemainderReportingOverflow(dividingBy: other)
return PVO(QR(quotient, remainder.partialValue), remainder.overflow)
}
@inlinable mutating func formQuotientWithRemainderReportingOverflow(dividingBy other: Digit) -> PVO<Digit> {
//=--------------------------------------=
if other.isZero {
return ANK.bitCast(PVO(self.first, true))
}
//=--------------------------------------=
var remainder = UInt()
self.withUnsafeMutableWords { this in
for index in this.indices.reversed() {
(this[index], remainder) = other.dividingFullWidth(HL(remainder, this[index]))
}
}
return PVO(remainder, false)
}
}