With the release of iOS 18 Developer Beta 5 and Public Beta 3, my team received reports from customers that all negative values in our app were showing as positives, which led to major confusion.
We narrowed down the issue to a change to the initializer for Decimal: Decimal(sign:exponent:significand)
. Prior to Beta 5, the sign
passed into the initializer would be the sign of the decimal. Passing plus
would result in a positive decimal, and passing minus
would result in a negative decimal. This is regardless of the sign of the significant. In Beta 5, it seems that the sign
passed into the init, and the sign of the significand
are now multiplied together. This means that passing .minus
for sign
and a negative Decimal for significand
results in an unexpectedly positive Decimal value in Beta 5 alone. This behavior does not seem to be explicitly documented.
I created a quick playground to illustrate the issue. Here's the code:
// Expected Value: 20
// Actual Value: 20
let positiveDecimal = Decimal(sign: .plus, exponent: 1, significand: 2)
// Expected Value: 20
// Actual Value (15.4.0, 16.0 Beta 4): 20
// Actual Value (16.0 Beta 5): -20
let positiveDecimalWithNegativeSignificand = Decimal(sign: .plus, exponent: 1, significand: -2)
// Expected Value: -20
// Actual Value: -20
let negativeDecimal = Decimal(sign: .minus, exponent: 1, significand: 2)
// Expected Value: -20
// Actual Value (15.4.0, 16.0 Beta 4): -20
// Actual Value (16.0 Beta 5): 20
let negativeDecimalWithNegativeSignificand = Decimal(sign: .minus, exponent: 1, significand: -2)
Here is the result of running the playground in Xcode 16.0 Beta 4 (and 15.4.0):
And here is the result of running it in Xcode 16.0 Beta 5:
I've tracked down the issue to a PR in the swift-foundation repo from 3 weeks ago, which seems to pull a commit from the swift-corelibs-foundation repo.
For anyone else who finds this thread looking for a solution, in the mean time you can wrap the significant in abs
and this should ensure consistent behavior between iOS 18 Beta 5 and prior iOS versions.