Eugene Auduchinok - 4 months ago 23

Swift Question

I've just noticed that Swift does some type casting over Int and Double.

When I try to evaluate

`(10 / 3.0) - (10 / 3)`

`0.333...`

`0.0`

Could someone explain this please?

Answer

Yes, I also found this quite surprising. `Double`

conforms to both `FloatLiteralConvertible`

and `IntegerLiteralConvertible`

(`ExpressibleByFloatLiteral`

and `ExpressibleByIntegerLiteral`

in Swift 3). Therefore a
`Double`

can be initialized with *floating point literal*

```
let a = 3.0
```

or with an *integer literal*:

```
let b : Double = 10
```

(The same is true for other floating point types like `Float`

and
`CGFloat`

.)

Now it might be unexpected for all of us with an (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 the value `0.25`

to the variable. From the context, the result of the
division must be a `Double`

and Swift does not implicitly convert types.
Therefore `/`

*must* be the floating point division operator

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

so the compiler creates both arguments as `Double`

s from the literals
"10" and "4". (If `10/4`

were treated as the division of two integers
then the result would also be an integer, and that cannot be assigned
to a `Double`

.)

Note that this is different from

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

which does an integer division and converts the result to `Double`

.
`Double`

has an `init(_ v: Int)`

constructor, and therefore `10/4`

*can* be treated as the division of two integers here.

It really looks a bit 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 a `Double`

, therefore `-`

must be the floating point subtraction operator

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

and thus `(10 / 3)`

must also be a `Double`

. Again, `/`

must be the floating point division operator, so `10`

and `3`

are treated as `Double`

constants.

Therefore the expression is equivalent to

```
(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, `10 / 3`

is the division of two integer constants, as explained above.