-1

I have this function:

extension Float {
    func shortenDecimals() -> Float {
        println(self)

        let a = self * 10.0
        println(a)

        let b = round(a)
        println(b)

        println(b/10.0)
        return b / 10.0
    }
}

What this function should do is return a float with 1 decimal

This is what it prints out :

self        :   0.0833333358168602
self * 10   :   0.833333373069763
round(a)    :   1.0
b/10        :   0.100000001490116

I find this very frustrating, why does it not return 0.1?

Arbitur
  • 38,684
  • 22
  • 91
  • 128
  • Are you fixed on `Float`? `Double` will give better results. – zisoft Oct 01 '14 at 16:21
  • Wow, I didnt know this problem existed for Float only... and Ive been programming for 4 years... please dont laugh x) – Arbitur Oct 01 '14 at 16:24
  • 2
    Double has exactly the same problem, only some magnitudes smaller, so it might get unnoticed if println() limits the output precision. – Martin R Oct 01 '14 at 16:28
  • I tested and didnt get the problem with double, tried comparing it to 0.1 which float failed ;) – Arbitur Oct 01 '14 at 18:13

1 Answers1

3

0.5 is the only float “with 1 decimal”. All other fractional floats have more digits after the dot when expressed in decimal, because the representation of floating-point numbers is binary, not decimal.

The binary and decimal systems are equivalent when it comes to representing integers (they can both represent all the integers), but not when it comes to representing fractional values. The values that are simple to represent in decimal are overwhelmingly not representable in binary. Exceptions to this general rule are 0.25, 0.5, 0.75, 0.125, but not 0.1, which is not representable exactly in binary. 0.100000001490116 shows the first digits of the best approximation that Float has to offer.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281