NSNumberFormatter小数位校验:仅显示非零小数的实现咨询
Solution for Dynamic Currency Decimal Display
Hey there! Let's fix up your NumberFormatter code so it only shows decimal digits when the fractional part isn't zero. Here are a couple of solid approaches tailored to your needs:
Approach 1: Dynamic Decimal Digits (Currency Standards Compliant)
This method respects the default decimal rules for each currency (e.g., USD uses 2 decimals, JPY uses 0) while hiding decimals entirely when the value is an integer. Perfect for proper currency formatting:
let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale(identifier: "\(SettingsViewController.currencyCode)") // Grab the default maximum decimal digits for the selected currency let defaultMaxFractionDigits = formatter.maximumFractionDigits // Check if the value has a non-zero fractional part let valueDouble = value // Assume `value` is your Double/Decimal input let isWholeNumber = valueDouble.truncatingRemainder(dividingBy: 1) == 0 // Adjust minimum decimal digits based on whether it's a whole number formatter.minimumFractionDigits = isWholeNumber ? 0 : defaultMaxFractionDigits formatter.maximumFractionDigits = defaultMaxFractionDigits // Apply the formatted string if let formattedPrice = formatter.string(from: NSNumber(value: valueDouble)) { value.text = formattedPrice }
How this works:
- We first get the currency's standard maximum decimal digits (handles edge cases like currencies without decimals automatically).
- Using
truncatingRemainder(dividingBy: 1), we check if the value is a whole number (no fractional part). - If it's a whole number, we set
minimumFractionDigitsto 0 to hide decimals. If not, we use the currency's standard decimal count to show the appropriate digits.
Approach 2: Flexible Truncation of Trailing Zeros
If you want to show up to 4 decimal digits (like your original code) but strip trailing zeros when they aren't needed, this string-processing approach gives you more control:
let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale(identifier: "\(SettingsViewController.currencyCode)") formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 4 formatter.roundingMode = .down // Adjust rounding as needed (e.g., .roundHalfUp) if var formattedPrice = formatter.string(from: NSNumber(value: value)) { // Strip trailing zeros and any leftover decimal/comma separator let decimalSeparator = formatter.decimalSeparator ?? "." let regexPattern = "\\\(decimalSeparator)0+$" formattedPrice = formattedPrice.replacingOccurrences(of: regexPattern, with: "", options: .regularExpression) value.text = formattedPrice }
How this works:
- We set the formatter to allow 0-4 decimal digits, then use a regex to remove any trailing zeros after the decimal separator (adapting to the selected locale's separator, whether it's
.or,). - This is great if you want to show as many decimal digits as needed (up to 4) without unnecessary trailing zeros.
Which to choose?
- Go with Approach 1 if you need strict compliance with currency formatting standards (most common for financial apps).
- Go with Approach 2 if you want more flexibility in displaying variable decimal lengths (e.g., showing 122.1 instead of 122.1000 for a value with one non-zero decimal digit).
内容的提问来源于stack exchange,提问作者Wizzardzz
相关产品推荐
相关产品推荐

