Skip to content

Commit ee8f9ee

Browse files
committed
Better handle edge cases in minRepresentableNumber for RN2
1 parent 123971a commit ee8f9ee

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

Sources/SignedNumberRepresentation.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,23 @@ public enum SignedNumberRepresentation {
3131
precondition(bias >= 0)
3232
return -bias
3333
case .radixNegativeTwo:
34-
if bitsCount >= Int.bitWidth {
35-
return Int.min
36-
}
3734
// Minimum corresponds to all of the odd bits being set.
3835
var result = 0
3936
var mult = 2
40-
for _ in stride(from: 1, to: bitsCount, by: 2) {
37+
for i in stride(from: 1, to: bitsCount, by: 2) {
4138
result -= mult
42-
mult *= 4
39+
let (newMult, overflow) = mult.multipliedReportingOverflow(by: 4)
40+
if overflow {
41+
// This means that we reached the Int.min limit.
42+
// Since, the last, 63rd, bit is an odd bit, Int.min is encodable within 64 bits using RN2.
43+
// So if the loop would continue in the absence of the overflow, which would result in even smaller
44+
// values, we need to return Int.min as the correct answer.
45+
if i + 2 < bitsCount {
46+
result = Int.min
47+
}
48+
break
49+
}
50+
mult = newMult
4351
}
4452
return result
4553
}
@@ -67,6 +75,8 @@ public enum SignedNumberRepresentation {
6775
let (newMult, overflow) = mult.multipliedReportingOverflow(by: 4)
6876
if overflow {
6977
// This means that we reached the Int.max limit.
78+
// Since, the last, 63rd, bit is an odd bit, we cannot encode Int.max within 64 bits using RN2,
79+
// so the correct answer is always "all even bits set".
7080
break
7181
}
7282
mult = newMult

0 commit comments

Comments
 (0)