ตัวระบุรูปแบบสตริงแม่นยำใน Swift


395

ด้านล่างเป็นวิธีที่ฉันจะตัดทอนทศนิยมสองตำแหน่ง

NSLog(@" %.02f %.02f %.02f", r, g, b);

ฉันตรวจสอบเอกสารและ eBook แต่ไม่สามารถเข้าใจได้ ขอบคุณ!

คำตอบ:


277

ทางออกที่ดีที่สุดของฉันจนถึงตอนนี้จากคำตอบของเดวิด :

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

ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่รวดเร็วที่สุดโดยผูกการดำเนินการจัดรูปแบบกับประเภทข้อมูลโดยตรง อาจเป็นไปได้ว่ามีห้องสมุดในตัวของการจัดรูปแบบการดำเนินการที่ใดที่หนึ่งหรืออาจจะเปิดตัวในไม่ช้า โปรดทราบว่าภาษายังอยู่ในช่วงเบต้า


76
สิ่งนี้มีความซับซ้อนโดยไม่จำเป็น คำตอบของ factone ทำงานได้และมีความรัดกุมมากขึ้น
Steven Marlowe

9
แน่นอนว่าถ้าคุณใช้เพียงครั้งเดียว แต่ถ้าคุณต้องการมีตัวเลือกการจัดรูปแบบมากขึ้นโดยใช้การแก้ไขสตริง (ซึ่งสามารถอ่านได้มากขึ้น) จากนั้นคุณสามารถใส่ส่วนขยายการจัดรูปแบบทั้งหมดในไฟล์ที่อื่นและอ้างอิงมันตลอดโครงการของคุณ แน่นอน Apple ควรจัดรูปแบบไลบรารี
Anton Tcholakov

2
โซลูชันนี้จะไม่ทำงานใน Swift 1.2 โดยไม่ส่งผลลัพธ์ไปที่ String
ibesora

เป็นคนดี แต่ไม่ใช่ Swift 2 เพื่อน
LastMove

798

วิธีง่ายๆคือ:

import Foundation // required for String(format: _, _)

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))

9
println(String(format: "a float number: %.5f", 1.0321))
zaph

78
ฉันเชื่อว่านี่เป็นคำตอบที่ดีกว่าคำตอบที่ยอมรับ มันใกล้กับ c-style มาตรฐานมากprintfโดยไม่ต้องเขียนส่วนขยายแยกต่างหาก
Keith Morris

9
อย่าลืม "นำเข้ารากฐาน" ที่ด้านบนของไฟล์
Chris Gregg

3
นี่เป็นคำตอบที่ดีกว่าคำตอบที่ยอมรับ แต่ยังคงใช้วิธีการพื้นฐาน (bridged to Swift)

1
อย่าลืมimport Foundation
NaN

125

ฉันพบว่าString.localizedStringWithFormatทำงานได้ค่อนข้างดี:

ตัวอย่าง:

let value: Float = 0.33333
let unit: String = "mph"

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)

คำถามไม่เกี่ยวกับหน่วยจัดการ localizedStringWithFormat เป็นสิ่งที่ดี แต่ไม่เกี่ยวข้อง
AmitP

ฉันเห็นด้วย AmitP มันถูกถามก่อนที่จะ String (รูปแบบ: ... , ข้อโต้แย้ง: ... ) มีอยู่
Valentin

84

นี่เป็นวิธีที่รวดเร็วและง่ายมากที่ไม่ต้องการโซลูชันที่ซับซ้อน

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3

