Xcode 在Swift中显示小数位数可变的浮点
是否有一种简单的方法可以在Swift中显示相应小数位数的浮点或双精度 例如,使用SI单位的iOS应用程序,可以根据所需的属性进行更改,并根据所需的输入和输出转换多达6个数量级。因此,它不仅需要显示1mg到1000微克,还需要显示另一种方式,即1微克=0.001毫克 我可以很容易地将字符串格式化如下:Xcode 在Swift中显示小数位数可变的浮点,xcode,swift,Xcode,Swift,是否有一种简单的方法可以在Swift中显示相应小数位数的浮点或双精度 例如,使用SI单位的iOS应用程序,可以根据所需的属性进行更改,并根据所需的输入和输出转换多达6个数量级。因此,它不仅需要显示1mg到1000微克,还需要显示另一种方式,即1微克=0.001毫克 我可以很容易地将字符串格式化如下: textFieldFoo.text = NSString(format: "%.1f mg", bar) as String 但是,如果用户要从1mcg转换为0.001mg,则显示为 0.0毫克
textFieldFoo.text = NSString(format: "%.1f mg", bar) as String
但是,如果用户要从1mcg转换为0.001mg,则显示为
0.0毫克
然而,包含最多6位小数以包含所有常见的可能性将导致一个笨拙、难看的UI
是否有一种简单的方法来格式化字符串,以便在其中包含浮点数/双精度数,并将其显示为相关的小数位数/有效数字?我敢肯定,如果有足够的时间和样板代码,我可以将if/else进行金字塔化以获得结果,但坦率地说,这并不雅观。有
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
}
}
使用Swift格式化为有效数字
1234.57
1.2e+03
12.3457
12
0.001235
1.2e-03
1.23457e+06
1.2e+06
您需要的是能够格式化为固定数量的有效数字,而不是固定数量的小数位数。解决这个问题的一个很好的swift方法是使用类扩展,再加上一点数学知识,根据数字的大小来决定要显示多少个小数位
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)
}
}
}
}
下面的示例扩展了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)
}
}
}
}
输出
1234.57
1.2e+03
12.3457
12
0.001235
1.2e-03
1.23457e+06
1.2e+06
如果我理解正确,您是:
默认情况下,NumberFormatters设置为false,但: 将此属性设置为true,以根据minimumSignificantDigits和maximumSignificantDigits属性指定的有效数字配置格式化数字。默认情况下,最小有效位数为1,最大有效位数为6 下面是一个关于如何处理体量的示例
let micrograms = Measurement(value: 1, unit: UnitMass.micrograms) // 1.0 µg
let nanograms = micrograms.converted(to: .nanograms) // 1000.0000000000001 ng
let picograms = micrograms.converted(to: .picograms) // 1000000.0 pg
let milligrams = micrograms.converted(to: .milligrams) // 0.001 mg
let centigrams = micrograms.converted(to: .centigrams) // 0.0001 cg
let decigrams = micrograms.converted(to: .decigrams) // 1e-05 dg
let grams = micrograms.converted(to: .grams) // 1e-06 g
let kilograms = micrograms.converted(to: .kilograms) // 1e-09 kg
let ounces = micrograms.converted(to: .ounces) // 3.527399072294044e-08 oz
let pounds = micrograms.converted(to: .pounds) // 2.2046244201837776e-09 lb
let stones = micrograms.converted(to: .stones) // 1.574731232746851e-10 st
let formatter = MeasurementFormatter()
formatter.numberFormatter.usesSignificantDigits = true
formatter.unitOptions = .providedUnit
formatter.string(from: nanograms) // "1 000 ng"
formatter.string(from: picograms) // "1 000 000 pg"
formatter.string(from: micrograms) // "1 µg"
formatter.string(from: milligrams) // "0,001 mg"
formatter.string(from: centigrams) // "0,0001 cg"
formatter.string(from: decigrams) // "0,00001 dg"
formatter.string(from: grams) // "0,000001 g"
formatter.string(from: kilograms) // "0,000000001 kg"
formatter.string(from: ounces) // "0,000000035274 oz"
formatter.string(from: pounds) // "0,00000000220462 lb"
formatter.string(from: stones) // "0,000000000157473 st"
也许您可以为此使用
NSNumberFormatter
。但是如果你有nano,micro和其他前缀,我想你需要一个自定义的格式化实现。谢谢。在接下来的一两天里,我将尝试让它发挥作用,马克回答说,如果它起作用,我认为这不会回答问题,因为他们事先不知道有效数字的数量。用户输入float/double,他们希望在显示器上显示看起来不错的最大sig数字。不多也不少。