1

I am trying to create a couple arrays of numbers from 1.0 to 1.25. I use the following code:

heightDisplayArray: [String] = []
heightArray: [Double] = []

for i in 1.stride(to: 1.25, by: 0.01){

   heightDisplayArray.append("\(i) meters")
   heightArray.append(i)

}

print (heightDisplayArray)
print (heightArray)

For some reason, results are appending as expected to heightDisplayArray, but is adding some unexpected numbers to heightArray. The console shows the following:

["1.0 meters", "1.01 meters", "1.02 meters", "1.03 meters", "1.04 meters", "1.05 meters", "1.06 meters", "1.07 meters", "1.08 meters", "1.09 meters", "1.1 meters", "1.11 meters", "1.12 meters", "1.13 meters", "1.14 meters", "1.15 meters", "1.16 meters", "1.17 meters", "1.18 meters", "1.19 meters", "1.2 meters", "1.21 meters", "1.22 meters", "1.23 meters", "1.24 meters"]

[1.0, 1.01, 1.02, 1.03, 1.04, 1.05, 1.0600000000000001, 1.0700000000000001, 1.0800000000000001, 1.0900000000000001, 1.1000000000000001, 1.1100000000000001, 1.1200000000000001, 1.1300000000000001, 1.1400000000000001, 1.1500000000000001, 1.1600000000000001, 1.1700000000000002, 1.1800000000000002, 1.1900000000000002, 1.2000000000000002, 1.2100000000000002, 1.2200000000000002, 1.2300000000000002, 1.2400000000000002]

How can I correct this behavior? I could change heightArray to be an Array of Strings instead of Doubles, but I'd prefer to find what is actually causing this to occur.

user1328035
  • 187
  • 1
  • 1
  • 12

1 Answers1

1

This error is because of precision of representation of Doubles. 0.01 cannot be represented precisely, so you get a small difference every now and then.

Cocoa offers a solution for situations like that: you can use NSDecimalNumber instead. This class represents decimal fractions precisely, so your code will produce no differences from expected numbers.

Another alternative is to change your representation to integers, but treat each number as the number of centimeters. In other words, instead of storing 1.34 m you store 134 cm. This would let you manipulate the values with the precision of centimeters, and change them to meters and centimeters on formatting.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523