2017-04-08 25 views
2
分隔千

我有以下浮動:1123455432.67899如何從一個浮動值與小數斯威夫特

我期望的結果是一個字符串:1,123,455,432.67899

最好的情況正確,和基於位置.(US /歐洲)

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) 
} 

此格式的偉大工程,只要我的持股量沒有小數,ALS只要我有小數,它開始「計算」。它基於第三個十進制數字計算向上/向下。

我錯過了什麼?什麼是獲得從不管有多少十進制數一Float一個String: 1,123,455,432.67899的最佳方式?非常感謝幫助。

編輯:

我的確切功能:

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。的Float

+0

您確定要指定'grouping'分離器','?並非所有地方都使用它。 – Alexander

+0

不,我不需要有分離由'被迫,',這只是示例代碼 –

+2

甲'Float'是一個32位的二進制浮點數。它可以表示約7位十進制數字,比較https://en.wikipedia.org/wiki/IEEE_floating_point。對於精確*十進制*算術,使用'(NS)DecimalNumber' –

回答

4

使用Double相反,您指定的值不是很好的可表示在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 
+0

它並不能真正幫助我解決問題。如果我使用確切的代碼,但與雙重,我把十進制數字,它開始更改數字從第三小數在 –

+0

我在put = 5.5555555555,輸出= 5.556 –

+5

@DavidSeek你得到3位小數,因爲這是默認的數字格式化程序。使用'formatter.maximumFractionDigits = 9'。 – rmaddy

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) 
+3

不需要將格式化程序的語言環境設置爲當前語言環境 - 這是默認設置。 – rmaddy

+0

@rmaddy很酷,不知道這個。 – Alexander

+0

Btw不需要初始化一個新的NSNumber對象。只是用於:而不是: –

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提供有用的注意事項。

+0

'guard'聲明的要點是什麼?只需返回'numberFormatter.string'的結果即可。 – rmaddy

+0

不要設置groupingSeparator。根據用戶的區域設置讓它默認正確。 – rmaddy

+0

Btw不需要初始化一個新的NSNumber對象。只用於:而不是從: –