轻松截断Double - swift

时间:2015-02-21 23:25:20

标签: swift truncate

我希望能够取经度/纬度值19.3563443并将其转换为19.35634(小数点后五位)。有没有简单的方法呢?

6 个答案:

答案 0 :(得分:1)

回合,获得双倍价值。

  NSString(format: "%.5f", myfloat).doubleValue

这不会截断,但对于长/纬到5位小数可能足够准确并且很快。

答案 1 :(得分:1)

您可以使用NumberFormatter

extension Formatter {
    static let number = NumberFormatter()
}
extension FloatingPoint {
    func fractionDigitsRounded(to digits: Int, roundingMode:  NumberFormatter.RoundingMode? = nil) -> Self {
        if let roundingMode = roundingMode {
            Formatter.number.roundingMode = roundingMode
        }
        Formatter.number.minimumFractionDigits = digits
        Formatter.number.maximumFractionDigits = digits
        if let string =  Formatter.number.string(for:  self) {
            if let floatingPoint = Formatter.number.number(from: string ) as? Self {
                return floatingPoint
            }
        }
        return 0
    }
}

let roundedToFive = 19.3563443.fractionDigitsRounded(to: 5)  //  19.35634

答案 2 :(得分:0)

我建议使用NSDecimalNumber。我不知道这是否比@ Leonardo的回答更好或更差。但是在处理数字时,我更喜欢坚持使用数字,而不是转换为字符串。下面的代码为请求的位数生成一个函数,可以根据需要重复使用。

这会通过四舍五入来截断。要获得正常的算术舍入,请将其更改为使用.RoundPlain而不是.RoundDown

func makeRounder(#digits: Int16) -> (Double) -> Double {
    class RoundHandler : NSObject, NSDecimalNumberBehaviors {
        var roundToDigits : Int16

        init(roundToDigits: Int16) {
            self.roundToDigits = roundToDigits
        }

        @objc func scale() -> Int16 {
            println("Digits: \(digits)")
            return roundToDigits
        }

        @objc func roundingMode() -> NSRoundingMode {
            return NSRoundingMode.RoundDown
        }

        @objc func exceptionDuringOperation(operation: Selector, error: NSCalculationError, leftOperand: NSDecimalNumber, rightOperand: NSDecimalNumber) -> NSDecimalNumber? {
            return nil
        }
    }

    let roundHandler = RoundHandler(roundToDigits:digits)

    func roundDigits(original:Double) -> Double {
        let decimal = NSDecimalNumber(double: original)
        let rounded = decimal.decimalNumberByRoundingAccordingToBehavior(roundHandler)
        return rounded.doubleValue
    }

    println("Digits: \(digits)")
    return roundDigits
}

let roundTo5 = makeRounder(digits:Int16(5))

roundTo5(19.3563443)
roundTo5(1.23456789)

答案 3 :(得分:0)

我在另一个网站上找到了不同的答案,并想分享它:

   let x = 129.88888888777
   let y =  Double(round(1000*x)/1000)

y returns 129.888

感谢swift" round"功能

答案 4 :(得分:0)

让x =(long * 100000).rounded(.towardZero)/ 100000

答案 5 :(得分:0)

这是一个数学问题,而不是编码问题(即,不要从数字转换为字符串再转换为数字)。如果您想截断小数,您需要做的就是将小数向右移动,但要截断许多地方(x10将其右移一位,x100将其移动两位,x1000将其移动三位,等等),截断新小数点后的所有内容,然后将其除以您最初乘以的数字,以将小数点移回其原始位置。

将pi截断3个地方:

  1. 移动小数点右边:3.1415927 * 10 ^ 3 = 3141.5927
  2. 将分数归零= 3141.0
  3. 将小数点后移:3141/10 ^ 3 = 3.141

为方便起见,将其添加为Double的扩展名:

extension Double {

    func truncate(to places: Int) -> Double {

        let newDecimal = pow(10, Double(places)) * self
        let truncated = Double(Int(newDecimal))
        let originalDecimal = truncated / pow(10, Double(places))
        return originalDecimal

    }

}

let dirty = 3.1415927
let clean = dirty.truncate(to: 2) // 3.14

更简洁的版本:

extension Double {

    func truncate(to places: Int) -> Double {
        return Double(Int(pow(10, Double(places)) * self)) / pow(10, Double(places))
    }

}