You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 minimumFractionDigits to 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:46:38