Skip to content

Commit

Permalink
Type-safe tuple bit casts.
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Jun 7, 2023
1 parent 616a958 commit ad1f93b
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 24 deletions.
16 changes: 8 additions & 8 deletions Sources/NBKCoreKit/NBKCoreInteger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ extension NBKCoreInteger {
@inlinable public func dividingFullWidthReportingOverflow(_ other: HL<Self, Magnitude>) -> PVO<QR<Self, Self>> {
//=--------------------------------------=
if self.isZero {
return PVO(QR(Self(bitPattern: other.low), Self(bitPattern: other.low)), true)
return NBK.bitCast(PVO(QR(other.low, other.low), true))
}
//=--------------------------------------=
let lhsIsLessThanZero: Bool = other.high.isLessThanZero
let rhsIsLessThanZero: Bool = /*--*/self.isLessThanZero
let minus: Bool = (lhsIsLessThanZero != rhsIsLessThanZero)
let lhsIsLessThanZero: Bool = other.high.isLessThanZero
let rhsIsLessThanZero: Bool = /*--*/self.isLessThanZero
let minus: Bool = lhsIsLessThanZero != rhsIsLessThanZero
//=--------------------------------------=
var lhsMagnitude = HL(Magnitude(bitPattern: other.high), other.low)
var lhsMagnitude = NBK.bitCast(other) as HL<Magnitude, Magnitude>
if lhsIsLessThanZero {
var carry = true
carry = lhsMagnitude.low .formTwosComplementSubsequence(carry)
Expand All @@ -136,7 +136,7 @@ extension NBKCoreInteger {

let rhsMagnitude = self.magnitude as Magnitude
//=--------------------------------------=
var qro = PVO(rhsMagnitude.dividingFullWidth(lhsMagnitude), lhsMagnitude.high >= rhsMagnitude)
var qro = NBK.bitCast(PVO(rhsMagnitude.dividingFullWidth(lhsMagnitude), lhsMagnitude.high >= rhsMagnitude)) as PVO<QR<Self, Self>>
//=--------------------------------------=
if minus {
qro.partialValue.quotient.formTwosComplement()
Expand All @@ -146,11 +146,11 @@ extension NBKCoreInteger {
qro.partialValue.remainder.formTwosComplement()
}

if Self.isSigned, qro.partialValue.quotient.mostSignificantBit != minus {
if minus != qro.partialValue.quotient.isLessThanZero {
qro.overflow = qro.overflow || !(minus && qro.partialValue.quotient.isZero)
}
//=--------------------------------------=
return PVO(QR(Self(bitPattern: qro.partialValue.quotient), Self(bitPattern: qro.partialValue.remainder)), qro.overflow)
return qro as PVO<QR<Self, Self>>
}
}

Expand Down
42 changes: 42 additions & 0 deletions Sources/NBKCoreKit/Private/BitCast.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Numberick 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: * NBK x Bit Cast
//*============================================================================*

extension NBK {

//=------------------------------------------------------------------------=
// MARK: Utilities
//=------------------------------------------------------------------------=

@inlinable public static func bitCast<A0, B0>(_ x: PVO<A0>) -> PVO<B0> where
A0: NBKBitPatternConvertible, B0: NBKBitPatternConvertible, A0.BitPattern == B0.BitPattern {
PVO(partialValue: B0(bitPattern: x.partialValue), x.overflow)
}

@inlinable public static func bitCast<A0, A1, B0, B1>(_ x: HL<A0, A1>) -> HL<B0, B1> where
A0: NBKBitPatternConvertible, B0: NBKBitPatternConvertible, A0.BitPattern == B0.BitPattern,
A1: NBKBitPatternConvertible, B1: NBKBitPatternConvertible, A1.BitPattern == B1.BitPattern {
HL(B0(bitPattern: x.high), B1(bitPattern: x.low))
}

@inlinable public static func bitCast<A0, A1, B0, B1>(_ x: QR<A0, A1>) -> QR<B0, B1> where
A0: NBKBitPatternConvertible, B0: NBKBitPatternConvertible, A0.BitPattern == B0.BitPattern,
A1: NBKBitPatternConvertible, B1: NBKBitPatternConvertible, A1.BitPattern == B1.BitPattern {
QR(quotient: B0(bitPattern: x.quotient), remainder: B1(bitPattern: x.remainder))
}

@inlinable public static func bitCast<A0, A1, B0, B1>(_ x: PVO<QR<A0, A1>>) -> PVO<QR<B0, B1>> where
A0: NBKBitPatternConvertible, B0: NBKBitPatternConvertible, A0.BitPattern == B0.BitPattern,
A1: NBKBitPatternConvertible, B1: NBKBitPatternConvertible, A1.BitPattern == B1.BitPattern {
PVO(partialValue: NBK.bitCast(x.partialValue), overflow: x.overflow)
}
}
4 changes: 1 addition & 3 deletions Sources/NBKDoubleWidthKit/NBKDoubleWidth+Bitwise.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ extension NBKDoubleWidth {
//=------------------------------------------------------------------------=

@inlinable public var byteSwapped: Self {
let a = High(bitPattern: self.low .byteSwapped)
let b = Low (bitPattern: self.high.byteSwapped)
return Self(descending: HL(a, b))
Self(descending: NBK.bitCast(HL(self.low.byteSwapped, self.high.byteSwapped)))
}
}
8 changes: 4 additions & 4 deletions Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division+Digit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension NBKDoubleWidth {
let lhsIsLessThanZero: Bool = self .isLessThanZero
let rhsIsLessThanZero: Bool = other.isLessThanZero
//=--------------------------------------=
var qro = self.magnitude.quotientAndRemainderReportingOverflow(dividingBy: other.magnitude)
var qro = NBK.bitCast(self.magnitude.quotientAndRemainderReportingOverflow(dividingBy: other.magnitude)) as PVO<QR<Self, Digit>>
//=--------------------------------------=
if lhsIsLessThanZero != rhsIsLessThanZero {
qro.partialValue.quotient.formTwosComplement()
Expand All @@ -55,11 +55,11 @@ extension NBKDoubleWidth {
qro.partialValue.remainder.formTwosComplement()
}

if lhsIsLessThanZero, rhsIsLessThanZero, qro.partialValue.quotient.mostSignificantBit {
if lhsIsLessThanZero && rhsIsLessThanZero && qro.partialValue.quotient.isLessThanZero {
qro.overflow = true
}
//=--------------------------------------=
return PVO(QR(Self(bitPattern: qro.partialValue.quotient), Digit(bitPattern: qro.partialValue.remainder)), qro.overflow)
return qro as PVO<QR<Self, Digit>>
}
}

Expand All @@ -82,7 +82,7 @@ extension NBKDoubleWidth where High == High.Magnitude {
@_disfavoredOverload @inlinable mutating func formQuotientWithRemainderReportingOverflow(dividingBy other: Digit) -> PVO<Digit> {
//=--------------------------------------=
if other.isZero {
return PVO(Digit(bitPattern: self.first), true)
return NBK.bitCast(PVO(self.first, true))
}
//=--------------------------------------=
var remainder = UInt.zero
Expand Down
16 changes: 8 additions & 8 deletions Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension NBKDoubleWidth {
let lhsIsLessThanZero: Bool = self .isLessThanZero
let rhsIsLessThanZero: Bool = other.isLessThanZero
//=--------------------------------------=
var qro = Magnitude.divide2222(self.magnitude, by: other.magnitude) as PVO<QR<Magnitude, Magnitude>>
var qro = NBK.bitCast(Magnitude.divide2222(self.magnitude, by: other.magnitude)) as PVO<QR<Self, Self>>
//=--------------------------------------=
if lhsIsLessThanZero != rhsIsLessThanZero {
qro.partialValue.quotient.formTwosComplement()
Expand All @@ -58,17 +58,17 @@ extension NBKDoubleWidth {
qro.partialValue.remainder.formTwosComplement()
}

if lhsIsLessThanZero, rhsIsLessThanZero, qro.partialValue.quotient.mostSignificantBit {
if lhsIsLessThanZero && rhsIsLessThanZero && qro.partialValue.quotient.isLessThanZero {
qro.overflow = true
}
//=--------------------------------------=
return PVO(QR(Self(bitPattern: qro.partialValue.quotient), Self(bitPattern: qro.partialValue.remainder)), qro.overflow)
return qro as PVO<QR<Self, Self>>
}

//=------------------------------------------------------------------------=
// MARK: Transformations x Full Width
//=------------------------------------------------------------------------=

@inlinable public func dividingFullWidth(_ other: HL<Self, Magnitude>) -> QR<Self, Self> {
self.dividingFullWidth(DoubleWidth(descending: other))
}
Expand All @@ -91,7 +91,7 @@ extension NBKDoubleWidth {
let rhsIsLessThanZero: Bool = self .isLessThanZero
let minus: Bool = lhsIsLessThanZero != rhsIsLessThanZero
//=--------------------------------------=
var qro = Magnitude.divide4222(other.magnitude, by: self.magnitude) as PVO<QR<Magnitude, Magnitude>>
var qro = NBK.bitCast(Magnitude.divide4222(other.magnitude, by: self.magnitude)) as PVO<QR<Self, Self>>
//=--------------------------------------=
if minus {
qro.partialValue.quotient.formTwosComplement()
Expand All @@ -101,11 +101,11 @@ extension NBKDoubleWidth {
qro.partialValue.remainder.formTwosComplement()
}

if Self.isSigned, qro.partialValue.quotient.mostSignificantBit != minus {
if minus != qro.partialValue.quotient.isLessThanZero {
qro.overflow = qro.overflow || !(minus && qro.partialValue.quotient.isZero)
}
//=--------------------------------------=
return PVO(QR(Self(bitPattern: qro.partialValue.quotient), Self(bitPattern: qro.partialValue.remainder)), qro.overflow)
return qro as PVO<QR<Self, Self>>
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extension NBKDoubleWidth {
minus = product.high.formTwosComplementSubsequence(minus)
}
//=--------------------------------------=
return HL(Self(bitPattern: product.high), product.low)
return NBK.bitCast(product) as HL<Self, Magnitude>
}
}

Expand Down

0 comments on commit ad1f93b

Please sign in to comment.