สิ่งนี้ไม่ได้รวบรวม (ใช้ 3.0.2 ในกล่องทราย Swift ของ IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger

@PeterDillinger คุณกำลังผ่านตัวเลือกแทนค่าที่ยังไม่ได้เปิด
Michael

63

คำตอบส่วนใหญ่ที่นี่ใช้ได้ อย่างไรก็ตามในกรณีที่คุณจะจัดรูปแบบตัวเลขบ่อยครั้งให้พิจารณาการขยายคลาส Float เพื่อเพิ่มเมธอดที่ส่งกลับสตริงที่จัดรูปแบบ ดูรหัสตัวอย่างด้านล่าง สิ่งนี้บรรลุเป้าหมายเดียวกันโดยใช้ตัวจัดรูปแบบตัวเลขและส่วนขยาย

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))")

คอนโซลแสดง:

The velocity is 12.33
The velocity is 12.3

อัพเดต SWIFT 3.1

extension Float {
    func string(fractionDigits:Int) -> String {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}

12
ฉันหวังว่าคนอื่นจะใช้NSNumberFormatterเช่นคำตอบนี้ คำตอบที่ได้รับการโหวตอย่างสูงอื่น ๆ นั้นล้มเหลวในการสะท้อนการตั้งค่าตำแหน่งที่ตั้งของอุปกรณ์ (เช่นในบางสถานที่พวกเขาใช้เครื่องหมายจุลภาคสำหรับตำแหน่งทศนิยมซึ่งสะท้อนให้เห็นว่า
Rob

3
การปรับปรุงเพียงอย่างเดียวที่ฉันต้องการเห็นคือการจัดเก็บฟอร์แมตเตอร์สำหรับจำนวนที่กำหนด - NSNumberFormatters มีราคาแพงในการสร้าง
Kendall Helmstetter Gelner

1
สิ่งที่ฉันกำลังมองหา! ขอบคุณ
gunjot singh

ฉันรู้ว่านี่เป็นคำถามที่ค่อนข้างเก่า แต่NSNumberFormatterค่อนข้างช้าในการเริ่มต้น ถ้าเป็นไปได้จะช่วยกำหนดหนึ่งและนำมาใช้ใหม่ ที่กล่าวว่าฉันอยู่ที่นี่อ่านคำถามนี้เพราะมันเป็นไปไม่ได้ในกรณีของฉัน
promacuser

44

คุณไม่สามารถทำได้ (ยัง) ด้วยการแก้ไขสตริง ทางออกที่ดีที่สุดของคุณยังคงเป็นรูปแบบ NSString:

println(NSString(format:"%.2f", sqrt(2.0)))

การคาดการณ์จาก python ดูเหมือนว่าไวยากรณ์ที่เหมาะสมอาจเป็น:

@infix func % (value:Double, format:String) -> String {
    return NSString(format:format, value)
}

ซึ่งทำให้คุณสามารถใช้พวกเขาเป็น:

M_PI % "%5.3f"                // "3.142"

คุณสามารถกำหนดโอเปอเรเตอร์ที่คล้ายกันสำหรับประเภทตัวเลขทั้งหมด แต่น่าเสียดายที่ฉันไม่พบวิธีที่จะใช้กับ Generics

อัพเดต Swift 5

อย่างน้อย Swift 5 Stringสนับสนุนการformat:เริ่มต้นโดยตรงดังนั้นไม่จำเป็นต้องใช้NSStringและไม่จำเป็นต้องใช้@infixคุณลักษณะอีกต่อไปซึ่งหมายความว่าตัวอย่างด้านบนควรเขียนเป็น:

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 (รูปแบบ:" formatString ", val) ' ฉันไม่เห็นในเอกสาร iBooks จาก Apple
Duncan C

1
มันเหมือนกับการสร้างวัตถุ -c ใด ๆ จากสวิฟท์ มันเป็นเวอร์ชั่นที่รวดเร็วของ[NSString stringWithFormat...
David Berry

Gotcha ฉันยังไม่ได้ไปไกลขนาดนั้นใน Swift iBook
Duncan C

IIRC ที่ไม่ได้อยู่ใน Swift iBook มันเป็นหนึ่งในช่วง WWDC การทำงานร่วมกันอย่างรวดเร็วของสวิฟท์ในความลึก
เมษายน

2
ถ้าคุณใช้% เช่นเดียวกับใน Python มันก็น่าจะเป็นวิธีอื่น "% 5.3f"% M_PI
Andy Dent

16

ทำไมมันซับซ้อน? คุณสามารถใช้สิ่งนี้แทน:

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

เห็นมันทำงานในสนามเด็กเล่น

PS:โซลูชันจาก: http://rrike.sh/xcode/rounding-various-decimal-places-swift/


นี่คือทางออกที่ดีที่สุดฉันไม่เข้าใจว่านี่ไม่ใช่สิ่งที่ดีที่สุด
pjtnt11

7
สิ่ง nitpicky .. 1.500000000 จะเป็นเพียง "1.5" และไม่ใช่ "1.50"
styler1972

13
import Foundation

extension CGFloat {
    var string1: String {
        return String(format: "%.1f", self)
    }
    var string2: String {
        return String(format: "%.2f", self)
    }
}

การใช้

let offset = CGPoint(1.23, 4.56)
print("offset: \(offset.x.string1) x \(offset.y.string1)")
// offset: 1.2 x 4.6

10

โซลูชันที่หรูหราและทั่วไปคือการเขียน%ตัวดำเนินการ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]

น่าเศร้าที่สิ่งนี้ตายในเบต้า 6: ข้อผิดพลาดร้ายแรง: ไม่ปลอดภัย unsafeBitCast ระหว่างขนาดที่แตกต่างกัน
binarymochi

@binarymochi ด้วย Beta 6: "Hello %@, This is pi : %.2f" % ["World", M_PI]ใช้งานได้ แต่"%@ %@" % ["Hello", "World"]เพิ่มแปลกcan't unsafeBitCast... เดาว่าจะได้รับการแก้ไขในรุ่นถัดไป
Vincent Guerci

คุณสามารถสร้าง ',' ลงในโอเปอร์เรเตอร์ที่ใช้งานได้หรือไม่? '@infix func, (…' จากนั้นเขียนสตริงของคุณเช่น "Hello% @ นี่คือ pi:% .2f", ["you", M_PI])?
Rick

@Rick no ที่คุณทำไม่ได้,ไม่ใช่โอเปอเรเตอร์อักขระที่ถูกต้องในภาษา Swift และภาษาส่วนใหญ่ และ imo จะดีกว่าถ้าใช้%โอเปอเรเตอร์ที่มีอยู่แล้วในภาษาอื่น ดูdeveloper.apple.com/library/ios/documentation/Swift/Conceptual/…
Vincent Guerci

8

สวิฟต์ 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)

