Strange Swift Casting

I just noticed that Swift does some casting on Int and Double. When I try to evaluate

(10 / 3.0) - (10 / 3) 

0.333... but actually 0.0 . Can someone explain this please?

+10
casting type-inference swift
source share
1 answer

Yes, I also found this rather unexpected. Double matches both FloatLiteralConvertible and IntegerLiteralConvertible ( ExpressibleByFloatLiteral and ExpressibleByIntegerLiteral in Swift 3). Therefore, Double can be initialized with a floating point literal

 let a = 3.0 

or with the whole literal:

 let b : Double = 10 

(The same is true for other floating point types such as Float and CGFloat .)

Now it may be unexpected for all of us with (Objective-) C background that both statements

 let x : Double = 10/4 // x = 2.5 . Really? Yes! let y = 10/4 as Double // Same here ... 

assign 0.25 variable. Out of context, the result of the division should be Double , and Swift does not imply type conversion. Therefore / must be a floating point division operator

 func /(lhs: Double, rhs: Double) -> Double 

therefore, the compiler creates both arguments as Double from the literals "10" and "4". (If 10/4 considered as a division of two integers, then the result will also be an integer, and this cannot be assigned before Double .)

Please note that this is different from

 let z = Double(10/4) // z = 2.0 . (I just thought that I understood it &%$!?) 

which performs integer division and converts the result to Double . Double has an init(_ v: Int) constructor, so 10/4 can be thought of as dividing two integers.

This looks a little strange if we summarize these results:

 let x : Double = 10/4 // x = 2.5 let y = 10/4 as Double // y = 2.5 let z = Double(10/4) // z = 2.0 

Now we can apply these results to your expression.

 (10 / 3.0) - (10 / 3) 

The first part (10 / 3.0) can only be Double , therefore - must be a floating point subtraction operator

 func -(lhs: Double, rhs: Double) -> Double 

and therefore (10 / 3) must also be Double . Again, / should be a floating point division operator, so 10 and 3 treated as Double constants.

Therefore, the expression is equivalent

 (Double(10) / 3.0) - (Double(10) / Double(3)) 

and evaluates to 0.0 . If you change the expression to

 (10 / 3.0) - Double(10 / 3) 

then the result is 0.333... because in this context 0.333... is the separation of two integer constants, as explained above.

+14
source share

All Articles