【问题标题】:Format decimals to have four non-zero digits after final zero将小数格式化为在最后一个零之后有四个非零数字
【发布时间】:2018-07-01 17:05:45
【问题描述】:

我想将小数格式化为在最后一个 0 之后有四个非零数字。例如,0.001765 或 0.00004839。

任何大于 1 的数字都只有两位小数。例如 2.23 。

我想知道是否可以使用 NumberFormatter 完成此操作?

【问题讨论】:

  • 假设您需要两个小数位来表示大于或等于 1 的值,而不是 0。
  • @rmaddy 我已经编辑了我的问题以反映您指出的更正

标签: ios swift number-formatting


【解决方案1】:

使用maximumSignificantDigits 属性。

let nf = NumberFormatter()
nf.maximumSignificantDigits = 4
print(nf.string(for: 0.00000232323)!)
// prints 0.000002323
print(nf.string(for: 2.3)!)
// prints 2.3

【讨论】:

  • 不需要初始化一个新的NSNumber对象。您可以使用Formatter 方法string(for: Any) 而不是from
  • 这只是maximumSignificantDigits 所做的一个例子。我已经更新了。
  • @LeoDabus 公平点,虽然我会质疑实际用例是什么。
  • 感谢您为我所面临的部分问题提供解决方案。这绝对解决了我描述的第一个案例 :) 我将提供我如何解决整个案例的答案
【解决方案2】:

你有两个条件。使用 minimumSignificantDigitsmaximumSignificantDigits 表示 4 位数字,使用 maximumFractionDigits 表示超过 1 的值的 2 位。

extension FloatingPoint {
    func specialFormat() -> String {
        let fmt = NumberFormatter()
        fmt.numberStyle = .decimal
        if abs(self) >= 1 {
            // adjust as needed
            fmt.maximumFractionDigits = 2
        } else {
            fmt.minimumSignificantDigits = 4
            fmt.maximumSignificantDigits = 4
        }

        return fmt.string(for: self)!
    }
}

print(0.001765345.specialFormat())
print(0.00004839643.specialFormat())
print(1.2345.specialFormat())

输出:

0.001765
0.00004840
1.23

【讨论】:

  • 对于一个简单的用例来说,这似乎过于复杂。
  • @Samah 怎么样? 1. 不简单。 OP 明确表示他们想处理两种不同的情况。 2. 使其成为扩展使其可重用。
  • 我错过了问题的那一部分。
  • 我只会让格式化程序成为扩展Formatter 的静态属性,这样您就不会在每次调用此方法时都创建新的NumberFormatter。类似于stackoverflow.com/a/48334604/2303865
  • @LeoDabus 好主意,不过如果将其添加到扩展程序中,我可能也会将其设为 private
【解决方案3】:

我结合使用收到的答案/cmets 来优化解决这个问题。

首先,两个必要的格式化程序通过扩展作为静态属性(如 Leo 所建议的那样)。

extension Formatter {
    static let twoDecimals: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        return formatter
    }()

    static let fourSigDigits: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.minimumSignificantDigits = 4
        formatter.maximumSignificantDigits = 4
        return formatter
    }()
}

然后,有条件地应用适当的格式化程序的扩展(如 rmaddy 所建议的):

extension FloatingPoint {
    var currencyFormat: String {
        return abs(self) >= 1 ? 
            Formatter.twoDecimals.string(for: self) ?? "" :
            Formatter.fourSigDigits.string(for: self) ?? ""
    }
}

最后,你可以这样使用它:

let eth = 1200.123456
let xrp = 1.23456789
let trx = 0.07891234

eth.currencyFormat //"1200.12"
xrp.currencyFormat //"1.23"
trx.currencyFormat //"0.07891"

【讨论】:

  • 您可以简单地扩展 FloatingPoint 协议来扩展所有浮点类型并使用string(for:) 方法。顺便说一句,考虑到不需要参数,您可以将其设为只读计算属性而不是方法
  • extension FloatingPoint { var currencyFormat: String { return abs(self) >= 1 ? Formatter.twoDecimals.string(for: self) ?? "" : Formatter.fourSigDigits.string(for: self) ?? "" } }
  • @LeoDabus 已编辑以反映您的改进 - 太棒了!
  • @LeoDabus 实际上我注意到了一个缺陷。如果数字大于 1,并且小数点后位为 0。例如,12.30。我将显示为 12.3。知道如何解释吗?否则,感谢您的所有意见
  • @LeoDabus 完美。再次感谢您的所有帮助 - 最终得到了一个很好的解决方案
猜你喜欢
  • 2020-01-27
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多