Precyzyjny specyfikator formatu ciągu w Swift

395

Poniżej znajduje się sposób, w jaki wcześniej obciąłem liczbę zmiennoprzecinkową do dwóch miejsc po przecinku

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

Sprawdziłem dokumenty i eBook, ale nie byłem w stanie tego rozgryźć. Dzięki!

użytkownik3524868
źródło

Odpowiedzi:

277

Moje najlepsze jak dotąd rozwiązanie, wynikające z odpowiedzi Davida :

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

Myślę, że jest to najbardziej szybkie rozwiązanie, wiążące operacje formatowania bezpośrednio z typem danych. Możliwe, że gdzieś jest wbudowana biblioteka operacji formatowania, a może wkrótce zostanie wydana. Pamiętaj, że język jest wciąż w fazie beta.

Anton Tcholakov
źródło
76
Jest to niepotrzebnie skomplikowane. odpowiedź realityone działa i jest znacznie bardziej zwięzła.
Steven Marlowe,
9
Jasne, jeśli używasz go tylko raz. Ale jeśli chcesz mieć więcej opcji formatowania przy użyciu interpolacji ciągów (co jest znacznie bardziej czytelne), możesz umieścić wszystkie rozszerzenia formatowania w pliku w innym miejscu i odwoływać się do niego w całym projekcie. Oczywiście idealnie Apple powinien zapewnić bibliotekę formatowania.
Anton Tcholakov,
2
To rozwiązanie nie będzie działać w Swift 1.2 bez rzutowania wyniku na String.
ibesora,
Niezły, ale nie przyjaciel Swift 2.
LastMove
798

prosty sposób to:

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

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
realityoneone
źródło
9
println(String(format: "a float number: %.5f", 1.0321))
zaph
78
Uważam, że jest to lepsza odpowiedź niż odpowiedź zaakceptowana. Jest znacznie bliższy standardowemu stylowi c printfbez konieczności pisania osobnych rozszerzeń.
Keith Morris
9
Nie zapomnij o „Importuj Fundację” na górze pliku.
Chris Gregg
3
Jest to lepsze niż zaakceptowana odpowiedź, ale nadal korzysta z metod Foundation (połączonych z Swift).
1
Koniecznieimport Foundation
NaN
125

Stwierdziłem, String.localizedStringWithFormatże działa całkiem dobrze:

Przykład:

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

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Valentin
źródło
Pytanie nie ma nic wspólnego z jednostkami obsługi. localizedStringWithFormat jest fajny, ale nie powiązany.
AmitP
Zgadzam się, AmitP, został zapytany, zanim String (format: ..., argumenty: ...) był dostępny
Valentin,
84

Jest to bardzo szybki i prosty sposób, który nie wymaga złożonego rozwiązania.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
fatihyildizhan
źródło
Nie kompiluje się (przy użyciu 3.0.2 w piaskownicy Swift IBM):Col 16: 'init' has been renamed to 'init(describing:)'
Peter Dillinger
@PeterDillinger przekazujesz opcjonalną zamiast nieopakowanej wartości.
Michael
63

Większość odpowiedzi tutaj jest poprawnych. Jednak w przypadku częstego formatowania liczby należy rozważyć rozszerzenie klasy Float w celu dodania metody zwracającej sformatowany ciąg. Zobacz przykładowy kod poniżej. Ten osiąga ten sam cel, używając formatera liczb i rozszerzenia.

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

Konsola pokazuje:

The velocity is 12.33
The velocity is 12.3

Aktualizacja 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)"
    }
}
Donn
źródło
12
Chciałbym, aby więcej osób skorzystało z NSNumberFormattertakiej odpowiedzi. Inne wysoko głosowane odpowiedzi po prostu nie odzwierciedlają ustawień regionalnych urządzenia (np. W niektórych lokalizacjach używają przecinka do miejsca po przecinku; to odzwierciedla; inne odpowiedzi tego nie robią).
Rob
3
Jedynym usprawnieniem, które chciałbym zobaczyć, jest przechowywanie formatera dla dowolnej liczby - NSNumberFormatters są drogie w budowie.
Kendall Helmstetter Gelner
1
dokładnie tego, czego szukałem! Dzięki
gunjot singh
Wiem, że to dość stare pytanie, ale NSNumberFormatterinicjowanie jest dość powolne. Jeśli to możliwe, pomaga zdefiniować jeden i użyć go ponownie. To powiedziawszy, czytam to pytanie, ponieważ w moim przypadku nie jest to możliwe.
promacuser
44

Nie możesz tego zrobić (jeszcze) z interpolacją ciągów. Najlepszym rozwiązaniem będzie nadal formatowanie NSString:

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

Ekstrapolując z Pythona, wydaje się, że rozsądną składnią może być:

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

Co następnie pozwala używać ich jako:

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

Możesz zdefiniować podobne operatory dla wszystkich typów liczbowych, niestety nie znalazłem sposobu, aby to zrobić za pomocą generyków.

Aktualizacja Swift 5

