请参阅 this answer 以了解如何对 Double 值进行舍入并返回将保留舍入的 Decimal 值,而不会在尝试以二进制浮点表示形式表示十进制值时产生任何伪影。然后,您可以像这样得到四舍五入的Decimal 值:
let roomTotal = 427.3000000002
let value = roomTotal.roundedDecimal(to: 2)
如果你想用指定的小数位数显示它(以及本地化用户当前语言环境的字符串),你可以使用NumberFormatter:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
现在,如果您希望 JSONDecoder 为您进行此转换,您可以,但我可能倾向于让 struct 准确表示返回的内容,避免任何复杂的 init(from:) 实现,但可能包括一个计算属性,以您想要的格式返回值,例如:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Double
var roundedRoomTotal: Decimal {
return roomTotal.roundedDecimal(to: 2)
}
}
如果您在解码时需要对roomTotal 进行四舍五入,您可以编写init(from:) 来实现:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Decimal
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
currencyCode = try values.decode(String.self, forKey: .currencyCode)
total = try values.decode(Double.self, forKey: .total)
roomCurrencyCode = try values.decode(String.self, forKey: .roomCurrencyCode)
exchangeRate = try values.decode(Double.self, forKey: .exchangeRate)
roomTotal = try values.decode(Double.self, forKey: .roomTotal).roundedDecimal(to: 2)
}
}
或者,您可以省略init(from:),但在解析后手动舍入:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Decimal
}
还有:
var object = try! JSONDecoder().decode(TransactionInfoModel.self, from: data)
var rounded = Decimal()
NSDecimalRound(&rounded, &object.roomTotal, 2, .plain)
object.roomTotal = rounded