ให้ temp: Float = div * 100 ให้ string = String (รูปแบบ: "% .2f", โลแคล: Locale.current, อาร์กิวเมนต์: temp) มันทำให้ฉันมีข้อผิดพลาด ไม่สามารถแปลงค่าของประเภท 'Float' เป็นประเภทอาร์กิวเมนต์ที่คาดหวัง '[CVarArg]
Chandni

คุณต้องใส่ 15.123 เข้าไปในอาเรย์เพื่อให้มันใช้งานได้
โดเรียนรอย

3
สำหรับฉันทำงาน: ให้สตริง = String (รูปแบบ: "% .2f", myString)
Grzegorz R. Kulesza

6

คุณยังสามารถใช้ NSLog ใน Swift ได้เช่นเดียวกับ Objective-C โดยไม่ต้องใช้เครื่องหมาย @

NSLog("%.02f %.02f %.02f", r, g, b)

แก้ไข:หลังจากทำงานกับ Swift มาระยะหนึ่งแล้วฉันต้องการเพิ่มรูปแบบนี้ด้วย

    var r=1.2
    var g=1.3
    var b=1.4
    NSLog("\(r) \(g) \(b)")

เอาท์พุท:

2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4

6

รายละเอียด

  • Xcode 9.3, Swift 4.1
  • Xcode 10.2.1 (10E1001), Swift 5

