How do I control the formatting of values when encoding data as JSON

I have a program that reads in CSV data from a text file on disk. It converts it to an array. It then encodes this array into a JSON string. It all works. The problem I have is the during the encoding process a double like 402.71 is converted to 402.70999999. How do I control the encoding process so that this number is 402.71 in the JSON string. Below is a line of CSV data, a line of the resulting array element and the resulting JSON object, the encoding function and the structures used for creating the array from the CSV data.

CSV data:
07/07/23, 403.03, 406.679, 402.71, 402.89, 3668080

Resulting array data:
TradingDays(tradingday: [DownloadHTML.Tradingday(timeStamp: 2023-07-07 00:00:00 +0000, open: 403.03, high: 406.679, low: 402.71, close: 402.89, volume: 3668080),

Resulting JSON object:
{
  "tradingday" : [
    {
      "timeStamp" : "2023-07-07T00:00:00Z",
      "low" : 402.70999999999998,   
      "high" : 406.67899999999997,  
      "volume" : 3668080,
      "open" : 403.02999999999997,  
      "close" : 402.88999999999999 
    },

Function:
func EncodeTradingDays (tradingDays: TradingDays) async -> String {
    
    var jsonData: Data?
    var jsonString: String
    let jsonEncoder = JSONEncoder()
    jsonEncoder.dateEncodingStrategy = .iso8601
    jsonEncoder.outputFormatting = [.prettyPrinted]
    
    do {
        jsonData = try jsonEncoder.encode(tradingDays)
        
    } catch {
        print("error encoding json data")
    }
    
    jsonString = String(data: jsonData!, encoding: .utf8)!
    return jsonString
}

Data structures:
struct TradingDays: Codable {
    var tradingday: [Tradingday]
}
struct Tradingday: Codable {

    var timeStamp: Date
    var open: Double
    var high: Double
    var low: Double
    var close: Double
    let volume: Int

    enum CodingKeys: String, CodingKey {
        case timeStamp
        case open, high, low, close, volume
    }
}
Accepted Answer

How do I control the encoding process so that this number is 402.71 in the JSON string.

Short answer: you can’t, for the Double type. There’s no equivalent of (for example) DateEncodingStrategy or DataEncodingStrategy for this type.

Longer answer: You’re seeing that a floating point type like Double isn’t a great choice for representing money, because of the representation issues inherent in floating point. (There are probably at least 999.0001 explanations of this topic that you can find online.)

Instead, consider using the Decimal type. This would be compatible with your existing JSON format that represents currency as numbers. Other solutions (but not compatible) could be to store them as strings ({"low": "402.71"}) or as integer cents with an implied decimal point ({"low": 40271}).

How do I control the formatting of values when encoding data as JSON
 
 
Q