【问题标题】:How to show result decimal style not exponential?如何显示结果小数样式不是指数?
【发布时间】:2018-06-17 08:07:24
【问题描述】:

我尝试将一个值转换为另一个值(从埃转换为 arshin,俄罗斯古代长度值),但我经常得到指数风格的结果 1.837684e-10。我需要以十进制格式显示它0.0000000001837

我使用的代码:

let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = NumberFormatter.Style.decimal

if let text = textField.text, let number = formatter.number(from: text) {

     angstrem = number.doubleValue

     arshin = Double(angstrem * 7112000000.0000)

     arshinLabel.text = "\(arshin)"
}

添加这一行没有任何意义:

formatter.numberStyle = NumberFormatter.Style.decimal

UPD 完整代码如下:

导入 UIKit

类 AngstremViewController: UIViewController {

var angstrem: Double = 0
var arshin: Double = 0
var versta: Double = 0
var vershok: Double = 0
var decimetr: Double = 0
var duim: Double = 0
var kilometr: Double = 0
var metr: Double = 0
var mili: Double = 0
var millimetr: Double = 0
var mormil: Double = 0
var sajen: Double = 0
var santimetr: Double = 0
var fut: Double = 0
var yard: Double = 0



@IBOutlet weak var textField: UITextField!




//Result labels
@IBOutlet weak var angstremLabel: UILabel!
@IBOutlet weak var arshinLabel: UILabel!
@IBOutlet weak var verstaLabel: UILabel!
@IBOutlet weak var vershokLabel: UILabel!
@IBOutlet weak var decimetrLabel: UILabel!
@IBOutlet weak var duimLabel: UILabel!
@IBOutlet weak var kilometrLabel: UILabel!
@IBOutlet weak var metrLabel: UILabel!
@IBOutlet weak var miliLabel: UILabel!
@IBOutlet weak var millimetrLabel: UILabel!
@IBOutlet weak var mormiliLabel: UILabel!
@IBOutlet weak var sajenLabel: UILabel!
@IBOutlet weak var santimetrLabel: UILabel!
@IBOutlet weak var futLabel: UILabel!
@IBOutlet weak var yardLabel: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()


    let toolBar = UIToolbar()
    toolBar.sizeToFit()
    toolBar.tintColor = UIColor.init(red:47/255.0, green:158/255.0, blue:249/255.0, alpha: 1.0)

    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)

    let doneButon = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneClicked))


    toolBar.setItems([flexibleSpace, doneButon], animated: true)

    textField.inputAccessoryView = toolBar

}



@objc func doneClicked() {
    view.endEditing(true)

    let formatter = NumberFormatter()
    formatter.locale = Locale.current
    formatter.numberStyle = NumberFormatter.Style.decimal

    if let text = textField.text, let number = formatter.number(from: text) {

        angstrem = number.doubleValue

        arshin = Double(angstrem * 0.00000000014060742)
        versta = Double(angstrem * 0.00000000000009373828270000001)
        vershok = Double(angstrem * 0.0000000022497188)
        decimetr = Double(angstrem * 0.000000001)
        duim = Double(angstrem * 0.0000000039370078700000005)
        kilometr = Double(angstrem * 0.0000000000001)
        metr = Double(angstrem * 0.0000000001)
        mili = Double(angstrem * 0.000000000000062137119)
        millimetr = Double(angstrem * 0.0000001)
        mormil = Double(angstrem * 0.00000000000005399568)
        sajen = Double(angstrem * 0.000000000046869141)
        santimetr = Double(angstrem * 0.00000001)
        fut = Double(angstrem * 0.00000000032808399)
        yard = Double(angstrem * 0.00000000010936132999999999)

        arshinLabel.text = "\(arshin)"
        verstaLabel.text = "\(versta)"
        vershokLabel.text = "\(vershok)"
        decimetrLabel.text = "\(decimetr)"
        duimLabel.text  = "\(duim)"
        kilometrLabel.text = "\(kilometr)"
        metrLabel.text = "\(metr)"
        miliLabel.text = "\(mili)"
        millimetrLabel.text = "\(millimetr)"
        mormiliLabel.text = "\(mormil)"
        sajenLabel.text = "\(sajen)"
        santimetrLabel.text = "\(santimetr)"
        futLabel.text = "\(fut)"
        yardLabel.text = "\(yard)"

    }
}

}

如果我转换这个

