Вопрос:

Как отделить тысячи от значения Float с десятичными числами в Swift

swift

448 просмотра

3 ответа

10355 Репутация автора

У меня есть следующий Float: 1123455432.67899

Мой желаемый результат - строка: 1,123,455,432.67899

Наилучшее решение правильно ,и в .зависимости от местоположения (США / Европа)

struct Number {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.groupingSeparator = ","
        formatter.numberStyle = .decimal
        return formatter
    }()
}

let myFloat: Float = 1123455432.67899
let myNumber = NSNumber(value: myFloat)
let formatter = Number.withSeparator
if let result = formatter.string(from: myNumber) {
   print(result)
}

Этот форматтер прекрасно работает, пока у моего Float нет десятичных дробей, и, как только у меня есть десятичные дроби, он начинает "вычислять". Он рассчитывает вверх / вниз на основе третьего десятичного числа.

Что мне не хватает? Каков наилучший способ получить String: 1,123,455,432.67899число Floatнезависимо от количества десятичных чисел? Помощь очень ценится.

Редактировать:

Моя точная функция:

func formatValue(_ value: String ) -> String {

    if let double = Double(value) {

        let formatter = Number.withSeparator
        if let result = formatter.string(from: NSNumber(value: double)) {
            return result
        } else {
            return value
        }
    } else {
        return value
    }
}

valueэто всегда число, например 5.5555555555. Но в этом конкретном случае result = 5.556.

Автор: David Seek Источник Размещён: 08.04.2017 04:27

Ответы (3)


4 плюса

36237 Репутация автора

Решение

Используйте Doubleвместо Floatуказанного вами значения, которое не очень хорошо представлено в Float:

// [... your current code ...]
let myDouble: Double = 1123455432.67899
let myNumber = NSNumber(value: myDouble)
// [... your current code ...]

1,123,455,432.679

e+XXОбозначение Floatимеет по умолчанию не только для шоу, это там , потому что Floatне может хранить все цифры. Увидеть:

let myFloat2: Float = 1123455432.67899
print(myFloat2 == 1123455432) // true
let notRepresentable = Float(exactly:1123455432.67899) // nil
Автор: luk2302 Размещён: 08.04.2017 04:34

1 плюс

36805 Репутация автора

По сути, ваша проблема связана с неточностью с плавающей запятой Float. Использование типа данных с плавающей запятой двойной точности ( Double) в некоторой степени облегчит это.

Кроме того, вы не должны жестко кодировать groupingSeperator, а вместо этого позволять выводить его из текущей локали (это поведение по умолчанию).

import Foundation

let numberFormatter: NumberFormatter = {
    let nf = NumberFormatter()
    nf.numberStyle = .decimal
    return nf
}()   


let myDouble = 1123455432.67899
let myNumber = NSNumber(value: myDouble)

// It's also directly initializable from a literal
// let myNumber: NSNumber = 1123455432.67899 

guard let result = numberFormatter.string(from: myNumber) else { fatalError() }  

print(result)
Автор: Alexander Размещён: 08.04.2017 04:48

1 плюс

19481 Репутация автора

В дополнение к ответу luk2302 я бы предложил добавить его как метод к Double расширению следующим образом:

extension Double {
    func formattedString(_ maximumFractionDigits: Int = 5) -> String? {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.maximumFractionDigits = maximumFractionDigits

        return numberFormatter.string(for:self)
    }
}

if let formattedString = 1123455432.67899.formattedString() {
    print(formattedString) // 1,123,455,432.67899
}

Это может улучшить легкость получения желаемой строки.

Спасибо за @rmaddy и @LeoDabus за предоставление полезных заметок.

Автор: Ahmad F Размещён: 08.04.2017 05:06
Вопросы из категории :
32x32