@@ -1191,57 +1191,57 @@ public func NSDecimalAdd(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand:
1191
1191
}
1192
1192
1193
1193
fileprivate func integerAdd( _ result: inout WideDecimal , _ left: inout Decimal , _ right: inout Decimal ) -> NSDecimalNumber . CalculationError {
1194
- var i : UInt32 = 0
1194
+ var idx : UInt32 = 0
1195
1195
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
1197
1197
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
1205
1205
}
1206
1206
1207
- while i < left. _length {
1207
+ while idx < left. _length {
1208
1208
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
1214
1214
} 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
1218
1218
}
1219
1219
break
1220
1220
}
1221
1221
}
1222
- while i < right. _length {
1222
+ while idx < right. _length {
1223
1223
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
1229
1229
} 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
1233
1233
}
1234
1234
break
1235
1235
}
1236
1236
}
1237
- result. _length = i
1237
+ result. _length = idx
1238
1238
1239
1239
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
1243
1243
}
1244
- if i > Decimal . maxSize {
1244
+ if idx > Decimal . maxSize {
1245
1245
return . overflow
1246
1246
}
1247
1247
@@ -1256,46 +1256,48 @@ fileprivate func integerAdd(_ result: inout WideDecimal, _ left: inout Decimal,
1256
1256
// give b-a...
1257
1257
//
1258
1258
fileprivate 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
1260
1261
var borrow : UInt16 = 0
1261
- let c : UInt32 = min ( left. _length, right. _length)
1262
1262
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
1270
1272
}
1271
1273
1272
- while i < left. _length {
1274
+ while idx < left. _length {
1273
1275
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
1279
1281
} 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
1283
1285
}
1284
1286
break
1285
1287
}
1286
1288
}
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
1293
1295
}
1294
1296
1295
1297
if borrow != 0 {
1296
1298
return . overflow
1297
1299
}
1298
- result. _length = i ;
1300
+ result. _length = idx ;
1299
1301
result. trimTrailingZeros ( )
1300
1302
1301
1303
return . noError;
0 commit comments