轻松截断 Double - swift

Easily truncating a Double - swift

我希望能够将 longitude/latitude 值 19.3563443 转换为 19.35634(小数点后五位)。有什么简单的方法可以做到这一点吗?

回合,双倍返还。

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

这不会截断,但可能足够精确 long/lat 到小数点后 5 位,而且速度很快。

您可以使用 NumberFormatter:

extension Formatter {
    static let number = NumberFormatter()
}

extension FloatingPoint {
    func fractionDigitsRounded(to digits: Int, roundingMode:  NumberFormatter.RoundingMode = .halfEven) -> String {
        Formatter.number.roundingMode = roundingMode
        Formatter.number.minimumFractionDigits = digits
        Formatter.number.maximumFractionDigits = digits
        return Formatter.number.string(for:  self) ?? ""
    }
}

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

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

这通过向下舍入来截断。要获得正常的算术舍入,请将其更改为使用 .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)

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

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

y returns 129.888

感谢 swift 的 "round" 功能。

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

这是一道数学题,不是编码题。 StringDouble 之间的转换不是很吸引人。在数学中,截去小数点右边的数字称为缩减比例。要截断一个非整数,您需要做的就是将小数点向右移动,无论您希望它截断多少地方(将其乘以 10 将其移动一位,将其乘以 100 将其移动它二,等等),将它转换成一个整数(它会丢弃新小数点后的所有东西),然后将它除以原来的乘数以 return 小数点到它原来的位置。

将 pi 的比例缩小到 3:

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

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

extension Double {
    func reduceScale(to places: Int) -> Double {
        let multiplier = pow(10, Double(places))
        let newDecimal = multiplier * self // move the decimal right
        let truncated = Double(Int(newDecimal)) // drop the fraction
        let originalDecimal = truncated / multiplier // move the decimal back
        return originalDecimal
    }
}

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