I am working on a simple project where I try to compute sum using Gauss's technic for summing Arithmetic series with the following data sets.
first term (a1) = 1
nthTerm (n) = 5
commonDifference (d) = 2
/*
Gauss formula
Sn= n/2[2A1 + (n-1)d]
*/
let a1 = 1
let n = 5
let d = 2
let sum = n / 2 * (2 * a1 + (n - 1) * d)
print("sum = \(sum)")
// Expected -> sum = 25
// Swift answer -> sum = 20 ❓
I tested the same code in Python and Javascript both of them gives the correct answer (25) but swift gives the answer as 20.
Am I missing something or there is a bug in Swift?
You're using Swift's integer numeric types. For example, print(n / 2) will actually print 2, not 2.5.
You can use floating-point numbers instead, for example by adding ".0" to the ends of the literals:
let a1 = 1.0 // <- ".0" makes it a floating-point literal
let n = 5.0
let d = 2.0
let sum = n / 2 * ((2 * a1) + ((n - 1) * d))
print("sum = \(sum)") // "sum = 25.0"
Or by explicitly asking for a floating-point type:
let a1: Double = 1 // <- Same as above
let n: Double = 5
let d: Double = 2
Thanks for your suggestion @Nevin, I just tested it, interestingly it only works if multiplication happens first but if I change the sum declaration to: -
let sum = (2 * a1 + (n - 1) * d) * ( n / 2) // -> 20 🤔
// but as you suggested
let sum = (2 * a1 + (n - 1) * d) * n / 2 // -> 25
Changing operator precedence will cause the first issue of Swift's integer numeric type to occur as mentioned by Karl.
So I think it's safer to go with casting to double almost all the time to avoid un-expected precedence bugs.
Previously sent as a dm, reposted here now that the topic has come back from the spam filter:
Actually, what @Nevin suggested is "safer" than using Double or any other floating-point type.
So long as you put off the division until the last moment, the dividend (twice the sum) is always divisible by the divisor (2).
If you use a floating-point type, it's not guaranteed that you can get an accurate result. Because not all integer values can be represented precisely by Double, and those can not are rounded. For example:
let a₁: Double = 1
let n: Double = 4611686018427387902
let d: Double = 0
let sum = n / 2 * ((2 * a₁) + ((n - 1) * d))
print(sum) // prints "4.611686018427388e+18"