Dưới đây là cách trước đây tôi đã cắt một số float đến hai chữ số thập phân
NSLog(@" %.02f %.02f %.02f", r, g, b);
Tôi đã kiểm tra các tài liệu và Sách điện tử nhưng không thể tìm ra. Cảm ơn!
Dưới đây là cách trước đây tôi đã cắt một số float đến hai chữ số thập phân
NSLog(@" %.02f %.02f %.02f", r, g, b);
Tôi đã kiểm tra các tài liệu và Sách điện tử nhưng không thể tìm ra. Cảm ơn!
Câu trả lời:
Giải pháp tốt nhất của tôi cho đến nay, theo phản hồi của David :
import Foundation
extension Int {
func format(f: String) -> String {
return String(format: "%\(f)d", self)
}
}
extension Double {
func format(f: String) -> String {
return String(format: "%\(f)f", self)
}
}
let someInt = 4, someIntFormat = "03"
println("The integer number \(someInt) formatted with \"\(someIntFormat)\" looks like \(someInt.format(someIntFormat))")
// The integer number 4 formatted with "03" looks like 004
let someDouble = 3.14159265359, someDoubleFormat = ".3"
println("The floating point number \(someDouble) formatted with \"\(someDoubleFormat)\" looks like \(someDouble.format(someDoubleFormat))")
// The floating point number 3.14159265359 formatted with ".3" looks like 3.142
Tôi nghĩ rằng đây là giải pháp giống Swift nhất, buộc các hoạt động định dạng trực tiếp vào kiểu dữ liệu. Cũng có thể có một thư viện tích hợp các hoạt động định dạng ở đâu đó, hoặc có thể nó sẽ được phát hành sớm. Hãy nhớ rằng ngôn ngữ vẫn đang trong giai đoạn thử nghiệm.
một cách đơn giản là:
import Foundation // required for String(format: _, _)
print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
println(String(format: "a float number: %.5f", 1.0321))
printf
mà không phải viết các phần mở rộng riêng biệt.
import Foundation
Tôi thấy String.localizedStringWithFormat
làm việc khá tốt:
Thí dụ:
let value: Float = 0.33333
let unit: String = "mph"
yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Đây là một cách rất nhanh và đơn giản , những người không cần giải pháp phức tạp.
let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
Col 16: 'init' has been renamed to 'init(describing:)'
Hầu hết các câu trả lời ở đây là hợp lệ. Tuy nhiên, trong trường hợp bạn sẽ định dạng số thường xuyên, hãy xem xét mở rộng lớp Float để thêm một phương thức trả về một chuỗi được định dạng. Xem mã ví dụ dưới đây. Điều này đạt được cùng một mục tiêu bằng cách sử dụng một định dạng số và phần mở rộng.
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NSNumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.stringFromNumber(self) ?? "\(self)"
}
}
let myVelocity:Float = 12.32982342034
println("The velocity is \(myVelocity.string(2))")
println("The velocity is \(myVelocity.string(1))")
Bảng điều khiển hiển thị:
The velocity is 12.33
The velocity is 12.3
extension Float {
func string(fractionDigits:Int) -> String {
let formatter = NumberFormatter()
formatter.minimumFractionDigits = fractionDigits
formatter.maximumFractionDigits = fractionDigits
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}
}
NSNumberFormatter
, như câu trả lời này. Các câu trả lời được bình chọn cao khác chỉ đơn giản là không phản ánh cài đặt ngôn ngữ thiết bị (ví dụ: ở một số địa phương, chúng sử dụng dấu phẩy cho vị trí thập phân; điều này phản ánh điều đó; các câu trả lời khác thì không).
NSNumberFormatter
khá chậm để khởi tạo. Nếu có thể, nó giúp xác định một và sử dụng lại nó. Điều đó nói rằng, tôi ở đây đọc câu hỏi này bởi vì điều đó là không thể trong trường hợp của tôi.
Bạn không thể làm điều đó (chưa) với phép nội suy chuỗi. Đặt cược tốt nhất của bạn vẫn sẽ là định dạng NSString:
println(NSString(format:"%.2f", sqrt(2.0)))
Ngoại suy từ python, có vẻ như một cú pháp hợp lý có thể là:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
Mà sau đó cho phép bạn sử dụng chúng như:
M_PI % "%5.3f" // "3.142"
Bạn có thể định nghĩa các toán tử tương tự cho tất cả các loại số, thật không may, tôi không tìm thấy cách nào để làm điều đó với tổng quát.
Cập nhật Swift 5
Ít nhất là Swift 5, String
hỗ trợ trực tiếp trình format:
khởi tạo, do đó không cần sử dụng NSString
và @infix
thuộc tính không còn cần thiết, điều đó có nghĩa là các mẫu ở trên phải được viết là:
println(String(format:"%.2f", sqrt(2.0)))
func %(value:Double, format:String) -> String {
return String(format:format, value)
}
Double.pi % "%5.3f" // "3.142"
[NSString stringWithFormat...
Tại sao làm cho nó phức tạp như vậy? Bạn có thể sử dụng điều này thay thế:
import UIKit
let PI = 3.14159265359
round( PI ) // 3.0 rounded to the nearest decimal
round( PI * 100 ) / 100 //3.14 rounded to the nearest hundredth
round( PI * 1000 ) / 1000 // 3.142 rounded to the nearest thousandth
Xem nó hoạt động trong Playground.
PS: Giải pháp từ: http://rrike.sh/xcode/rounding-various-decimal-places-swift/
Một giải pháp thanh lịch và chung chung hơn là viết lại %
toán tử ruby / python :
// Updated for beta 5
func %(format:String, args:[CVarArgType]) -> String {
return NSString(format:format, arguments:getVaList(args))
}
"Hello %@, This is pi : %.2f" % ["World", M_PI]
"Hello %@, This is pi : %.2f" % ["World", M_PI]
không hoạt động, nhưng "%@ %@" % ["Hello", "World"]
tăng một cách kỳ lạ can't unsafeBitCast
... Đoán sẽ được sửa trong phiên bản tiếp theo.
,
không phải là toán tử ký tự hợp lệ, trong Swift và hầu hết các ngôn ngữ. Và imo, tốt hơn là sử dụng %
toán tử đã tồn tại trong các ngôn ngữ khác. Xem developer.apple.com/l
Swift 4
let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
Bạn vẫn có thể sử dụng NSLog trong Swift như trong Objective-C mà không cần ký hiệu @.
NSLog("%.02f %.02f %.02f", r, g, b)
Chỉnh sửa: Sau một thời gian làm việc với Swift, tôi cũng muốn thêm biến thể này
var r=1.2
var g=1.3
var b=1.4
NSLog("\(r) \(g) \(b)")
Đầu ra:
2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0
func làm tròn (quy tắc _: FloatingPointRoundingRule) -> Double
let x = 6.5
// Equivalent to the C 'round' function:
print(x.rounded(.toNearestOrAwayFromZero))
// Prints "7.0"
// Equivalent to the C 'trunc' function:
print(x.rounded(.towardZero))
// Prints "6.0"
// Equivalent to the C 'ceil' function:
print(x.rounded(.up))
// Prints "7.0"
// Equivalent to the C 'floor' function:
print(x.rounded(.down))
// Prints "6.0"
var x = 5.2
x.round()
// x == 5.0
var y = 5.5
y.round()
// y == 6.0
var z = -5.5
z.round()
// z == -6.0
làm thay đổi vòng func (quy tắc _: FloatingPointRoundingRule)
// Equivalent to the C 'round' function:
var w = 6.5
w.round(.toNearestOrAwayFromZero)
// w == 7.0
// Equivalent to the C 'trunc' function:
var x = 6.5
x.round(.towardZero)
// x == 6.0
// Equivalent to the C 'ceil' function:
var y = 6.5
y.round(.up)
// y == 7.0
// Equivalent to the C 'floor' function:
var z = 6.5
z.round(.down)
// z == 6.0
extension Numeric {
private func _precision(number: NSNumber, formatter: NumberFormatter) -> Self? {
if let formatedNumString = formatter.string(from: number),
let formatedNum = formatter.number(from: formatedNumString) {
return formatedNum as? Self
}
return nil
}
private func toNSNumber() -> NSNumber? {
if let num = self as? NSNumber { return num }
guard let string = self as? String, let double = Double(string) else { return nil }
return NSNumber(value: double)
}
func precision(_ minimumFractionDigits: Int,
roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> Self? {
guard let number = toNSNumber() else { return nil }
let formatter = NumberFormatter()
formatter.minimumFractionDigits = minimumFractionDigits
formatter.roundingMode = roundingMode
return _precision(number: number, formatter: formatter)
}
func precision(with numberFormatter: NumberFormatter) -> String? {
guard let number = toNSNumber() else { return nil }
return numberFormatter.string(from: number)
}
}
_ = 123.44.precision(2)
_ = 123.44.precision(3, roundingMode: .up)
let numberFormatter = NumberFormatter()
numberFormatter.minimumFractionDigits = 1
numberFormatter.groupingSeparator = " "
let num = 222.3333
_ = num.precision(2)
func option1<T: Numeric>(value: T, numerFormatter: NumberFormatter? = nil) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(2)
print("value1 = \(value1 != nil ? "\(value1!)" : "nil")")
let value2 = value.precision(5)
print("value2 = \(value2 != nil ? "\(value2!)" : "nil")")
if let value1 = value1, let value2 = value2 {
print("value1 + value2 = \(value1 + value2)")
}
print("")
}
func option2<T: Numeric>(value: T, numberFormatter: NumberFormatter) {
print("Type: \(type(of: value))")
print("Original Value: \(value)")
let value1 = value.precision(with: numberFormatter)
print("formated value = \(value1 != nil ? "\(value1!)" : "nil")\n")
}
func test(with double: Double) {
print("===========================\nTest with: \(double)\n")
let float = Float(double)
let float32 = Float32(double)
let float64 = Float64(double)
let float80 = Float80(double)
let cgfloat = CGFloat(double)
// Exapmle 1
print("-- Option1\n")
option1(value: double)
option1(value: float)
option1(value: float32)
option1(value: float64)
option1(value: float80)
option1(value: cgfloat)
// Exapmle 2
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.minimumIntegerDigits = 1
numberFormatter.minimumFractionDigits = 4
numberFormatter.maximumFractionDigits = 9
numberFormatter.usesGroupingSeparator = true
numberFormatter.groupingSeparator = " "
numberFormatter.groupingSize = 3
print("-- Option 2\n")
option2(value: double, numberFormatter: numberFormatter)
option2(value: float, numberFormatter: numberFormatter)
option2(value: float32, numberFormatter: numberFormatter)
option2(value: float64, numberFormatter: numberFormatter)
option2(value: float80, numberFormatter: numberFormatter)
option2(value: cgfloat, numberFormatter: numberFormatter)
}
test(with: 123.22)
test(with: 1234567890987654321.0987654321)
===========================
Test with: 123.22
-- Option1
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Float
Original Value: 123.22
value1 = nil
value2 = nil
Type: Double
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
Type: Float80
Original Value: 123.21999999999999886
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 123.22
value1 = 123.22
value2 = 123.22
value1 + value2 = 246.44
-- Option 2
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Float
Original Value: 123.22
formatted value = 123.220001221
Type: Double
Original Value: 123.22
formatted value = 123.2200
Type: Float80
Original Value: 123.21999999999999886
formatted value = nil
Type: CGFloat
Original Value: 123.22
formatted value = 123.2200
===========================
Test with: 1.2345678909876544e+18
-- Option1
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Float
Original Value: 1.234568e+18
value1 = nil
value2 = nil
Type: Double
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
Type: Float80
Original Value: 1234567890987654400.0
value1 = nil
value2 = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
value1 = 1.23456789098765e+18
value2 = 1.23456789098765e+18
value1 + value2 = 2.4691357819753e+18
-- Option 2
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Float
Original Value: 1.234568e+18
formatted value = 1 234 567 939 550 610 000.0000
Type: Double
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
Type: Float80
Original Value: 1234567890987654400.0
formatted value = nil
Type: CGFloat
Original Value: 1.2345678909876544e+18
formatted value = 1 234 567 890 987 650 000.0000
extension Double {
func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
return Double(formattedString)!
}
}
1.3333.formatWithDecimalPlaces(2)
Các câu trả lời được đưa ra cho đến nay đã nhận được nhiều phiếu bầu nhất là dựa trên các phương pháp NSString và sẽ yêu cầu bạn phải nhập Foundation.
Dù đã làm điều đó, bạn vẫn có quyền truy cập vào NSLog.
Vì vậy, tôi nghĩ rằng câu trả lời cho câu hỏi, nếu bạn đang hỏi cách tiếp tục sử dụng NSLog trong Swift, chỉ đơn giản là:
import Foundation
//It will more help, by specify how much decimal Point you want.
let decimalPoint = 2
let floatAmount = 1.10001
let amountValue = String(format: "%0.*f", decimalPoint, floatAmount)
đây là một giải pháp nhanh chóng "tinh khiết"
var d = 1.234567
operator infix ~> {}
@infix func ~> (left: Double, right: Int) -> String {
if right == 0 {
return "\(Int(left))"
}
var k = 1.0
for i in 1..right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
}
println("\(d~>2)")
println("\(d~>1)")
println("\(d~>0)")
Sức mạnh của sự mở rộng
extension Double {
var asNumber:String {
if self >= 0 {
var formatter = NSNumberFormatter()
formatter.numberStyle = .NoStyle
formatter.percentSymbol = ""
formatter.maximumFractionDigits = 1
return "\(formatter.stringFromNumber(self)!)"
}
return ""
}
}
let velocity:Float = 12.32982342034
println("The velocity is \(velocity.toNumber)")
Đầu ra: Vận tốc là 12,3
Ngoài ra với làm tròn:
extension Float
{
func format(f: String) -> String
{
return NSString(format: "%\(f)f", self)
}
mutating func roundTo(f: String)
{
self = NSString(format: "%\(f)f", self).floatValue
}
}
extension Double
{
func format(f: String) -> String
{
return NSString(format: "%\(f)f", self)
}
mutating func roundTo(f: String)
{
self = NSString(format: "%\(f)f", self).doubleValue
}
}
x = 0.90695652173913
x.roundTo(".2")
println(x) //0.91
sử dụng phương pháp dưới đây
let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)
println(output)
Rất nhiều câu trả lời hay ở trên, nhưng đôi khi một mẫu thích hợp hơn loại gobbledygook "% .3f". Đây là cách tôi sử dụng NumberFormatter trong Swift 3.
extension Double {
func format(_ pattern: String) -> String {
let formatter = NumberFormatter()
formatter.format = pattern
return formatter.string(from: NSNumber(value: self))!
}
}
let n1 = 0.350, n2 = 0.355
print(n1.format("0.00#")) // 0.35
print(n2.format("0.00#")) // 0.355
Ở đây tôi muốn 2 số thập phân luôn được hiển thị, nhưng số thứ ba chỉ khi nó bằng không.
Cập nhật Swift 4 Xcode 10
extension Double {
var asNumber:String {
if self >= 0 {
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.percentSymbol = ""
formatter.maximumFractionDigits = 2
return "\(formatter.string(from: NSNumber(value: self)) ?? "")"
}
return ""
}
}
Còn các tiện ích mở rộng trên các loại Double và CGFloat:
extension Double {
func formatted(_ decimalPlaces: Int?) -> String {
let theDecimalPlaces : Int
if decimalPlaces != nil {
theDecimalPlaces = decimalPlaces!
}
else {
theDecimalPlaces = 2
}
let theNumberFormatter = NumberFormatter()
theNumberFormatter.formatterBehavior = .behavior10_4
theNumberFormatter.minimumIntegerDigits = 1
theNumberFormatter.minimumFractionDigits = 1
theNumberFormatter.maximumFractionDigits = theDecimalPlaces
theNumberFormatter.usesGroupingSeparator = true
theNumberFormatter.groupingSeparator = " "
theNumberFormatter.groupingSize = 3
if let theResult = theNumberFormatter.string(from: NSNumber(value:self)) {
return theResult
}
else {
return "\(self)"
}
}
}
Sử dụng:
let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")
bản in: 112 465 848 348 508.46
@infix func ^(left:Double, right: Int) -> NSNumber {
let nf = NSNumberFormatter()
nf.maximumSignificantDigits = Int(right)
return nf.numberFromString(nf.stringFromNumber(left))
}
let r = 0.52264
let g = 0.22643
let b = 0.94837
println("this is a color: \(r^3) \(g^3) \(b^3)")
// this is a color: 0.523 0.226 0.948
Tôi không biết về hai vị trí thập phân, nhưng đây là cách bạn có thể in nổi với số thập phân bằng 0, vì vậy tôi tưởng tượng đó có thể là 2 vị trí, 3, vị trí ... (Lưu ý: bạn phải chuyển đổi CGFloat thành Double để vượt qua thành Chuỗi (định dạng :) hoặc nó sẽ thấy giá trị bằng 0)
func logRect(r: CGRect, _ title: String = "") {
println(String(format: "[ (%.0f, %.0f), (%.0f, %.0f) ] %@",
Double(r.origin.x), Double(r.origin.y), Double(r.size.width), Double(r.size.height), title))
}
Ví dụ Swift2: Độ rộng màn hình của thiết bị iOS định dạng Float loại bỏ số thập phân
print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
@Christian Dietrich:
thay vì:
var k = 1.0
for i in 1...right+1 {
k = 10.0 * k
}
let n = Double(Int(left*k)) / Double(k)
return "\(n)"
nó cũng có thể là:
let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"
[sửa:] Xin lỗi vì nhầm lẫn * - Tất nhiên điều này hoạt động với Nhân đôi. Tôi nghĩ, thực tế nhất (nếu bạn muốn các chữ số được làm tròn, không bị cắt) thì nó sẽ giống như thế:
infix operator ~> {}
func ~> (left: Double, right: Int) -> Double {
if right <= 0 {
return round(left)
}
let k = pow(10.0, Double(right))
return round(left*k) / k
}
Chỉ dành cho Float, chỉ cần thay Double bằng Float, pow bằng powf và round bằng roundf.
Cập nhật: Tôi thấy rằng thực tế nhất là sử dụng kiểu trả về Double thay vì String. Nó hoạt động tương tự cho đầu ra String, tức là:
println("Pi is roughly \(3.1415926 ~> 3)")
print: Pi là khoảng 3.142
Vì vậy, bạn có thể sử dụng nó theo cách tương tự cho String (thậm chí bạn vẫn có thể viết: println (d ~> 2)), nhưng ngoài ra, bạn cũng có thể sử dụng nó để làm tròn các giá trị trực tiếp, tức là:
d = Double(slider.value) ~> 2
hoặc bất cứ điều gì bạn cần