Import Foundation changes the behavior of arithmetic operators
Welcome to Swift! Type :help for assistance.
1> 1 / 3.0
$R0: Double = 0.33333333333333331
2> 1 % 3
$R1: Int = 1
3> 1 % 3 / 3.0
$R2: Double = 0.33333333333333331
4> import Foundation
5> 1 / 3.0
$R3: Double = 0.33333333333333331
6> 1 % 3
$R4: Int = 1
7> 1 % 3 / 3.0
$R5: Int = 0 // this result changes after importing Foundation
Is this a bug or some kind of implicit conversion magic in Swift?
Edit
Another (easier) way to reproduce this problem:
1> 1.0 / 3
$R0: Double = 0.33333333333333331
2> import Foundation
3> 1.0 / 3
$R1: Int = 0
4> Double(1.0) / 3 // this is a workaround
$R2: Double = 0.33333333333333331
I can reproduce this issue in an iOS app, not just from the REPL. I am using xcode6-beta5.
source to share
Without Foundation, these two expressions return different types:
1 % 3 / 3 // 0 : Int
1 % 3 / 3.0 // 0.33333333333 : Double
This is consistent with the behavior defined in the Swift book:
"If you combine integer and floating point literals in an expression, the Double will be inferred from context:"
With Foundation, expressions return an integer:
1 % 3 / 3 // 0 : Int
1 % 3 / 3.0 // 0 : Int
After researching, I don't see anything obvious in Foundation that could cause this: there are no strange operators defined for% or / that will do this, and the precedence will be the same. Not only that, but I am unable to reproduce the behavior outside the playground or REPL. If you do this in a simple console application, you will see the expected output (0.333333333333333: Double) even if you import Foundation.
As Zaf says, this is almost certainly a mistake. I would report this.
source to share
I played in the playground to try and reproduce your problem but was unable to. I tried this ...
let r7 = 1 % 3 / 3.0 //evaluates to 0.333333
import Foundation
let r8 = 1 % 3 / 3.0 //evaluates to 0.333333
I think perhaps what you see is the difference in RHS assignment for explicit Double vs type Int variable on LHS. So...
let r5:Double = 1 % 3 / 3.0 //evaluates to 0.33333
let r6:Int = 1 % 3 / 3.0 //evaluates to 0
I find this mathematical expression also slightly ambiguous for different readers. It might be wise to rewrite it as (1% 3) /3.0 (if that's what you mean, what the computer sees). Of course, the result of 1% 3 is an integer 1. Integer 1 divided by Double 3.0 equals 0.33333. So I feel like your problem can be reduced to ...
let r5:Double = 0.3333333 //evaluates to 0.33333
let r6:Int = 0.3333333 //evaluates to 0
Which doesn't have much to do with arithmetic, just the differences between the Int and Double types. Hope it helps.
source to share