Skip to content

Commit

Permalink
Add: Count/isPowerOf2 (#109).
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Oct 11, 2024
1 parent b1e7d91 commit 3379092
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Sources/CoreKit/Models/Count+Comparison.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,17 @@ extension Count {
@inlinable public var isInfinite: Bool {
Bool(self.base.appendix)
}

/// Indicates whether this value is a power of `2`.
///
/// - Note: `log2(&0+1)` is the only representable infinite power of `2`.
///
@inlinable public var isPowerOf2: Bool {
if self.base.isPositive {
return (self.base & self.base.decremented().unchecked()).isZero

} else {
return (self == Self.infinity)
}
}
}
3 changes: 2 additions & 1 deletion Tests/UltimathnumTests/BinaryInteger+Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ import TestKit2
whereIs(type)

func whereIs<T>(_ type: T.Type) where T: BinaryInteger {
#expect(T.size.isPowerOf2)
#expect(T.size >= T.Element .size)
#expect(T.size == T.Magnitude.size)
#expect(T.size == T.Signitude.size)

Ɣexpect(MemoryLayout<T>.self, equals: MemoryLayout<T.Magnitude>.self)
Ɣexpect(MemoryLayout<T>.self, equals: MemoryLayout<T.Signitude>.self)

Expand Down
32 changes: 27 additions & 5 deletions Tests/UltimathnumTests/Count+Comparison.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ import TestKit2
// MARK: Tests
//=------------------------------------------------------------------------=

@Test(arguments: fuzzers)
func comparisonIsLikeUnsignedIntegerComparison(_ randomness: consuming FuzzerInt) {
for _ in 0 ..< 256 {
let lhs = UX.entropic(using: &randomness)
let rhs = UX.entropic(using: &randomness)
Ɣexpect(Count(raw: lhs), equals: Count(raw: rhs), is: lhs.compared(to: rhs))
}
}

@Test(arguments: fuzzers)
func isZeroIsLikeBinaryIntegerIsZero(_ randomness: consuming FuzzerInt) {
for _ in 0 ..< 256 {
Expand All @@ -38,11 +47,24 @@ import TestKit2
}

@Test(arguments: fuzzers)
func comparisonIsLikeUnsignedIntegerComparison(_ randomness: consuming FuzzerInt) {
for _ in 0 ..< 256 {
let lhs = UX.entropic(using: &randomness)
let rhs = UX.entropic(using: &randomness)
Ɣexpect(Count(raw: lhs), equals: Count(raw: rhs), is: lhs.compared(to: rhs))
func isPowerOf2IsNormalExceptMaxIsPowerOf2(_ randomness: consuming FuzzerInt) {
#expect( Count(raw: UX.max).isPowerOf2)
#expect(!Count(raw: IX.min).isPowerOf2)
#expect(!Count(raw: IX.max).isPowerOf2)
#expect(!Count(raw: UX.min).isPowerOf2)

for distance in 0 ..< IX(size: IX.self) - 1 {
#expect(Count(IX.lsb << distance).isPowerOf2)
}

for _ in 0 ..< conditional(debug: 64, release: 256) {
let random = IX.entropic(as: .natural, using: &randomness)
let expectation: Bool = random.count(Bit.one) == Count(01)
#expect(Count(random).isPowerOf2 == expectation)
}

for _ in 0 ..< conditional(debug: 64, release: 256) {
#expect(!Count(raw: IX.random(in: IX.min...IX(-2), using: &randomness)).isPowerOf2)
}
}
}

0 comments on commit 3379092

Please sign in to comment.