0

While I was playing and testing various things with SwiftUI. I found this bizarre situation. It is I guess related to the limit value that Double can handle, but anyway I thought it was weird enough to make a post. And hopefully someone can explain exactly what is happening or let me know where I made a mistake.

It seems like any odd value for t in the following code will cause the same kind of trouble.

let v:Double = 13082761331670030, t:Double = 1
var u:Double

u = v - t;
u += t;

if u == v {print("All is right.")}
else {
    print("This is weird. We now have:")
    print("v = \(String(format: "%.0f",v)) and u = \(String(format: "%.0f",u))")
}

Executing the code leads to:

u != v
Michel
  • 10,303
  • 17
  • 82
  • 179
  • 1
    Representable floating point numbers are not uniformly distributed. They become sparser and sparser as you increase in magnitude. There is simply no real number that rounds to 13082761331670029 that is also representable by `Double`, so u + 1 is still 13082761331670028. – Sweeper Jul 02 '20 at 03:38
  • 1
    try setting `let v: Double = 13082761331670031` (+1 over what you have) and you'll see a warning from XCode. `Double` lacks precision due to limited number of bits to represent the significant digits – New Dev Jul 02 '20 at 03:38
  • 1
    https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Martin R Jul 02 '20 at 03:38
  • 1
    Relevant: https://math.stackexchange.com/questions/2094022/why-does-floating-point-numbers-have-uneven-spacing-on-the-number-line – Sweeper Jul 02 '20 at 03:43
  • 1
    Here’s a simpler example: `let v: Double = 13082761331670031`. Now print `v`. You’re simply exceeding what can represented accurately in a 64 bit floating type. – Rob Jul 02 '20 at 16:13
  • Right! An even simpler case. The point is the same. – Michel Jul 03 '20 at 03:23

0 Answers0