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.

+3


source to share


3 answers


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.

+1


source


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.

0


source


The answer is that Swift is broken, it's Beta after all. I've filed a bug with Apple Radar: 17962491.

0


source







All Articles