Swift-NSNumber中RoundingMode进位模式

2,441 阅读6分钟
原文链接: www.jianshu.com

项目开发中涉及保留两位小数,保留整数,都可以通过NumberFormatter来实现,通过minimumFractionDigits和maximumFractionDigits来设置,经常会遇到四舍五入的情况.有的时候是保留到固定位数,之后的数字全部舍弃,如12.257希望保留两位的结果是12.25,可以通过RoundingMode的枚举设置来实现.

public enum RoundingMode : UInt {

        
        case ceiling

        case floor

        case down

        case up

        case halfEven

        case halfDown

        case halfUp
    }

ceiling

向正无限大方向舍入的舍入模式.

数字 保留整数位
8.5 9
7.5 8
2.7 3
2.3 3
2.0 2
-2.0 -2
-2.3 -2
-2.7 -2
-7.5 -7
-8.5 -8

测试代码:

print("FlyElephant RoundMode ceiling测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化4:\(money)")
        }

        result = NSNumber(value: 2.0).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .ceiling)
        if let money = result {
            print("格式化10:\(money)")
        }
ceiling.png

floor

向负无限大方向舍入的舍入模式.

数字 保留整数位
8.5 8
7.5 7
2.7 2
2.3 2
2.0 2
-2.0 -2
-2.3 -3
-2.7 -3
-7.5 -8
-8.5 -9
print("FlyElephant RoundMode floor测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .floor)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .floor)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .floor)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .floor)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .floor)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .floor)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .floor)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .floor)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .floor)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .floor)
        if let money = result {
            print("格式化10:\(money)")
        }
floor.png

up

始终对非零舍弃部分前面的数字加 1.

数字 保留整数位
8.5 9
7.5 8
2.7 3
2.3 3
2.0 2
-2.0 -2
-2.3 -3
-2.7 -3
-7.5 -8
-8.5 -9
print("FlyElephant RoundMode up测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .up)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .up)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .up)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .up)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .up)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .up)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .up)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .up)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .up)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .up)
        if let money = result {
            print("格式化10:\(money)")
        }
up.png

down

从不对舍弃部分前面的数字加 1,相当于截取.

数字 保留整数位
8.5 8
7.5 7
2.7 2
2.3 2
2.0 2
-2.0 -2
-2.3 -2
-2.7 -2
-7.5 -7
-8.5 -8
print("FlyElephant RoundMode down测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .down)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .down)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .down)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .down)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .down)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .down)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .down)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .down)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .down)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .down)
        if let money = result {
            print("格式化10:\(money)")
        }
down.png

halfUp

向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入.如果被舍弃部分大于等于舍弃部分的一半及以上,相当于up,否则相当于down,经典的四舍五入模式.

数字 保留整数位
8.5 9
7.5 8
2.7 3
2.3 2
2.0 2
-2.0 -2
-2.3 -2
-2.7 -3
-7.5 -8
-8.5 -9
print("FlyElephant RoundMode halfup测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .halfUp)
        if let money = result {
            print("格式化10:\(money)")
        }
halfUp.png

halfDown

向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入.如果被舍弃部分大于等于舍弃部分的一半以上,相当于up,否则相当于down,经典的四舍五入模式.

数字 保留整数位
8.5 8
7.5 7
2.7 3
2.3 2
2.0 2
-2.0 -2
-2.3 -2
-2.7 -3
-7.5 -7
-8.5 -8
print("FlyElephant RoundMode halfDown测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .halfDown)
        if let money = result {
            print("格式化10:\(money)")
        }
halfDown.png

halfEven

向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入.如果舍弃部分左边的数字为奇数,则舍入行为同 halfUp,如果为偶数,则舍入行为同halfDown.在重复进行一系列计算时,此舍入模式可以在统计上将累加错误减到最小.此舍入模式也称为“银行家舍入法”,主要在美国使用. 称之为四舍六入,五分奇数和偶数的两种情况.

数字 保留整数位
8.5 8
7.5 8
2.7 3
2.3 2
2.0 2
-2.0 -2
-2.3 -2
-2.7 -3
-7.5 -8
-8.5 -8
print("FlyElephant RoundMode halfEven测试========")
        var result = NSNumber(value: 8.5).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化1:\(money)")
        }
        
        result = NSNumber(value: 7.5).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化2:\(money)")
        }
        
        result = NSNumber(value: 2.7).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化3:\(money)")
        }
        
        result = NSNumber(value: 2.3).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化4:\(money)")
        }
        
        result = NSNumber(value: 2.0).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化5:\(money)")
        }
        
        result = NSNumber(value: -2.0).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化6:\(money)")
        }
        
        result = NSNumber(value: -2.3).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化7:\(money)")
        }
        
        result = NSNumber(value: -2.7).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化8:\(money)")
        }
        
        result = NSNumber(value: -7.5).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化9:\(money)")
        }
        
        result = NSNumber(value: -8.5).numberFormate(mode: .halfEven)
        if let money = result {
            print("格式化10:\(money)")
        }
halfEven.png

辅助方法

extension NSNumber {
    
    func numberFormate(mode: NumberFormatter.RoundingMode, minDigits: Int = 0, maxDigits:Int = 0) -> String? {
        let formate = NumberFormatter()
        formate.numberStyle = NumberFormatter.Style.decimal
        formate.groupingSeparator = ","
        formate.minimumFractionDigits = minDigits
        formate.maximumFractionDigits = maxDigits
        formate.roundingMode = mode
        let result = formate.string(from: self)
        return result
    }
}