diff --git a/Sources/NBKCoreKit/NBKCoreInteger.swift b/Sources/NBKCoreKit/NBKCoreInteger.swift index 3f9f1be0..49d84387 100644 --- a/Sources/NBKCoreKit/NBKCoreInteger.swift +++ b/Sources/NBKCoreKit/NBKCoreInteger.swift @@ -120,14 +120,14 @@ extension NBKCoreInteger { @inlinable public func dividingFullWidthReportingOverflow(_ other: HL) -> PVO> { //=--------------------------------------= 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 if lhsIsLessThanZero { var carry = true carry = lhsMagnitude.low .formTwosComplementSubsequence(carry) @@ -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> //=--------------------------------------= if minus { qro.partialValue.quotient.formTwosComplement() @@ -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> } } diff --git a/Sources/NBKCoreKit/Private/BitCast.swift b/Sources/NBKCoreKit/Private/BitCast.swift new file mode 100644 index 00000000..79952cc9 --- /dev/null +++ b/Sources/NBKCoreKit/Private/BitCast.swift @@ -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(_ x: PVO) -> PVO where + A0: NBKBitPatternConvertible, B0: NBKBitPatternConvertible, A0.BitPattern == B0.BitPattern { + PVO(partialValue: B0(bitPattern: x.partialValue), x.overflow) + } + + @inlinable public static func bitCast(_ x: HL) -> HL 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(_ x: QR) -> QR 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(_ x: PVO>) -> PVO> 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) + } +} diff --git a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Bitwise.swift b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Bitwise.swift index cd538e87..0e634e68 100644 --- a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Bitwise.swift +++ b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Bitwise.swift @@ -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))) } } diff --git a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division+Digit.swift b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division+Digit.swift index 0aadca6d..ce570ba4 100644 --- a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division+Digit.swift +++ b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division+Digit.swift @@ -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> //=--------------------------------------= if lhsIsLessThanZero != rhsIsLessThanZero { qro.partialValue.quotient.formTwosComplement() @@ -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> } } @@ -82,7 +82,7 @@ extension NBKDoubleWidth where High == High.Magnitude { @_disfavoredOverload @inlinable mutating func formQuotientWithRemainderReportingOverflow(dividingBy other: Digit) -> PVO { //=--------------------------------------= if other.isZero { - return PVO(Digit(bitPattern: self.first), true) + return NBK.bitCast(PVO(self.first, true)) } //=--------------------------------------= var remainder = UInt.zero diff --git a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift index 63b62bf0..0e423469 100644 --- a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift +++ b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift @@ -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> + var qro = NBK.bitCast(Magnitude.divide2222(self.magnitude, by: other.magnitude)) as PVO> //=--------------------------------------= if lhsIsLessThanZero != rhsIsLessThanZero { qro.partialValue.quotient.formTwosComplement() @@ -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> } - + //=------------------------------------------------------------------------= // MARK: Transformations x Full Width //=------------------------------------------------------------------------= - + @inlinable public func dividingFullWidth(_ other: HL) -> QR { self.dividingFullWidth(DoubleWidth(descending: other)) } @@ -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> + var qro = NBK.bitCast(Magnitude.divide4222(other.magnitude, by: self.magnitude)) as PVO> //=--------------------------------------= if minus { qro.partialValue.quotient.formTwosComplement() @@ -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> } } diff --git a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Multiplication.swift b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Multiplication.swift index d0965401..a9194a8d 100644 --- a/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Multiplication.swift +++ b/Sources/NBKDoubleWidthKit/NBKDoubleWidth+Multiplication.swift @@ -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 } }