-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
| Previous ID | SR-3269 |
| Radar | None |
| Original Reporter | Jnosh (JIRA User) |
| Type | Bug |
| Status | Resolved |
| Resolution | Done |
Additional Detail from JIRA
| Votes | 0 |
| Component/s | Standard Library |
| Labels | Bug |
| Assignee | None |
| Priority | Medium |
md5: eb6c13d3ddfbc5d703671cbaac11a5dc
Issue Description:
The overflow is triggered regardless of the value of by or to.
Example:
// Unsigned integer > IntMax.max
let value = 0xFFFF_FFFF_FF00_0000 as UInt
// OK
let add = value + 0x1000
// Abort due to overflow
let advanced = value.advaced(by: 0x1000)The issue lies with the default implementation for advanced & distance on UnsignedInteger (stdlib/public/core/FixedPoint.swift.gyb). The calculations are performed on intermediate IntMax values. The UnsignedInteger is cast to IntMax using numericCast() which aborts when the UnsignedInteger is larger than IntMax.max.
I can submit a pull request with a fix but I wanted to check first that this is not intended behaviour? (Probably not but I'm just surprised no one hit this case before 😛).
Also, regarding a potential fix, I see two general approaches:
-
(Ab)Use two's complement arithmetic. Simplest but I don't know what the policy is for the Stdlib regarding binary representation. i.e. is it OK to assume two's complement?
-
Don't cast to a signed type at all and switch on the stride's sign to decide whether to add or subtract. Would not depend on binary representation but adds a branch...