@@ -1191,57 +1191,57 @@ public func NSDecimalAdd(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand:
11911191}
11921192
11931193fileprivate func integerAdd( _ result: inout WideDecimal , _ left: inout Decimal , _ right: inout Decimal ) -> NSDecimalNumber . CalculationError {
1194- var i : UInt32 = 0
1194+ var idx : UInt32 = 0
11951195 var carry : UInt16 = 0
1196- let c : UInt32 = min ( left. _length, right. _length)
1196+ let maxIndex : UInt32 = min ( left. _length, right. _length) // The highest index with bits set in both values
11971197
1198- while i < c {
1199- let li = UInt32 ( left [ i ] )
1200- let ri = UInt32 ( right [ i ] )
1201- let accumulator = li + ri + UInt32( carry)
1202- carry = UInt16 ( truncatingIfNeeded: accumulator >> 16 )
1203- result [ i ] = UInt16 ( truncatingIfNeeded: accumulator )
1204- i += 1
1198+ while idx < maxIndex {
1199+ let li = UInt32 ( left [ idx ] )
1200+ let ri = UInt32 ( right [ idx ] )
1201+ let sum = li + ri + UInt32( carry)
1202+ carry = UInt16 ( truncatingIfNeeded: sum >> 16 )
1203+ result [ idx ] = UInt16 ( truncatingIfNeeded: sum )
1204+ idx += 1
12051205 }
12061206
1207- while i < left. _length {
1207+ while idx < left. _length {
12081208 if carry != 0 {
1209- let li = UInt32 ( left [ i ] )
1210- let accumulator = li + UInt32( carry)
1211- carry = UInt16 ( truncatingIfNeeded: accumulator >> 16 )
1212- result [ i ] = UInt16 ( truncatingIfNeeded: accumulator )
1213- i += 1
1209+ let li = UInt32 ( left [ idx ] )
1210+ let sum = li + UInt32( carry)
1211+ carry = UInt16 ( truncatingIfNeeded: sum >> 16 )
1212+ result [ idx ] = UInt16 ( truncatingIfNeeded: sum )
1213+ idx += 1
12141214 } else {
1215- while i < left. _length {
1216- result [ i ] = left [ i ]
1217- i += 1
1215+ while idx < left. _length {
1216+ result [ idx ] = left [ idx ]
1217+ idx += 1
12181218 }
12191219 break
12201220 }
12211221 }
1222- while i < right. _length {
1222+ while idx < right. _length {
12231223 if carry != 0 {
1224- let ri = UInt32 ( right [ i ] )
1225- let accumulator = ri + UInt32( carry)
1226- carry = UInt16 ( truncatingIfNeeded: accumulator >> 16 )
1227- result [ i ] = UInt16 ( truncatingIfNeeded: accumulator )
1228- i += 1
1224+ let ri = UInt32 ( right [ idx ] )
1225+ let sum = ri + UInt32( carry)
1226+ carry = UInt16 ( truncatingIfNeeded: sum >> 16 )
1227+ result [ idx ] = UInt16 ( truncatingIfNeeded: sum )
1228+ idx += 1
12291229 } else {
1230- while i < right. _length {
1231- result [ i ] = right [ i ]
1232- i += 1
1230+ while idx < right. _length {
1231+ result [ idx ] = right [ idx ]
1232+ idx += 1
12331233 }
12341234 break
12351235 }
12361236 }
1237- result. _length = i
1237+ result. _length = idx
12381238
12391239 if carry != 0 {
1240- result [ i ] = carry
1241- i += 1
1242- result. _length = i
1240+ result [ idx ] = carry
1241+ idx += 1
1242+ result. _length = idx
12431243 }
1244- if i > Decimal . maxSize {
1244+ if idx > Decimal . maxSize {
12451245 return . overflow
12461246 }
12471247
@@ -1256,46 +1256,48 @@ fileprivate func integerAdd(_ result: inout WideDecimal, _ left: inout Decimal,
12561256// give b-a...
12571257//
12581258fileprivate func integerSubtract( _ result: inout Decimal , _ left: inout Decimal , _ right: inout Decimal ) -> NSDecimalNumber . CalculationError {
1259- var i : UInt32 = 0
1259+ var idx : UInt32 = 0
1260+ let maxIndex : UInt32 = min ( left. _length, right. _length) // The highest index with bits set in both values
12601261 var borrow : UInt16 = 0
1261- let c : UInt32 = min ( left. _length, right. _length)
12621262
1263- while i < c {
1264- let li = UInt32 ( left [ i] )
1265- let ri = UInt32 ( right [ i] )
1266- let accumulator : UInt32 = ( 0x10000 + li) - UInt32( borrow) - ri
1267- result [ i] = UInt16 ( truncatingIfNeeded: accumulator)
1268- borrow = 1 - UInt16( truncatingIfNeeded: accumulator >> 16 )
1269- i += 1
1263+ while idx < maxIndex {
1264+ let li = UInt32 ( left [ idx] )
1265+ let ri = UInt32 ( right [ idx] )
1266+ // 0x10000 is to borrow in advance to avoid underflow.
1267+ let difference : UInt32 = ( 0x10000 + li) - UInt32( borrow) - ri
1268+ result [ idx] = UInt16 ( truncatingIfNeeded: difference)
1269+ // borrow = 1 if the borrow was used.
1270+ borrow = 1 - UInt16( truncatingIfNeeded: difference >> 16 )
1271+ idx += 1
12701272 }
12711273
1272- while i < left. _length {
1274+ while idx < left. _length {
12731275 if borrow != 0 {
1274- let li = UInt32 ( left [ i ] )
1275- let accumulator = 0xffff + li // + no carry
1276- borrow = 1 - UInt16( truncatingIfNeeded: accumulator >> 16 )
1277- result [ i ] = UInt16 ( truncatingIfNeeded: accumulator )
1278- i += 1
1276+ let li = UInt32 ( left [ idx ] )
1277+ let sum = 0xffff + li // + no carry
1278+ borrow = 1 - UInt16( truncatingIfNeeded: sum >> 16 )
1279+ result [ idx ] = UInt16 ( truncatingIfNeeded: sum )
1280+ idx += 1
12791281 } else {
1280- while i < left. _length {
1281- result [ i ] = left [ i ]
1282- i += 1
1282+ while idx < left. _length {
1283+ result [ idx ] = left [ idx ]
1284+ idx += 1
12831285 }
12841286 break
12851287 }
12861288 }
1287- while i < right. _length {
1288- let ri = UInt32 ( right [ i ] )
1289- let accumulator = 0xffff - ri + UInt32( borrow)
1290- borrow = 1 - UInt16( truncatingIfNeeded: accumulator >> 16 )
1291- result [ i ] = UInt16 ( truncatingIfNeeded: accumulator )
1292- i += 1
1289+ while idx < right. _length {
1290+ let ri = UInt32 ( right [ idx ] )
1291+ let difference = 0xffff - ri + UInt32( borrow)
1292+ borrow = 1 - UInt16( truncatingIfNeeded: difference >> 16 )
1293+ result [ idx ] = UInt16 ( truncatingIfNeeded: difference )
1294+ idx += 1
12931295 }
12941296
12951297 if borrow != 0 {
12961298 return . overflow
12971299 }
1298- result. _length = i ;
1300+ result. _length = idx ;
12991301 result. trimTrailingZeros ( )
13001302
13011303 return . noError;
0 commit comments