2

I want to do Double.pi - Float.pi, but I am getting an error:

Binary operator '-' cannot be applied to operands of type 'Double' and 'Float.

When I typecast Float to Double or Double to Float (for example: Double(Float.pi)), the result is wrong. How can I subtract them?

let floatPi = Float.pi
let Pi = Double.pi
print("float pi = \(floatPi)")
print("double pi = \(Pi)")
let substraction = Pi - floatPi
print(substraction)

Here is the result from the above:

float pi = 3.1415925

double pi = 3.141592653589793

error: MyPlayground.playground:20:23: error: binary operator '-' cannot be applied to operands of type 'Double' and 'Float' let substraction = Pi - floatPi

When I try this:

let floatPi = Double(Float.pi)

The result is:

float pi = 3.141592502593994

double pi = 3.141592653589793

1.5099579897537296e-07

Enchantres
  • 853
  • 2
  • 9
  • 22
  • 4
    How is the result wrong? What do you get? What do you expect? – Eric Postpischil Jan 26 '21 at 17:32
  • 1
    I expect the result of this phrase 3.141592653589793 - 3.1415925 – Enchantres Jan 26 '21 at 18:03
  • 2
    I voted to reopen. Per [this page](https://developer.apple.com/documentation/swift/float/1845969-pi), `Float.pi` and `Double.pi` are rounded toward zero. So `Float.pi` differs from `Double.pi` and also from `Float(Double.pi)`, which rounds to nearest in the conversion from `Double` to `Float`. – Eric Postpischil Jan 26 '21 at 18:42
  • possible duplicate of https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Leo Dabus Jan 26 '21 at 19:18
  • 1
    @LeoDabus: This should not be marked as a duplicate of that because this one involves an unusual rounding choice. Please do not promiscuously mark floating-point questions as duplicates of that one, because it prevents explaining specific issues in floating-point. – Eric Postpischil Jan 26 '21 at 19:19
  • @EricPostpischil the issue is that OP is using Float32 instead of Float64. – Leo Dabus Jan 26 '21 at 19:23
  • Thank you very much! It is more clear now. – Enchantres Jan 26 '21 at 19:52
  • 1
    @LeoDabus: **An** issue is that the OP is subtracting an IEEE-754 binary32 value from a binary64 value. **Another** issue is, as I wrote, that there is an unusual rounding method in use. Please do not promiscuously mark floating-point questions as duplicates of that one, because it prevents explaining specific issues in floating-point. – Eric Postpischil Jan 26 '21 at 19:53
  • I did not mark anything as duplicate I just commented that it was a possible duplicate of that question so that OP could read those answers as well – Leo Dabus Jan 26 '21 at 20:25
  • @EricPostpischil: That is interesting, I never noticed that before. The corresponding source code is here https://github.com/apple/swift/blob/main/stdlib/public/core/FloatingPointTypes.swift.gyb#L454 . – Martin R Feb 01 '21 at 12:39

1 Answers1

2

The reason you are seeing a difference is that Double can represent the value of π more accurately, because it uses more bits to get more precision. Both Float.pi and Double.pi are created by representing the mathematical value of π as accurately as possible in the Float or Double type without exceeding the mathematical value (the value of π is rounded to the nearest representable value in the direction of zero). So Float.pi and Double.pi have different values, and subtracting them produces about 1.5•10−7.

Further, the decimal numerals you see when you print Float.pi or Double.pi with default formatting are not the actual values inside the computer. Both Float and Double use a binary format in which each number is represented as a significand (in effect, some integer) multiplied by a negative power of two (including negative powers of 2, such as 2−34, for example). So the actual value of Float.pi is 3.141592502593994140625, and the actual value of Double.pi is 3.141592653589793115997963468544185161590576171875.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312