Count number of decimal places in a Float (or Decimal) in Swift

后端 未结 5 1526
长情又很酷
长情又很酷 2021-02-06 05:43

I want to count the number of decimal places (ignoring trailing zeros) in a Float (or NSDecimalNumber) for example:

1.45000 => 2
5.98 => 2
1.00 => 0
0.8         


        
5条回答
  •  名媛妹妹
    2021-02-06 06:29

    Doing this with Decimal is fairly straightforward, provided you correctly create your Decimal. Decimals are stored as significand * 10^exponent. significand is normalized to the smallest integer possible. So for 1230, the significand is 123 and the exponent is 1. For 1.23 the significand is also 123 and the exponent is -2. That leads us to:

    extension Decimal {
        var significantFractionalDecimalDigits: Int {
            return max(-exponent, 0)
        }
    }
    

    However, you must be very careful constructing your Decimal. If you construct it from a Double, you will already have applied binary rounding errors. So for example:

    let n = Decimal(0.111) // 0.11100000000000002048 because you passed a Double
    significantFractionalDecimalDigits // 20
    

    vs.

    let n = Decimal(string: "0.111")!
    n.significantFractionalDecimalDigits // 3 what you meant
    

    Keep in mind of course that Decimal has a maximum number of significant digits, so it may still apply rounding.

    let n = Decimal(string: "12345678901235678901234567890.1234567890123456789")!
    n.significantFractionalDecimalDigits // 9 ("should" be 19)
    

    And if you're walking down this road at all, you really must read the Floating Point Guide and the canonical StackOverflow question: Is floating point math broken?

提交回复
热议问题