Легко обрезая двойной - swift

Я хочу иметь возможность принять значение долготы / широты 19,3563443 и превратить его в 19,35634 (пять десятичных знаков). Есть ли простой способ сделать это?

6 ответов

Решение

Ты можешь использовать 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

Округлите, верните двойное значение.

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

Это не будет усекать, но может быть достаточно точным для длинных / лат до 5 десятичных знаков и быстро.

Я нашел другой ответ на другом сайте и хотел поделиться им:

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

y returns 129.888

благодаря "круглой" функции Swift.

Это математическая задача, а не проблема кодирования (то есть не переводите числа в строки обратно в числа). Если вы хотите урезать десятичную дробь, все, что вам нужно сделать, это переместить десятичную дробь вправо на любое количество мест, где вы хотите, чтобы она была усечена (x10, чтобы переместить ее вправо на одну цифру, x100, чтобы переместить ее на две цифры, x1000, чтобы переместить ее на три цифры, и т.д.), обрежьте все после нового десятичного числа, а затем разделите его на число, на которое вы первоначально умножили его, чтобы переместить десятичное число обратно в исходное положение.

Чтобы обрезать пи на 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))
    }

}

Пусть x = (long*100000).ground(.towardZero)/100000

Я предлагаю использовать 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)
Другие вопросы по тегам