โซลูชันที่ 1

func round () -> Double

(5.2).rounded()
// 5.0
(5.5).rounded()
// 6.0
(-5.2).rounded()
// -5.0
(-5.5).rounded()
// -6.0

func round (_ กฎ: 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"

การกลายพันธุ์ func รอบ ()

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

การกลายพันธุ์ func round (_ กฎ: 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

โซลูชันที่ 2

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


3

คำตอบที่ได้รับจากการโหวตมากที่สุดนั้นขึ้นอยู่กับวิธีการของ NSString และคุณจะต้องนำเข้ามูลนิธิ

แม้ว่าจะทำเช่นนั้นแล้วคุณยังสามารถเข้าถึง NSLog ได้

ดังนั้นฉันคิดว่าคำตอบสำหรับคำถามหากคุณถามว่าจะใช้ NSLog ใน Swift ได้อย่างไรก็คือ:

import Foundation


3
//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)

2

นี่คือทางออกที่รวดเร็ว "บริสุทธิ์"

 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)")

2

พลังของการขยาย

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)")

ผลลัพธ์: ความเร็วคือ 12.3



1

คุณยังสามารถสร้างโอเปอเรเตอร์ได้ด้วยวิธีนี้

operator infix <- {}

func <- (format: String, args:[CVarArg]) -> String {
    return String(format: format, arguments: args)
}

let str = "%d %.1f" <- [1453, 1.123]

1

นอกจากนี้ยังมีการปัดเศษ:

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


1

เวอร์ชันของตัวดำเนินการ ruby ​​/ python% ของ Vincent Guerci อัปเดตสำหรับ Swift 2.1:

func %(format:String, args:[CVarArgType]) -> String {
  return String(format:format, arguments:args)
}

"Hello %@, This is pi : %.2f" % ["World", M_PI]

1

คำตอบที่ดีมากมายด้านบน แต่บางครั้งรูปแบบก็เหมาะสมกว่า "gobbledygook"% .3f " นี่คือสิ่งที่ฉันใช้ในการใช้ NumberFormatter ใน 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

ที่นี่ฉันต้องการให้แสดงทศนิยม 2 ครั้ง แต่อันดับที่สามก็ต่อเมื่อมันไม่เป็นศูนย์


1

อัพเดต 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 ""
    }
}

1

สิ่งที่เกี่ยวกับส่วนขยายในประเภท Double และ 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)"
      }
   }
}

การใช้งาน:

let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")

จำนวนพิมพ์: 112 465 848 348 508.46


0
@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

0

ฉันไม่รู้เกี่ยวกับทศนิยมสองตำแหน่ง แต่นี่คือวิธีที่คุณสามารถพิมพ์จำนวนทศนิยมด้วยทศนิยมศูนย์ดังนั้นฉันคิดว่าสามารถเป็น 2 ตำแหน่ง 3 ตำแหน่ง ... (หมายเหตุ: คุณต้องแปลง CGFloat เป็น Double to pass เป็น String (รูปแบบ :) หรือจะเห็นค่าเป็นศูนย์)

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))
}


-1

@Christian Dietrich:

แทน:

var k = 1.0
    for i in 1...right+1 {
        k = 10.0 * k
    }
let n = Double(Int(left*k)) / Double(k)
return "\(n)"

มันอาจจะเป็น:

let k = pow(10.0, Double(right))
let n = Double(Int(left*k)) / k
return "\(n)"

[การแก้ไข:] ขออภัยในความสับสน * - แน่นอนว่ามันใช้ได้กับคู่ผสม ฉันคิดว่าเป็นประโยชน์มากที่สุด (ถ้าคุณต้องการที่จะปัดเศษตัวเลขไม่ตัด) มันจะเป็นเช่นนั้น:

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
}

