快速双串


108

在更新xCode 6之前,我没有问题将双精度型转换为字符串,但是现在它给了我一个错误

var a: Double = 1.5
var b: String = String(a)

它给我错误信息“双精度不能转换为字符串”。还有其他方法吗?


5
像这样定义它也可能很有用var b = "\(a)"
erdekhayser 2014年

Answers:


211

它不是强制转换,而是根据具有格式的值创建字符串。

let a: Double = 1.5
let b: String = String(format: "%f", a)

print("b: \(b)") // b: 1.500000

格式不同:

let c: String = String(format: "%.1f", a)

print("c: \(c)") // c: 1.5

format如果不需要格式化,也可以省略该属性。


1
分数位数更大的双精度数呢?像let a = 2.34934340320 let stringValue = String(format:“%f”,a)将给出2.349343
Nico

1
可以使用printf格式化选项控制显示,请参见:字符串格式说明符printf(3)
zaph 2015年

2
您只需要更改格式即可控制位数:format:"%.1f" = 1 digit // 1.5; format:"%.5f" = 5 digits // 1.50000
Megaetron

3
请更新您的答案,在Swift 2.1中,您只需要做String(yourDouble)
Alexandre G.

1
您可以使用let代替var。现在无需多次调用它。
Oleksandr

81
let double = 1.5 
let string = double.description

更新Xcode 7.1•Swift 2.1:

现在Double也可以转换为String,因此您可以根据需要简单地使用它:

let double = 1.5
let doubleString = String(double)   // "1.5"

Swift 3或更高版本,我们可以扩展LosslessStringConvertible并使其通用

Xcode 11.3•Swift 5.1或更高版本

extension LosslessStringConvertible { 
    var string: String { .init(self) } 
}

let double = 1.5 
let string = double.string  //  "1.5"

对于固定数目的小数位数,我们可以扩展FloatingPoint协议:

extension FloatingPoint {
    func fixedFraction(digits: Int) -> String {
        return String(format: "%.*f", digits, self as! CVarArg)
    }
}

如果您需要对数字格式(最小和最大小数位数和舍入模式)进行更多控制,则可以使用NumberFormatter:

extension Formatter {
    static let number = NumberFormatter()
}

extension FloatingPoint {
    func fractionDigits(min: Int = 2, max: Int = 2, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
        Formatter.number.minimumFractionDigits = min
        Formatter.number.maximumFractionDigits = max
        Formatter.number.roundingMode = roundingMode
        Formatter.number.numberStyle = .decimal
        return Formatter.number.string(for: self) ?? ""
    }
}

2.12345.fractionDigits()                                    // "2.12"
2.12345.fractionDigits(min: 3, max: 3, roundingMode: .up)   // "2.124"

1
这是黑客还是合法方法?不同的ios版本会导致任何问题吗?
Esqarrouth 2014年

2
不,使用不同的ios版本不会有任何问题。它也适用于OSX。顺便说一句,这是在使用Double或Int进行字符串插值时得到的结果。
Leo Dabus 2014年

很有用。您无法像%f一样格式化。而且它也适用于Int,因此您有两种方法可以做到这一点。
Patrik Vaberer 2015年

对于0.00001,它将不起作用,它将作为字符串变为“ 1e-05”。
亚历克斯

替换String(format: "%.\(digits)f", self as! CVarArg)String(format: "%.*f", digits, self as! CVarArg)
rmaddy19年

21

除了@Zaph答案,您还可以创建 extension:

extension Double {
    func toString() -> String {
        return String(format: "%.1f",self)
    }
}

用法:

var a:Double = 1.5
println("output: \(a.toString())")  // output: 1.5

1
@MaximShoustin OP没有足够的代表来投票和回答,所以必须15。我也不同意创建扩展,当声明:a.toString()被另一位开发人员看到时,肯定会有WTF时刻。
zaph

