最简单的截取小数位的方法:
1 2 3 4 5 6
| func afterDecimalNum(_ count: Int) -> String { guard count >= 0 else { return "" } let format = "%.\(count)f" return String(format: format, self) }
|
这里的方法会出现的问题是,当浮点数的小数位在保留对应小数位的时候,会默认的四舍五入,eg
1 2 3
| var pp = 11.999003 String(format: "%.1f", pp)
|
包括网上常见的方法
1 2 3 4 5 6
| func roundToPlaces(value:Double, places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor }
roundToPlaces(value: pp, places: 1)
|
使用 NumberFormatter 找到了一个的解决方案,实现的效果是:
- 截取对应小数位,不会进位(可控)
- 小数位为零时,不展示
NumberFormatter
详细属性这里不做解释
1 2 3 4 5 6 7 8 9 10 11
| 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)) ?? "" } }
|
测试用例
1 2 3
| let num: [Float] = [12.1, 12.00, 100.123, 123.0001, 123.999, 0.000001, 0.00] let res = num.map({$0.tempIIIIIII()})
|
2021.7.13 更:
上述的测试用例并不全面,当 num = 12.9
的时候输出的结果会变成 12.8,出现的失真的情况。
为了达成准确的截取小数点的效果,使用了如下方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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 { return String(format: "%.0f", stepone) }else{ return "\(stepone)" } } }
|
参考链接
iOS 保留两位小数,避免四舍五入