0

I'm running a for loop to get values returned from JSON. I'm getting the latitude values more specifically. I'm rounding the values using dblLat = (dblLat * 100).rounded() / 100

When appending the values to a new Array, only the first element is appended correctly as rounded, thereafter each new element is appended as a double with 15 decimal places:

do {
    let json = try JSONSerialization.jsonObject(with: data, options: [])
    //print(json)
    var latArray = [Double]()
    guard let array = json as? [Any] else { return }
    for user in array {
        guard let userDict = user as? [String: Any] else { return }
        guard let userID = userDict["id"] as? Int else { print("No Int Value Present"); return }
        guard let name = userDict["name"] as? String else { return }
        print(name)
        guard let company = userDict["company"] as? [String : String] else { return }
        print(company)
        guard let companyName = company["name"] as? String else { return }
        print(companyName)
        guard let address = userDict["address"] as? [String : Any] else { return }
        guard let geo = address["geo"] as? [String : String] else { return }
        print(geo)
        guard let lat = geo["lat"] as? String else { return }
        guard var dblLat = Double(lat) else { return }
        dblLat = (dblLat * 100).rounded() / 100
        print(dblLat)
        latArray.append(dblLat)
        print(latArray)
        //print(lat)
        print(userID)
    }

} catch {
    print(error)
}

Printing the array:

[-37.32, -43.950000000000003, -68.609999999999999, 29.460000000000001, -31.809999999999999, -71.420000000000002, 24.890000000000001, -14.4, 24.649999999999999, -38.240000000000002]

rmaddy
  • 314,917
  • 42
  • 532
  • 579
shawn.t
  • 105
  • 1
  • 9
  • I wouldn't do any rounding until you need to display the value to a user and then use a `NumberFormatter`. – rmaddy Aug 20 '18 at 16:21
  • Anything I'm missing in terms of coding? – shawn.t Aug 20 '18 at 16:21
  • 1
    You just need to understand how numbers working in programming. See [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – rmaddy Aug 20 '18 at 16:22
  • I must add: the array will be used later in code to display a graph, so rounding needs to take place before being appending to the array. – shawn.t Aug 20 '18 at 16:23
  • I don't think not rounding will affect your graph. Unless the graph is zoomable and the user zooms in really close. As a matter of fact, since you are showing it in a graph, you shouldn't be rounding it because a graph is capable of showing the exact coordinate. Rounding is usually done for convenience. Since graph is visual data and not numerical, that inconvenience is solved. – Rakesha Shastri Aug 20 '18 at 16:25
  • Regardless if it's going to be displayed on a graph, I would like to know the reason as to why the values are appended with 15 decimal places after being formatted. – shawn.t Aug 20 '18 at 16:33
  • Did you check the link @rmaddy shared? – Rakesha Shastri Aug 20 '18 at 16:34
  • Binary forms of some numbers are just infinite https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – ielyamani Aug 20 '18 at 16:53

1 Answers1

0

The Binary representation of some numbers is just infinite. Have a look here.

You could use a NumberFormatter to get strings with two decimal places

let array = [-37.32, -68.609999999999999, 29.460000000000001, -31.809999999999999, -71.420000000000002, 24.890000000000001, -14.4, 24.649999999999999, -38.240000000000002]

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2

let roundedStringsArray = array.map {formatter.string(from: NSNumber(floatLiteral: $0))!}

print(roundedStringsArray)
ielyamani
  • 17,807
  • 10
  • 55
  • 90
  • This is only relevant to display the numbers as strings to the user. This does not change the value and from the comments below the question, this won't help. – rmaddy Aug 20 '18 at 16:44