101 lines
2.8 KiB
Swift
101 lines
2.8 KiB
Swift
|
|
//
|
|||
|
|
// Coin.swift
|
|||
|
|
// Crush
|
|||
|
|
//
|
|||
|
|
// Created by Leon on 2025/8/31.
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
import Foundation
|
|||
|
|
|
|||
|
|
/// 专门用于金额管理的结构体(内部存储为美分)
|
|||
|
|
struct Coin {
|
|||
|
|
private(set) var cents: Int
|
|||
|
|
|
|||
|
|
init(cents: Int) {
|
|||
|
|
self.cents = max(0, cents)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
init(usd: CGFloat) {
|
|||
|
|
cents = max(0, Int(round(usd * 100.0)))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
init(input: String?) {
|
|||
|
|
cents = Coin.parseInput(input)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var dollars: Decimal {
|
|||
|
|
return Decimal(cents) / 100
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 格式化输出,不带货币符号(始终向下截断到 2 位小数)
|
|||
|
|
var formatted: String {
|
|||
|
|
let decimal = dollars as NSDecimalNumber
|
|||
|
|
let behavior = NSDecimalNumberHandler(
|
|||
|
|
roundingMode: .down, // 向下截断
|
|||
|
|
scale: 2, // 保留 2 位小数
|
|||
|
|
raiseOnExactness: false,
|
|||
|
|
raiseOnOverflow: false,
|
|||
|
|
raiseOnUnderflow: false,
|
|||
|
|
raiseOnDivideByZero: false
|
|||
|
|
)
|
|||
|
|
let truncated = decimal.rounding(accordingToBehavior: behavior)
|
|||
|
|
|
|||
|
|
let formatter = NumberFormatter()
|
|||
|
|
formatter.numberStyle = .decimal
|
|||
|
|
formatter.minimumFractionDigits = 0
|
|||
|
|
formatter.maximumFractionDigits = 2
|
|||
|
|
formatter.usesGroupingSeparator = false
|
|||
|
|
|
|||
|
|
return formatter.string(from: truncated) ?? "0"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var thousandthsFormatted: String {
|
|||
|
|
let decimal = dollars as NSDecimalNumber
|
|||
|
|
let behavior = NSDecimalNumberHandler(
|
|||
|
|
roundingMode: .down, // 向下截断
|
|||
|
|
scale: 2, // 保留 2 位小数
|
|||
|
|
raiseOnExactness: false,
|
|||
|
|
raiseOnOverflow: false,
|
|||
|
|
raiseOnUnderflow: false,
|
|||
|
|
raiseOnDivideByZero: false
|
|||
|
|
)
|
|||
|
|
let truncated = decimal.rounding(accordingToBehavior: behavior)
|
|||
|
|
|
|||
|
|
let formatter = NumberFormatter()
|
|||
|
|
formatter.numberStyle = .decimal
|
|||
|
|
formatter.minimumFractionDigits = 0
|
|||
|
|
formatter.maximumFractionDigits = 2
|
|||
|
|
formatter.usesGroupingSeparator = true // 启用千分位分隔符
|
|||
|
|
|
|||
|
|
return formatter.string(from: truncated) ?? "0"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static func parseInput(_ text: String?) -> Int {
|
|||
|
|
guard let text = text, !text.isEmpty else { return 0 }
|
|||
|
|
|
|||
|
|
let formatter = NumberFormatter()
|
|||
|
|
formatter.numberStyle = .decimal
|
|||
|
|
formatter.locale = Locale(identifier: "en_US")
|
|||
|
|
|
|||
|
|
if let number = formatter.number(from: text) {
|
|||
|
|
let decimal = Decimal(number.doubleValue)
|
|||
|
|
return (decimal * 100 as NSDecimalNumber).intValue
|
|||
|
|
}
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
let m1 = Money(cents: 1234)
|
|||
|
|
print(m1.formatted) // 12.34
|
|||
|
|
|
|||
|
|
let m2 = Money(cents: 1200)
|
|||
|
|
print(m2.formatted) // 12
|
|||
|
|
|
|||
|
|
let m3 = Money(cents: 1250)
|
|||
|
|
print(m3.formatted) // 12.5
|
|||
|
|
|
|||
|
|
let m4 = Money(cents: 10000)
|
|||
|
|
print(m4.formatted) // 100
|
|||
|
|
*/
|
|||
|
|
}
|