From 906622f485acdf60f866463ce3c36166d8b5336a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Thu, 28 Sep 2023 09:09:56 +0200 Subject: [PATCH] [NBKCoreKit] Sign and magnitude decoding (#86). --- Sources/NBKCoreKit/Aliases.swift | 3 + .../NBKIntegerDescription+Decoding.swift | 95 ++++++- .../Documentation.docc/Documentation.md | 1 + .../NBKIntegerDescription+Decoding.swift | 257 +++++++++++++----- 4 files changed, 273 insertions(+), 83 deletions(-) diff --git a/Sources/NBKCoreKit/Aliases.swift b/Sources/NBKCoreKit/Aliases.swift index 76bf9652..39a3e5b0 100644 --- a/Sources/NBKCoreKit/Aliases.swift +++ b/Sources/NBKCoreKit/Aliases.swift @@ -22,3 +22,6 @@ public typealias PVO = (partialValue: PV, overflow: Bool) /// A quotient and a remainder, relating to division. public typealias QR = (quotient: Q, remainder: R) + +/// A sign and a magnitude. +public typealias SM = (sign: FloatingPointSign, magnitude: M) diff --git a/Sources/NBKCoreKit/Private/NBKIntegerDescription+Decoding.swift b/Sources/NBKCoreKit/Private/NBKIntegerDescription+Decoding.swift index 67d0d5f4..4fd73a90 100644 --- a/Sources/NBKCoreKit/Private/NBKIntegerDescription+Decoding.swift +++ b/Sources/NBKCoreKit/Private/NBKIntegerDescription+Decoding.swift @@ -53,12 +53,13 @@ extension NBK.IntegerDescription { } //=--------------------------------------------------------------------= - // MARK: Utilities + // MARK: Utilities x Binary Integer //=--------------------------------------------------------------------= @inlinable public func decode( _ description: some StringProtocol, as type: T.Type = T.self) -> T? { - var description = String(description); return description.withUTF8({ self.decode($0) }) + var description = String(description) + return description.withUTF8({ self.decode($0) }) } @inlinable public func decode( @@ -68,10 +69,48 @@ extension NBK.IntegerDescription { @inlinable public func decode( _ description: NBK.UnsafeUTF8, as type: T.Type = T.self) -> T? { + guard let components: SM = self.decodeCodeBlock(description) else { return nil } + return T(sign: components.sign, magnitude: components.magnitude) + } + + //=--------------------------------------------------------------------= + // MARK: Utilities x Sign & Magnitude + //=--------------------------------------------------------------------= + + @inlinable public func decode( + _ description: some StringProtocol, as type: SM.Type = SM.self) -> SM? { + var description = String(description) + return description.withUTF8({ self.decode($0) }) + } + + @inlinable public func decode( + _ description: StaticString, as type: SM.Type = SM.self) -> SM? { + description.withUTF8Buffer({ self.decode($0) }) + } + + @inlinable public func decode( + _ description: NBK.UnsafeUTF8, as type: SM.Type = SM.self) -> SM? { + self.decodeCodeBlock(description) + } + + //=--------------------------------------------------------------------= + // MARK: Utilities x Private x Algorithms + //=--------------------------------------------------------------------= + + /// ### Development 1 + /// + /// Consider throwing errors instead of returning optionals. + /// + /// ### Development 2 + /// + /// `@inline(always)` is required for performance reasons (with optionals, not errors). + /// + @inline(__always) @inlinable func decodeCodeBlock( + _ description: NBK.UnsafeUTF8, as type: SM.Type = SM.self) -> SM? { let components = NBK.IntegerDescription.makeSignBody(from: description) let digits = NBK.UnsafeUTF8(rebasing: components.body) - guard let magnitude: T.Magnitude = NBK.IntegerDescription.decode(digits: digits, solution: self.solution) else { return nil } - return T(sign: components.sign, magnitude: magnitude) + guard let magnitude: M = NBK.IntegerDescription.decode(digits: digits, solution: self.solution) else { return nil } + return SM(sign: components.sign, magnitude: magnitude) } } @@ -100,7 +139,7 @@ extension NBK.IntegerDescription { /// - Note: The decoding strategy is case insensitive. /// @frozen public struct DecoderDecodingRadix { - + //=--------------------------------------------------------------------= // MARK: Initializers //=--------------------------------------------------------------------= @@ -108,7 +147,7 @@ extension NBK.IntegerDescription { @inlinable public init() { } //=--------------------------------------------------------------------= - // MARK: Utilities + // MARK: Utilities x Binary Integer //=--------------------------------------------------------------------= @inlinable public func decode( @@ -124,11 +163,49 @@ extension NBK.IntegerDescription { @inlinable public func decode( _ description: NBK.UnsafeUTF8, as type: T.Type = T.self) -> T? { + guard let components: SM = self.decodeCodeBlock(description) else { return nil } + return T(sign: components.sign, magnitude: components.magnitude) + } + + //=--------------------------------------------------------------------= + // MARK: Utilities x Sign & Magnitude + //=--------------------------------------------------------------------= + + @inlinable public func decode( + _ description: some StringProtocol, as type: SM.Type = SM.self) -> SM? { + var description = String(description) + return description.withUTF8({ self.decode($0) }) + } + + @inlinable public func decode( + _ description: StaticString, as type: SM.Type = SM.self) -> SM? { + description.withUTF8Buffer({ self.decode($0) }) + } + + @inlinable public func decode( + _ description: NBK.UnsafeUTF8, as type: SM.Type = SM.self) -> SM? { + self.decodeCodeBlock(description) + } + + //=--------------------------------------------------------------------= + // MARK: Utilities x Private x Algorithms + //=--------------------------------------------------------------------= + + /// ### Development 1 + /// + /// Consider throwing errors instead of returning optionals. + /// + /// ### Development 2 + /// + /// `@inline(always)` is required for performance reasons (with optionals, not errors). + /// + @inline(__always) @inlinable func decodeCodeBlock( + _ description: NBK.UnsafeUTF8, as type: SM.Type = SM.self) -> SM? { let components = NBK.IntegerDescription.makeSignRadixBody(from: description) let solution = AnyRadixSolution(components.radix) - let digits = NBK.UnsafeUTF8(rebasing: components.body ) - guard let magnitude: T.Magnitude = NBK.IntegerDescription.decode(digits: digits, solution: solution) else { return nil } - return T(sign: components.sign, magnitude: magnitude) + let digits = NBK.UnsafeUTF8(rebasing: components.body) + guard let magnitude: M = NBK.IntegerDescription.decode(digits: digits, solution: solution) else { return nil } + return SM(sign: components.sign, magnitude: magnitude) } } } diff --git a/Sources/Numberick/Documentation.docc/Documentation.md b/Sources/Numberick/Documentation.docc/Documentation.md index bc5f8dd0..56828a13 100644 --- a/Sources/Numberick/Documentation.docc/Documentation.md +++ b/Sources/Numberick/Documentation.docc/Documentation.md @@ -135,4 +135,5 @@ Int256(5) % Int(5), UInt256(5) % UInt(5) - ``LH`` - ``PVO`` - ``QR`` +- ``SM`` - ``NBK`` diff --git a/Tests/NBKCoreKitTests/Private/NBKIntegerDescription+Decoding.swift b/Tests/NBKCoreKitTests/Private/NBKIntegerDescription+Decoding.swift index 362bef87..c1f52c48 100644 --- a/Tests/NBKCoreKitTests/Private/NBKIntegerDescription+Decoding.swift +++ b/Tests/NBKCoreKitTests/Private/NBKIntegerDescription+Decoding.swift @@ -13,101 +13,167 @@ import NBKCoreKit import XCTest //*============================================================================* -// MARK: * NBK x Integer Description x Decoding +// MARK: * NBK x Integer Description x Decoding x Binary Integer //*============================================================================* -final class NBKIntegerDescriptionTestsOnDecoding: XCTestCase { +final class NBKIntegerDescriptionTestsOnDecodingAsBinaryInteger: XCTestCase { //=------------------------------------------------------------------------= // MARK: Tests //=------------------------------------------------------------------------= func testDecodingInt32() { - NBKAssertDecoding(Int32?(nil), 16, "-80000001") - NBKAssertDecoding(Int32 .min, 16, "-80000000") - NBKAssertDecoding(Int32 .max, 16, "+7fffffff") - NBKAssertDecoding(Int32?(nil), 16, "+80000000") + NBKAssertDecodingAsBinaryInteger(Int32?(nil), 10, "-2147483649") + NBKAssertDecodingAsBinaryInteger(Int32 .min, 10, "-2147483648") + NBKAssertDecodingAsBinaryInteger(Int32 .max, 10, "+2147483647") + NBKAssertDecodingAsBinaryInteger(Int32?(nil), 10, "+2147483648") - NBKAssertDecoding(Int32?(nil), 10, "-2147483649") - NBKAssertDecoding(Int32 .min, 10, "-2147483648") - NBKAssertDecoding(Int32 .max, 10, "+2147483647") - NBKAssertDecoding(Int32?(nil), 10, "+2147483648") + NBKAssertDecodingAsBinaryInteger(Int32?(nil), 16, "-0080000001") + NBKAssertDecodingAsBinaryInteger(Int32 .min, 16, "-0080000000") + NBKAssertDecodingAsBinaryInteger(Int32 .max, 16, "+007fffffff") + NBKAssertDecodingAsBinaryInteger(Int32?(nil), 16, "+0080000000") - NBKAssertDecodingByDecodingRadix(Int32?(nil), 16, "-0x80000001") - NBKAssertDecodingByDecodingRadix(Int32 .min, 16, "-0x80000000") - NBKAssertDecodingByDecodingRadix(Int32 .max, 16, "+0x7fffffff") - NBKAssertDecodingByDecodingRadix(Int32?(nil), 16, "+0x80000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32?(nil), 10, "-2147483649") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32 .min, 10, "-2147483648") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32 .max, 10, "+2147483647") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32?(nil), 10, "+2147483648") - NBKAssertDecodingByDecodingRadix(Int32?(nil), 10, "-2147483649") - NBKAssertDecodingByDecodingRadix(Int32 .min, 10, "-2147483648") - NBKAssertDecodingByDecodingRadix(Int32 .max, 10, "+2147483647") - NBKAssertDecodingByDecodingRadix(Int32?(nil), 10, "+2147483648") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32?(nil), 16, "-0x80000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32 .min, 16, "-0x80000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32 .max, 16, "+0x7fffffff") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int32?(nil), 16, "+0x80000000") } func testDecodingInt64() { - NBKAssertDecoding(Int64?(nil), 16, "-8000000000000001") - NBKAssertDecoding(Int64 .min, 16, "-8000000000000000") - NBKAssertDecoding(Int64 .max, 16, "+7fffffffffffffff") - NBKAssertDecoding(Int64?(nil), 16, "+8000000000000000") + NBKAssertDecodingAsBinaryInteger(Int64?(nil), 10, "-9223372036854775809") + NBKAssertDecodingAsBinaryInteger(Int64 .min, 10, "-9223372036854775808") + NBKAssertDecodingAsBinaryInteger(Int64 .max, 10, "+9223372036854775807") + NBKAssertDecodingAsBinaryInteger(Int64?(nil), 10, "+9223372036854775808") - NBKAssertDecoding(Int64?(nil), 10, "-9223372036854775809") - NBKAssertDecoding(Int64 .min, 10, "-9223372036854775808") - NBKAssertDecoding(Int64 .max, 10, "+9223372036854775807") - NBKAssertDecoding(Int64?(nil), 10, "+9223372036854775808") + NBKAssertDecodingAsBinaryInteger(Int64?(nil), 16, "-0008000000000000001") + NBKAssertDecodingAsBinaryInteger(Int64 .min, 16, "-0008000000000000000") + NBKAssertDecodingAsBinaryInteger(Int64 .max, 16, "+0007fffffffffffffff") + NBKAssertDecodingAsBinaryInteger(Int64?(nil), 16, "+0008000000000000000") - NBKAssertDecodingByDecodingRadix(Int64?(nil), 16, "-0x8000000000000001") - NBKAssertDecodingByDecodingRadix(Int64 .min, 16, "-0x8000000000000000") - NBKAssertDecodingByDecodingRadix(Int64 .max, 16, "+0x7fffffffffffffff") - NBKAssertDecodingByDecodingRadix(Int64?(nil), 16, "+0x8000000000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64?(nil), 10, "-9223372036854775809") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64 .min, 10, "-9223372036854775808") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64 .max, 10, "+9223372036854775807") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64?(nil), 10, "+9223372036854775808") - NBKAssertDecodingByDecodingRadix(Int64?(nil), 10, "-9223372036854775809") - NBKAssertDecodingByDecodingRadix(Int64 .min, 10, "-9223372036854775808") - NBKAssertDecodingByDecodingRadix(Int64 .max, 10, "+9223372036854775807") - NBKAssertDecodingByDecodingRadix(Int64?(nil), 10, "+9223372036854775808") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64?(nil), 16, "-0x08000000000000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64 .min, 16, "-0x08000000000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64 .max, 16, "+0x07fffffffffffffff") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(Int64?(nil), 16, "+0x08000000000000000") } func testDecodingUInt32() { - NBKAssertDecoding(UInt32?(nil), 16, "-00000001") - NBKAssertDecoding(UInt32 .min, 16, "000000000") - NBKAssertDecoding(UInt32 .max, 16, "0ffffffff") - NBKAssertDecoding(UInt32?(nil), 16, "100000000") - - NBKAssertDecoding(UInt32?(nil), 10, "-000000001") - NBKAssertDecoding(UInt32 .min, 10, "0000000000") - NBKAssertDecoding(UInt32 .max, 10, "4294967295") - NBKAssertDecoding(UInt32?(nil), 10, "4294967296") + NBKAssertDecodingAsBinaryInteger(UInt32?(nil), 10, "-0000000001") + NBKAssertDecodingAsBinaryInteger(UInt32 .min, 10, "-0000000000") + NBKAssertDecodingAsBinaryInteger(UInt32 .max, 10, "+4294967295") + NBKAssertDecodingAsBinaryInteger(UInt32?(nil), 10, "+4294967296") - NBKAssertDecodingByDecodingRadix(UInt32?(nil), 16, "-0x00000001") - NBKAssertDecodingByDecodingRadix(UInt32 .min, 16, "0x000000000") - NBKAssertDecodingByDecodingRadix(UInt32 .max, 16, "0x0ffffffff") - NBKAssertDecodingByDecodingRadix(UInt32?(nil), 16, "0x100000000") - - NBKAssertDecodingByDecodingRadix(UInt32?(nil), 10, "-000000001") - NBKAssertDecodingByDecodingRadix(UInt32 .min, 10, "0000000000") - NBKAssertDecodingByDecodingRadix(UInt32 .max, 10, "4294967295") - NBKAssertDecodingByDecodingRadix(UInt32?(nil), 10, "4294967296") + NBKAssertDecodingAsBinaryInteger(UInt32?(nil), 16, "-0000000001") + NBKAssertDecodingAsBinaryInteger(UInt32 .min, 16, "-0000000000") + NBKAssertDecodingAsBinaryInteger(UInt32 .max, 16, "+00ffffffff") + NBKAssertDecodingAsBinaryInteger(UInt32?(nil), 16, "+0100000000") + + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32?(nil), 10, "-00000000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32 .min, 10, "-00000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32 .max, 10, "+04294967295") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32?(nil), 10, "+04294967296") + + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32?(nil), 16, "-0x000000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32 .min, 16, "-0x000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32 .max, 16, "+0x0ffffffff") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt32?(nil), 16, "+0x100000000") } func testDecodingUInt64() { - NBKAssertDecoding(UInt64?(nil), 16, "-0000000000000001") - NBKAssertDecoding(UInt64 .min, 16, "00000000000000000") - NBKAssertDecoding(UInt64 .max, 16, "0ffffffffffffffff") - NBKAssertDecoding(UInt64?(nil), 16, "10000000000000000") + NBKAssertDecodingAsBinaryInteger(UInt64?(nil), 10, "-00000000000000000001") + NBKAssertDecodingAsBinaryInteger(UInt64 .min, 10, "-00000000000000000000") + NBKAssertDecodingAsBinaryInteger(UInt64 .max, 10, "+18446744073709551615") + NBKAssertDecodingAsBinaryInteger(UInt64?(nil), 10, "+18446744073709551616") + + NBKAssertDecodingAsBinaryInteger(UInt64?(nil), 16, "-00000000000000000001") + NBKAssertDecodingAsBinaryInteger(UInt64 .min, 16, "-00000000000000000000") + NBKAssertDecodingAsBinaryInteger(UInt64 .max, 16, "+0000ffffffffffffffff") + NBKAssertDecodingAsBinaryInteger(UInt64?(nil), 16, "+00010000000000000000") + + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64?(nil), 10, "-00000000000000000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64 .min, 10, "-00000000000000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64 .max, 10, "+18446744073709551615") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64?(nil), 10, "+18446744073709551616") + + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64?(nil), 16, "-0x000000000000000001") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64 .min, 16, "-0x000000000000000000") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64 .max, 16, "+0x00ffffffffffffffff") + NBKAssertDecodingByDecodingRadixAsBinaryInteger(UInt64?(nil), 16, "+0x010000000000000000") + } + + //=------------------------------------------------------------------------= + // MARK: Tests x Miscellaneous + //=------------------------------------------------------------------------= + + func testDecodingStringWithoutDigitsReturnsNil() { + NBKAssertDecodingAsBinaryInteger( Int32?(nil), 10, "+") + NBKAssertDecodingAsBinaryInteger( Int64?(nil), 16, "+") + NBKAssertDecodingAsBinaryInteger(UInt32?(nil), 10, "+") + NBKAssertDecodingAsBinaryInteger(UInt64?(nil), 16, "+") + } +} - NBKAssertDecoding(UInt64?(nil), 10, "-0000000000000000001") - NBKAssertDecoding(UInt64 .min, 10, "00000000000000000000") - NBKAssertDecoding(UInt64 .max, 10, "18446744073709551615") - NBKAssertDecoding(UInt64?(nil), 10, "18446744073709551616") +//*============================================================================* +// MARK: * NBK x Integer Description x Decoding x Sign & Magnitude +//*============================================================================* + +final class NBKIntegerDescriptionTestsOnDecodingAsSignMagnitude: XCTestCase { + + //=------------------------------------------------------------------------= + // MARK: Tests + //=------------------------------------------------------------------------= + + func testDecodingUInt32() { + NBKAssertDecodingAsSignMagnitude( nil, UInt32?(nil), 10, "-4294967296") + NBKAssertDecodingAsSignMagnitude(.minus, UInt32 .max, 10, "-4294967295") + NBKAssertDecodingAsSignMagnitude(.plus, UInt32 .max, 10, "+4294967295") + NBKAssertDecodingAsSignMagnitude( nil, UInt32?(nil), 10, "+4294967296") + + NBKAssertDecodingAsSignMagnitude( nil, UInt32?(nil), 16, "-0100000000") + NBKAssertDecodingAsSignMagnitude(.minus, UInt32 .max, 16, "-00ffffffff") + NBKAssertDecodingAsSignMagnitude(.plus, UInt32 .max, 16, "+00ffffffff") + NBKAssertDecodingAsSignMagnitude( nil, UInt32?(nil), 16, "+0100000000") + + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt32?(nil), "-004294967296") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.minus, UInt32 .max, "-004294967295") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.plus, UInt32 .max, "+004294967295") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt32?(nil), "+004294967296") - NBKAssertDecodingByDecodingRadix(UInt64?(nil), 16, "-0x0000000000000001") - NBKAssertDecodingByDecodingRadix(UInt64 .min, 16, "0x00000000000000000") - NBKAssertDecodingByDecodingRadix(UInt64 .max, 16, "0x0ffffffffffffffff") - NBKAssertDecodingByDecodingRadix(UInt64?(nil), 16, "0x10000000000000000") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt32?(nil), "-0x0100000000") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.minus, UInt32 .max, "-0x00ffffffff") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.plus, UInt32 .max, "+0x00ffffffff") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt32?(nil), "+0x0100000000") + } + + func testDecodingUInt64() { + NBKAssertDecodingAsSignMagnitude( nil, UInt64?(nil), 10, "-18446744073709551616") + NBKAssertDecodingAsSignMagnitude(.minus, UInt64 .max, 10, "-18446744073709551615") + NBKAssertDecodingAsSignMagnitude(.plus, UInt64 .max, 10, "+18446744073709551615") + NBKAssertDecodingAsSignMagnitude( nil, UInt64?(nil), 10, "+18446744073709551616") + + NBKAssertDecodingAsSignMagnitude( nil, UInt64?(nil), 16, "-00010000000000000000") + NBKAssertDecodingAsSignMagnitude(.minus, UInt64 .max, 16, "-0000ffffffffffffffff") + NBKAssertDecodingAsSignMagnitude(.plus, UInt64 .max, 16, "+0000ffffffffffffffff") + NBKAssertDecodingAsSignMagnitude( nil, UInt64?(nil), 16, "+00010000000000000000") - NBKAssertDecodingByDecodingRadix(UInt64?(nil), 10, "-0000000000000000001") - NBKAssertDecodingByDecodingRadix(UInt64 .min, 10, "00000000000000000000") - NBKAssertDecodingByDecodingRadix(UInt64 .max, 10, "18446744073709551615") - NBKAssertDecodingByDecodingRadix(UInt64?(nil), 10, "18446744073709551616") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt64?(nil), "-0018446744073709551616") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.minus, UInt64 .max, "-0018446744073709551615") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.plus, UInt64 .max, "+0018446744073709551615") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt64?(nil), "+0018446744073709551616") + + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt64?(nil), "-0x00010000000000000000") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.minus, UInt64 .max, "-0x0000ffffffffffffffff") + NBKAssertDecodingByDecodingRadixAsSignMagnitude(.plus, UInt64 .max, "+0x0000ffffffffffffffff") + NBKAssertDecodingByDecodingRadixAsSignMagnitude( nil, UInt64?(nil), "+0x00010000000000000000") } //=------------------------------------------------------------------------= @@ -115,10 +181,10 @@ final class NBKIntegerDescriptionTestsOnDecoding: XCTestCase { //=------------------------------------------------------------------------= func testDecodingStringWithoutDigitsReturnsNil() { - NBKAssertDecoding( Int32?(nil), 10, "+") - NBKAssertDecoding( Int64?(nil), 16, "+") - NBKAssertDecoding(UInt32?(nil), 10, "+") - NBKAssertDecoding(UInt64?(nil), 16, "+") + NBKAssertDecodingAsSignMagnitude(nil, UInt32?(nil), 10, "+") + NBKAssertDecodingAsSignMagnitude(nil, UInt32?(nil), 16, "+") + NBKAssertDecodingAsSignMagnitude(nil, UInt64?(nil), 10, "+") + NBKAssertDecodingAsSignMagnitude(nil, UInt64?(nil), 16, "+") } } @@ -209,7 +275,7 @@ final class NBKIntegerDescriptionTestsOnDecodingOneDigit: XCTestCase { // MARK: * NBK x Integer Description x Decoding x Assertions //*============================================================================* -private func NBKAssertDecoding( +private func NBKAssertDecodingAsBinaryInteger( _ result: T?, _ radix: Int, _ description: StaticString, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= @@ -217,9 +283,29 @@ file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= XCTAssertEqual(result, decoder.decode(description), file: file, line: line) XCTAssertEqual(result, decoder.decode(description.description), file: file, line: line) + //=------------------------------------------= } -private func NBKAssertDecodingByDecodingRadix( +private func NBKAssertDecodingAsSignMagnitude( +_ sign: FloatingPointSign?, _ magnitude: M?, _ radix: Int, _ description: StaticString, +file: StaticString = #file, line: UInt = #line) { + //=------------------------------------------= + let decoder = NBK.IntegerDescription.Decoder(radix: radix) + //=------------------------------------------= + brr: do { + let decoded: SM? = decoder.decode(description) + XCTAssertEqual(sign, decoded?.sign, file: file, line: line) + XCTAssertEqual(magnitude, decoded?.magnitude, file: file, line: line) + } + + brr: do { + let decoded: SM? = decoder.decode(description.description) + XCTAssertEqual(sign, decoded?.sign, file: file, line: line) + XCTAssertEqual(magnitude, decoded?.magnitude, file: file, line: line) + } +} + +private func NBKAssertDecodingByDecodingRadixAsBinaryInteger( _ result: T?, _ radix: Int, _ description: StaticString, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= @@ -229,6 +315,29 @@ file: StaticString = #file, line: UInt = #line) { XCTAssertEqual(result, decoder.decode(description.description), file: file, line: line) } +private func NBKAssertDecodingByDecodingRadixAsSignMagnitude( +_ sign: FloatingPointSign?, _ magnitude: M?, _ description: StaticString, +file: StaticString = #file, line: UInt = #line) { + //=------------------------------------------= + let decoder = NBK.IntegerDescription.DecoderDecodingRadix() + //=------------------------------------------= + brr: do { + let decoded: SM? = decoder.decode(description) + XCTAssertEqual(sign, decoded?.sign, file: file, line: line) + XCTAssertEqual(magnitude, decoded?.magnitude, file: file, line: line) + } + + brr: do { + let decoded: SM? = decoder.decode(description.description) + XCTAssertEqual(sign, decoded?.sign, file: file, line: line) + XCTAssertEqual(magnitude, decoded?.magnitude, file: file, line: line) + } +} + +//=----------------------------------------------------------------------------= +// MARK: + Digit +//=----------------------------------------------------------------------------= + private func NBKAssertDecodingDigitsByTruncating( _ result: T?, _ radix: Int, _ digits: String, file: StaticString = #file, line: UInt = #line) {