添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
才高八斗的玉米  ·  帮助中心·  4 月前    · 
深沉的伏特加  ·  Download a blob with ...·  5 月前    · 
坚强的伤疤  ·  Linux ...·  1 年前    · 

Swift 保留小数 避免四舍五入进位

最简单的截取小数位的方法:

/// 保留_位小数
func afterDecimalNum(_ count: Int) -> String {
    guard count >= 0 else { return "" }
    let format = "%.\(count)f"
    return String(format: format, self)
}

这里的方法会出现的问题是,当浮点数的小数位在保留对应小数位的时候,会默认的四舍五入,eg

// 11.999003  -> 12.0
var pp = 11.999003
String(format: "%.1f", pp)

包括网上常见的方法

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
roundToPlaces(value: pp, places: 1) // 12 这里没有了小数位

使用 NumberFormatter 找到了一个的解决方案,实现的效果是:

1. 截取对应小数位,不会进位(可控)

2. 小数位为零时,不展示

NumberFormatter 详细属性这里不做解释

extension Float {
    func interceptionDecimal(_ base: Int) -> String {
        let format = NumberFormatter.init()
        format.numberStyle = .decimal
        format.minimumFractionDigits = 0 // 最少小数位
        format.maximumFractionDigits = base // 最多小数位
        format.formatterBehavior = .default
        format.roundingMode = .down // 小数位以截取方式。不同枚举的截取方式不同
        return format.string(from: NSNumber(value: self)) ?? ""
}

测试用例

let num: [Float] = [12.1, 12.00, 100.123, 123.0001, 123.999, 0.000001, 0.00]
let res = num.map({$0.tempIIIIIII()})
// res = ["12.1", "12", "100.123", "123", "123.999", "0", "0"]

2021.7.13 更:

上述的测试用例并不全面,当 `num = 12.9` 的时候输出的结果会变成 12.8,出现的失真的情况。

为了达成准确的截取小数点的效果,使用了如下方案:

extension Float {
    /// 准确的小数尾截取 - 没有进位
    func decimalString(_ base: Self = 1) -> String {
        let tempCount: Self = pow(10, base)
        let temp = self*tempCount
        let target = Self(Int(temp))
        let stepone = target/tempCount
        if stepone.truncatingRemainder(dividingBy: 1) == 0 {