สำหรับ Float เท่านั้นเพียงแทนที่ Double ด้วย Float pow ด้วย powf และ round ด้วย roundf
อัปเดต:ฉันพบว่าเป็นประโยชน์มากที่สุดที่จะใช้ return type Double แทน String มันทำงานเหมือนกันสำหรับการส่งออก String คือ:

println("Pi is roughly \(3.1415926 ~> 3)")

ภาพพิมพ์: Pi มีค่าประมาณ 3.142
ดังนั้นคุณสามารถใช้วิธีเดียวกันกับ Strings (คุณยังสามารถเขียนได้: println (d ~> 2)) แต่คุณยังสามารถใช้เพื่อปัดเศษค่าโดยตรงเช่น:

d = Double(slider.value) ~> 2

หรืออะไรก็ได้ที่คุณต้องการ ...


เห็นได้ชัดว่ามีความตั้งใจที่จะแสดงความคิดเห็นฉันเข้าใจว่าคุณต้องการพื้นที่เพิ่มเติมเพื่อให้ได้จุดและมันมีค่า แต่ถ้าคุณจะเขียนมันเป็นคำตอบที่สมบูรณ์ทำให้มันมีประโยชน์โดยอิสระ คุณสามารถเพิ่มรหัสเต็มตัวอย่างเช่นจากนั้นคำพูดและรับทราบถึงคริสเตียน
Jaime Gómez

@ Jaime Gómez: ฉันไม่ได้รับอนุญาตให้แสดงความคิดเห็นคำตอบข้างต้น แต่อย่างไรก็ตามฉันมีการตีความผิด ๆ * ในนั้น ไม่ทราบว่าควรเก็บไว้หรือควรลบทิ้ง ของหลักสูตรนี้สามารถใช้ในลักษณะที่คล้ายกันเพียงแค่การปัดเศษ (โดยไม่มีการแปลงสตริง) และสามารถแปลเป็นภาษาโปรแกรมอื่น ๆ ได้อย่างง่ายดาย * ฉันสันนิษฐานว่าด้วย Double มันจะถูกปัดเศษเป็น 8 หลักซึ่งแน่นอนว่าเป็นข้อผิดพลาดเพราะฉันปัดเศษด้วย Float และแปลงเป็น Double โดยไม่ได้ตั้งใจ
Stuepfnick

PS: ฉันต้องการที่จะใช้วิธีการที่คล้ายกันมากขึ้นสำหรับการปัดเศษโดยทั่วไปไม่ใช่เอาท์พุทสตริงดังนั้นกลับมาพิมพ์ Double (& วิธีปกติ?) Sidenote : ถ้าคุณปัดลอยด้วยวิธีนั้น (เช่นจาก Slider) และผลลัพธ์เป็นสตริง จะไม่เป็นผลเช่น "0.1" แต่ถ้าคุณแปลง Float นั้นเป็น Double และจากนั้นเป็น String * จะเป็น: "0.100000001490116" เนื่องจาก Float ไม่สามารถเก็บ 0.1 ได้อย่างใกล้ชิดเท่านั้น ผมคิดว่ามันเหมือนกันกับคู่เพียงกับความแม่นยำสอง ;) ดังนั้นมักจะแปลงเป็นคู่ก่อนที่จะปัดเศษจึงจะเป็นที่แน่นอนเป็นไปได้และแปรรูป String ดีเกินไป
Stuepfnick

PPS: แน่นอนด้วย Return Type Double บางครั้งมันก็แตกต่างกันเล็กน้อยเช่นถ้าคุณต้องการตั้งค่าข้อความฉลากคุณต้องเขียน: myLabel.text = "\ (d ~> 2)"แทนที่จะเป็นเพียง: myLabel text = d ~> 2แต่ฉันก็ยังคิดว่าฟังก์ชั่นนั้นมีประโยชน์มากกว่า (แน่นอนทุกคนสามารถทำในสิ่งที่พวกเขาต้องการเพียงแค่ความคิดของฉัน ... )
Stuepfnick

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.