let number = formatter.number(from: text)

let number = formatter.String(from: number)

我有错误。 我理解方法,但在所有情况下它都不起作用。

有人可以帮忙吗?

【问题讨论】:

  • 您的“数字到文本”转换根本不使用 NumberFormatter ...
  • 我必须如何在没有“数字到文本”的标签中显示结果?这种方式我有很多错误
  • 你需要把arshinLabel.text = "\(arshin)"改成arshinLabel.text = formatter.string(from: number)
  • 请注意,Swift 允许在变量名中使用多个 unicode 字符:ångström
  • @DávidPásztor 但我还有很多其他值(如米、公里...)

标签: ios swift decimal number-formatting


【解决方案1】:

所以首先你所做的根本没有使用格式化程序(正如@Martin R 已经提到的那样)。您需要使用formatter.string(from: <#number#>)。但它也不会以这种方式工作,它很可能会显示“0”。要模拟您的结果,您需要使用 .scientific 样式。

所以您正在寻找的是.decimal 样式,其中包括minimumFractionDigits,它将强制显示您需要的多个数字。另一种可能更好的方法是使用minimumSignificantDigits。这将始终显示至少 N 个非零数字(类似 1001 仍算作 4 个非零数字)。

另一个问题是,在处理此类值时,您根本不应该使用double。您需要NSDecimalNumber,它专为精确和大值而设计。

查看以下结合了所有内容的示例:

let firstValue = NSDecimalNumber(string: "0.0000000001837")
let secondValue: NSDecimalNumber = 0.00001

let overallValue = firstValue.multiplying(by: secondValue)

let formatter = NumberFormatter()
formatter.locale = .current
formatter.numberStyle = .decimal
formatter.minimumSignificantDigits = 4

if let text = formatter.string(from: overallValue) {
    print(text)
}

这将打印0,000000000000001837 的结果。如果我将minimumSignificantDigits 增加到6,那么结果将是0,00000000000000183700

【讨论】:

  • 如果使用 formatter.string 我有错误:“无法将 'String' 类型的值转换为预期的参数类型 'NSNumber'”
  • @IvanKisin 您需要更具体一点,也许添加产生此错误的代码。无论如何,您似乎在某个地方期待一个NSNumber,但有一个像let myNumber: NSNumber = myString 这样的字符串。对此的修复可能再次是:let myNumber: NSNumber = NSDecimalNumber(string: myString)
  • 但是您的解决方案不起作用。我更新了主题中的代码。也许你会看到另一个错误,这会毁掉一切......
  • @IvanKisin 您完全误解了我们要告诉您的内容。问题不在于您从文本字段中获取值的位置,而是您将其转换回字符串的位置。关键是将arshinLabel.text = "\(arshin)" 转换为arshinLabel.text = formatter.string(from: number)。根本不需要您的第一个格式化程序,因为您可以简单地使用NSDecimalNumber(string: textField.text)。例如:arshinLabel.text = formatter.string(from: NSDecimalNumber(string: textField.text).multiplying(by: 0.00000000014060742))
  • 它正在工作,但现在格式化程序只从输入的数字中获取整数部分并将其乘以 0.00000000014060742
【解决方案2】:

我已经在 Playground 中转换了你会发现有用的代码:

let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = NumberFormatter.Style.decimal
let text = "0.0000000001837"
//! Convert string to number
let number = formatter.number(from: text)!
// 1.837e-10
let stringFromNumber = formatter.string(from: number)
//0
// Set up maximum number of fractional digits in formatter
formatter.maximumFractionDigits = 100
let fullStringFromNumber = formatter.string(from: number)
//"0.0000000001837"
let angstrem = number.doubleValue
let arshin = Double(angstrem * 7112000000.0000)
//1.3064744
let arshinNumber = NSNumber(value: arshin)
let arshinStr = formatter.string(from: arshinNumber)
//"1.3064744"

【讨论】:

    【解决方案3】:

    感谢@matic-oblak!

    解决办法是:

    let formatter = NumberFormatter()
            formatter.locale = Locale.current
            formatter.numberStyle = .decimal
            formatter.minimumSignificantDigits = 6
    
    
    
            if let text = textField.text, let number = formatter.number(from: text) {
    
    
                angstrem = number.doubleValue
    
    
                arshinLabel.text = formatter.string(from: NSDecimalNumber(value: angstrem).multiplying(by: 0.00000000014060742))
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多