Począwszy od co najmniej Swift 5, Stringbezpośrednio obsługujeformat: inicjalizator, więc nie trzeba go używać, NSStringa @infixatrybut nie jest już potrzebny, co oznacza, że ​​powyższe próbki należy zapisać jako:

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

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

Double.pi % "%5.3f"         // "3.142"
David Berry
źródło
gdzie znalazłeś tę składnię „NSString (format:„ formatString ”, val)”. Nie widzę tego w dokumencie iBooks firmy Apple.
Duncan C
1
Jest to to samo, co konstruowanie dowolnego obiektu celu-c z szybkiego. Jest to szybka wersja[NSString stringWithFormat...
David Berry
Gotcha Jeszcze nie zaszedłem tak daleko w Swift iBook.
Duncan C
IIRC, którego nie było w Swift iBook. Było to podczas jednej z sesji WWDC. Szybka interoperacyjność w głębokości
ahruss
2
Jeśli wdrażasz% tak jak w Pythonie, powinno być na odwrót. "% 5,3f"% M_PI
Andy Dent
16

Dlaczego to takie skomplikowane? Możesz użyć tego zamiast:

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

Zobacz, jak działa na placu zabaw.

PS: Rozwiązanie od: http://rrike.sh/xcode/rounding-various-decimal-places-swift/

Steyn Viljoen
źródło
To zdecydowanie najlepsze rozwiązanie, nie rozumiem, jak to nie jest na szczycie.
pjtnt11,
7
nitpicky thing .. 1.500000000 byłoby tylko „1.5”, a nie „1.50”
styler1972
13
import Foundation

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

Stosowanie

let offset = CGPoint(1.23, 4.56)
print("offset: \(offset.x.string1) x \(offset.y.string1)")
// offset: 1.2 x 4.6
neoneye
źródło
10

Bardziej eleganckim i ogólnym rozwiązaniem jest przepisanie %operatora 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]
Vincent Guerci
źródło
Niestety, to umiera w wersji beta 6: błąd krytyczny: nie może być niebezpieczny BitCast między typami o różnych rozmiarach.
binarymochi
@binarymochi Z wersją beta 6: "Hello %@, This is pi : %.2f" % ["World", M_PI]działa, ale dziwnie "%@ %@" % ["Hello", "World"]podnosi can't unsafeBitCast... Zgadnij, że zostanie to naprawione w następnej wersji.
Vincent Guerci
Czy możesz zrobić „,” w używanym operatorze? „@infix func, (…”, a następnie napisz ciągi znaków takie jak „Witaj% @, to jest pi:% .2f”, [„you”, M_PI])?
Rick,
@ Rick no you not, ,nie jest poprawnym operatorem znaków, w Swift i większości języków. I imo, lepiej jest użyć %operatora, który już istnieje w innych językach. Zobacz developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Vincent Guerci
8

Szybki 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
onmyway133
źródło
let temp: Float = div * 100 let string = String (format: "% .2f", locale: Locale.current, arguments: temp) daje mi błąd. Nie można przekonwertować wartości typu „Float” na oczekiwany typ argumentu [CVarArg]
Chandni
musisz umieścić ten 15.123 w tablicy, aby działał
Dorian Roy
3
dla mnie działa: let string = String (format: "% .2f", myString)
Grzegorz R. Kulesza
6

Nadal możesz używać NSLog w Swift jak w Objective-C tylko bez znaku @.

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

Edycja: Po pracy z Swift od jakiegoś czasu chciałbym również dodać tę odmianę

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

Wynik:

2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
hol
źródło
6

Detale

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

Rozwiązanie 1

func zaokrąglony () -> Podwójny

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

func zaokrąglony (reguła: FloatingPointRoundingRule) -> Podwójny

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"

mutating func round ()

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

mutating func round (_ zasada: 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

Rozwiązanie 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)
    }
}

Stosowanie

_ = 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)

Pełna próbka

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)

Wynik

===========================
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
Wasilij Bodnarchuk
źródło
4
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)
Lucas Farah
źródło
3

Odpowiedzi udzielone do tej pory, które uzyskały największą liczbę głosów, opierają się na metodach NSString i będą wymagać importu Foundation.

Po wykonaniu tej czynności nadal masz dostęp do NSLog.

Myślę więc, że odpowiedź na pytanie, jeśli pytasz, jak kontynuować używanie NSLog w Swift, to po prostu:

import Foundation

fqdn
źródło
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)
Ravi Kumar
źródło
2

tutaj „czyste” szybkie rozwiązanie

 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)")
Christian Dietrich
źródło
2

Moc rozszerzenia

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

Wyjście: prędkość wynosi 12,3

Muhammad Aamir Ali
źródło
2

mniej pisania na klawiaturze:

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
szczyt
źródło
1

W ten sposób możesz również utworzyć operatora

operator infix <- {}

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

let str = "%d %.1f" <- [1453, 1.123]
otello
źródło
1

Również z zaokrągleniem:

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
ChikabuZ
źródło
1

