2016-03-11 62 views
1

是否有簡單的方法在Swift中顯示浮點數或雙精度到相關小數位數。在Swift中將浮點數顯示爲可變小數位數

例如,一個使用SI單位的iOS應用程序,可根據所需屬性進行更改,並根據所需的輸入和輸出轉換最多6個數量級。因此它不僅需要顯示1毫克到1000毫克,而且還需要顯示 - 即1微克= 0.001毫克。

如下我很容易格式的字符串:

textFieldFoo.text = NSString(format: "%.1f mg", bar) as String 

然而,如果用戶從1mcg轉換爲0.001mg,這將顯示爲 0.0毫克

然而,包括了到小數點後6位以包含所有常見的可能性會導致難看,醜陋的用戶界面。

有沒有簡單的方法來格式化一個字符串,以便包含一個浮點數/雙精度數據,並將其顯示爲相關的小數位數/有效數字?我敢肯定,在給定時間和足夠的樣板代碼的情況下,我可以通過金字塔來得到結果,但這是坦率的不雅。

+1

也許你可以使用'NSNumberFormatter'這一點​​。 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/但是,如果你有nano,micro和其他前綴以及我認爲你需要一個自定義的實現格式。 –

回答

1

NSMAssFormatter但它並沒有一直下降到微克。它的設計是爲了塑造人的體重。

您可以通過繼承NSNumberFormatter滾你自己:

enum MassUnit: Double { 
    case Microgram = 1e-6 
    case Milligram = 1e-3 
    case Gram = 1 
    case Kilogram = 1e3 

    static let allUnits: [MassUnit] = [.Microgram, .Milligram, .Gram, .Kilogram] 

    var unitAbbreviation: String { 
     get { 
      switch self { 
      case .Microgram: return "mcg" 
      case .Milligram: return "mg" 
      case .Gram: return "g" 
      case .Kilogram: return "kg" 
      } 

     } 
    } 
} 

class MyMassFormatter: NSNumberFormatter { 
    func bestFitStringForWeightInGrams(weight: Double) -> String { 
     var selectedString = self.stringFromNumber(weight)! 
     var selectedUnit = MassUnit.Gram 

     // Pick the unit that results in the shortest string 
     for unit in MassUnit.allUnits { 
      if let str = self.stringFromNumber(weight/unit.rawValue) 
       where str.characters.count < selectedString.characters.count { 
        selectedString = str 
        selectedUnit = unit 
      } 
     } 

     return selectedString + selectedUnit.unitAbbreviation 
    } 
} 

用法:

let formatter = MyMassFormatter() 
formatter.format = "0.######" 

print(formatter.bestFitStringForWeightInGrams(0.000001)) // 1mcg 
print(formatter.bestFitStringForWeightInGrams(0.005))  // 5mg 
print(formatter.bestFitStringForWeightInGrams(2500))  // 2.5kg 
print(formatter.bestFitStringForWeightInGrams(1234.5))  // 1234.5g 
+0

非常感謝。我會在第二天或第二天開始工作,如果有效,請給出答案 – docBen

0

使用雨燕

你想要的是格式化的能力格式化,以有效數字固定數量的有效數字,而不是固定的小數位數。解決這個問題的一個很好的選擇是使用類擴展,用一點數學來決定根據數量的大小來顯示多少個小數位數。

下面的示例擴展了Double類,以便將格式設置爲固定數量的有效數字,並根據數量的大小使用浮點數表示法或科學計數法。

import Foundation 

//extension to format a Double to a fixed number of significant figures 
extension Double { 
    func sigFigs(_ numberOfSignificantFigures: Int) -> String { 

     let mag = log10(abs(self)) 
     let intMag = Int(mag) 

     if mag >= 0 { 
      if intMag < numberOfSignificantFigures { 
       return String(format: "%.\(numberOfSignificantFigures - intMag - 1)f",self) 
      } 
      else { 
       return String(format: "%.\(numberOfSignificantFigures - 1)e",self) 
      } 
     } 
     else { 
      if -intMag < numberOfSignificantFigures { 
       return String(format: "%.\(numberOfSignificantFigures)f",self) 
      } 
      else { 
       return String(format: "%.\(numberOfSignificantFigures - 1)e",self) 
      } 
     } 
    } 
} 

使用

let num1 = 1234.5678 
let num2 = 12.345678 
let num3 = 0.0
let num4 = 1234567.8 

print(num1.sigFigs(6)) 
print(num1.sigFigs(2)) 
print(num2.sigFigs(6)) 
print(num2.sigFigs(2)) 
print(num3.sigFigs(6)) 
print(num3.sigFigs(2)) 
print(num4.sigFigs(6)) 
print(num4.sigFigs(2)) 

輸出

1234.57 
1.2e+03 
12.3457 
12 
0.0
1.2e-03 
1.23457e+06 
1.2e+06 
相關問題