如何在Swift中将数字与Float值中的小数分开

时间:2017-04-08 16:27:13

标签: swift

我有以下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没有小数,这个格式化程序就可以正常运行,因为我有小数,它开始计算"计算"。它根据第3个十进制数计算上/下。

我错过了什么?无论有多少十进制数,从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

3 个答案:

答案 0 :(得分:4)

使用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

答案 1 :(得分:1)

从根本上说,你的问题来自于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)

答案 2 :(得分:1)

除了luk2302's answer之外,我建议将其添加为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提供了有用的说明。