użyj poniższej metody

let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)

println(output)
Ramkumar chintala
źródło
1

Wersja operatora ruby ​​/ python% Vincenta Guerci, zaktualizowana do wersji Swift 2.1:

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

"Hello %@, This is pi : %.2f" % ["World", M_PI]
Paul King
źródło
1

Wiele dobrych odpowiedzi powyżej, ale czasami wzorzec jest bardziej odpowiedni niż rodzaj „% .3f” gobbledygook. Oto moje ujęcie przy użyciu NumberFormatter w 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

Tutaj chciałem, aby zawsze były wyświetlane 2 miejsca po przecinku, ale trzeci tylko, jeśli nie był zero.

AlexT
źródło
1

Aktualizacja 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 ""
    }
}
Jason
źródło
1

Co z rozszerzeniami typów Double i 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)"
      }
   }
}

Stosowanie:

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

wydruki: 112 465 848 348 508,46

M. Wilm
źródło
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
użytkownik3778351
źródło
0

Nie wiem o dwóch miejscach po przecinku, ale oto jak drukować liczby zmiennoprzecinkowe z zerowymi miejscami po przecinku, więc wyobrażam sobie, że mogą to być 2 miejsca, 3 miejsca ... (Uwaga: musisz przeliczyć CGFloat na Double, aby przejść na String (format :) lub zobaczy wartość zero)

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))
}
jasne światło
źródło
0

Przykład Swift2: szerokość ekranu urządzenia iOS formatującego zmiennoprzecinkowe usuwając liczbę dziesiętną

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
Gunnar Forsgren - Mobimacja
źródło
-1

@Christian Dietrich:

zamiast:

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

może to być również:

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

[korekta:] Przepraszam za zamieszanie * - Oczywiście to działa z Doubles. Myślę, że najbardziej praktyczny (jeśli chcesz, aby cyfry były zaokrąglane, a nie odcinane), byłoby to coś takiego:

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
}

Tylko dla Float, po prostu zamień Double na Float, pow na powf i round na roundf.
Aktualizacja: Odkryłem, że najbardziej praktyczne jest użycie zwracanego typu Double zamiast String. Działa to samo dla danych wyjściowych String, tj .:

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

wypisuje: Pi ma w przybliżeniu 3.142,
więc możesz używać go w ten sam sposób dla napisów (możesz nawet pisać: println (d ~> 2)), ale dodatkowo możesz także użyć go do zaokrąglenia wartości bezpośrednio, tj .:

d = Double(slider.value) ~> 2

lub cokolwiek potrzebujesz ...

Stuepfnick
źródło
To oczywiście ma być komentarz. Rozumiem, że potrzebujesz więcej miejsca na rację i jest to cenne, ale jeśli masz zamiar napisać to jako pełnoprawną odpowiedź, spraw, by była przydatna sama w sobie, niezależnie; możesz na przykład dodać pełny kod, a następnie uwagę i potwierdzić Christianowi.
Jaime Gómez
@Jaime Gómez: Nie wolno mi komentować powyższej odpowiedzi. Ale zresztą miałem w tym fałszywą interpretację *. Nie wiem, czy warto je zachować, czy też należy je usunąć. Oczywiście można tego użyć w podobny sposób tylko do zaokrąglania (bez konwersji ciągów) i można go łatwo przetłumaczyć na inne języki programowania. * Przyjąłem, że w Double jest zaokrąglane do około 8 cyfr, co oczywiście było błędem, ponieważ zaokrągliłem go za pomocą Float i przypadkowo przekonwertowałem go na Double.
Stuepfnick
PS: Wolałbym raczej używać podobnych metod do zaokrąglania, a nie ciągów wyjściowych, więc zwróć typ Double (i zwykła metoda?) Sidenote : Jeśli zaokrąglisz Float w ten sposób (tj. Z Slidera), a wynik do String go będzie dobrze, podobnie jak „0.1”, ale jeśli przekonwertujesz Float na Double, a następnie na String *, będzie to: „0.100000001490116”, ponieważ Float nie jest w stanie dokładnie zapisać 0,1, tylko bardzo blisko. Wydaje mi się, że tak samo jest z Double, tylko z podwójną precyzją ;) Dlatego zawsze przed zaokrąglaniem zawsze konwertuj na Double , aby był możliwie dokładny i konwertuje na String również.
Stuepfnick
PPS: Oczywiście w przypadku Return Type Double czasem jest to trochę inaczej, tzn. Jeśli chcesz ustawić tekst etykiety, musisz napisać: myLabel.text = "\ (d ~> 2)" zamiast po prostu: myLabel. text = d ~> 2 , ale nadal uważam, że funkcja jest bardziej praktyczna w ten sposób. (oczywiście każdy może robić, co chce, tylko moje myśli…)
Stuepfnick,
-2

posługiwać się

CGFloat 

lub

Float.roundTo(places:2)
Nicson
źródło
1
CGFloat nie ma rundy członkowskiej do
Chandni