1
@Zaph为什么不呢?当然,您可以添加一些前缀并将其更改myToString()为确保其自定义定义。但是像其他语言一样,原型制作可以避免代码重复和良好的维护。
Maxim Shoustin 2014年

@MaximShoustin新手问题:println("output: \(a.toString())")和之间有什么区别println("output: \(a)")。第二个选项不会导致编译错误。这是一个不好的做法吗?
Alex Guerrero 2014年

有没有聪明的方法可以将这样的扩展名写到Double或FloatingPoint上,该扩展名可以在可选Double上工作以返回空的String?
Kinergy

@KinergyyourDouble?.toString() ?? ""
Leo Dabus


9

快速使任何东西变成字符串,除了枚举值可能只是在println()方法中做的事情

例如:

var stringOfDBL = "\(myDouble)"


3

此功能可让您指定要显示的小数位数:

func doubleToString(number:Double, numberOfDecimalPlaces:Int) -> String {
    return String(format:"%."+numberOfDecimalPlaces.description+"f", number)
}

用法:

let numberString = doubleToStringDecimalPlacesWithDouble(number: x, numberOfDecimalPlaces: 2)

替换String(format:"%."+numberOfDecimalPlaces.description+"f", number)String(format:"%.*f", numberOfDecimalPlaces, number)
rmaddy

3

这里有许多答案建议了多种技术。但是,在用户界面中显示数字时,您总是希望使用a,NumberFormatter以便对结果进行正确的格式化,四舍五入和本地化:

let value = 10000.5

let formatter = NumberFormatter()
formatter.numberStyle = .decimal

guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.5

如果您想要固定的小数位数,例如货币值

let value = 10000.5

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.50

但是这种方法的优点在于,它会被适当地本地化,从而在10,000.50美国但10.000,50在德国。不同的语言环境具有不同的数字首选格式,NumberFormatter在UI中显示数字值时,我们应该使用最终用户首选的格式。

不用说,虽然NumberFormatter在UI中准备字符串表示形式是必不可少的,但是如果将数字值作为字符串写入以进行持久存储,与Web服务接口等,则不应使用它。


2
这应该标记为正确的答案
Asad Khan



0
var b = String(stringInterpolationSegment: a)

这对我有用。你可以试试看


0

在Swift 4中,如果您想在UI中修改并使用Double作为textLabel“ String”,则可以在文件末尾添加:

    extension Double {
func roundToInt() -> Int{
    return Int(Darwin.round(self))
}

}

如果您希望将其包含在textlabel中,请像这样使用它:

currentTemp.text = "\(weatherData.tempCelsius.roundToInt())"

或将其打印为Int:

print(weatherData.tempCelsius.roundToInt())

0

我宁愿使用NSNumber和NumberFormatter方法(在需要时),也可以使用扩展名来避免膨胀代码

extension Double {

   var toString: String {
      return NSNumber(value: self).stringValue
   }

}

你也可能需要反向方法

extension String {

    var toDouble: Double {
        return Double(self) ?? .nan
    }

}

你为什么返回可选但分配.nan如果没有呢?您应该做一个或另一个。不是都。顺便说一句,使用String初始化器有什么问题?您也可以使其成为更通用的扩展LossLessStringConvertible协议,而不是扩展Double extension LosslessStringConvertible { var string: String { return .init(self) } }
Leo Dabus

你是双归吗?是垃圾,因为我已经检查它为零并返回NaN
Giuseppe Mazzilli

0

Swift 5:使用以下代码

extension Double {

    func getStringValue(withFloatingPoints points: Int = 0) -> String {
        let valDouble = modf(self)
        let fractionalVal = (valDouble.1)
        if fractionalVal > 0 {
            return String(format: "%.*f", points, self)
        }
        return String(format: "%.0f", self)
    }
}

替换String(format: "%.\(points)f", self)String(format: "%.*f", points, self)
rmaddy19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.