Прецизионный спецификатор формата строки в Swift

395

Ниже показано, как я бы предварительно обрезал число с плавающей запятой до двух десятичных разрядов.

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

Я проверил документы и электронную книгу, но не смог понять это. Спасибо!

user3524868
источник

Ответы:

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

Я думаю, что это наиболее Swift-подобное решение, связывающее операции форматирования непосредственно с типом данных. Вполне может быть, что где-то есть встроенная библиотека операций форматирования, или, возможно, она скоро выйдет. Имейте в виду, что язык все еще находится в бета-версии.

Антон Чолаков
источник
76
Это излишне сложно. Ответ от реалии работает и является гораздо более кратким.
Стивен Марлоу
9
Конечно, если вы используете его только один раз. Но если вы хотите иметь больше опций форматирования с использованием интерполяции строк (что гораздо удобнее для чтения), вы можете поместить все расширения форматирования в файл в другом месте и ссылаться на него в рамках всего проекта. Конечно, в идеале Apple должна предоставить библиотеку форматирования.
Антон Чолаков
2
Это решение не будет работать в Swift 1.2 без приведения результата к String.
Ибесора
Хороший, но не Swift 2 Friend.
LastMove
798

простой способ это:

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

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
realityone
источник
9
println(String(format: "a float number: %.5f", 1.0321))
Zaph
78
Я считаю, что это лучший ответ, чем принятый ответ. Это намного ближе к стандартному c-стилю printfбез необходимости писать отдельные расширения.
Кит Моррис
9
Не забудьте «импортировать фундамент» вверху файла.
Крис Грегг
3
Это лучше, чем принятый ответ, но все еще использует методы Foundation (соединенные со Swift).
1
Обязательноimport Foundation
NaN
125

Я нашел String.localizedStringWithFormatработать довольно хорошо:

Пример:

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

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
Valentin
источник
Вопрос не имеет ничего общего с единицами обработки. localizedStringWithFormat - это хорошо, но не связано.
AmitP
Я согласен, AmitP, его спросили до того, как String (формат: ..., аргументы: ...) был доступен
Валентин
84

Это очень быстрый и простой способ, который не требует сложного решения.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
fatihyildizhan
источник
Это не компилируется (используя 3.0.2 в песочнице IBM Swift):Col 16: 'init' has been renamed to 'init(describing:)'
Питер Диллинджер
@PeterDillinger вы передаете необязательное, а не развернутое значение.
Майкл
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, чтобы больше людей использовали , как этот ответ. Другие ответы с высоким рейтингом просто не отражают настройки локали устройства (например, в некоторых локалях они используют запятую для десятичного разряда; это отражает это; другие ответы нет).
Роб
3
Единственное улучшение, которое я хотел бы видеть, - это сохранение форматера для любого заданного числа - NSNumberFormatters создавать дорого.
Кендалл Хельмштеттер Гелнер,
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"

Вы можете определить аналогичные операторы для всех числовых типов, к сожалению, я не нашел способа сделать это с обобщениями.

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 (format:" formatString ", val) '. Я не вижу этого в документе iBooks от Apple.
Дункан C
1
Это то же самое, что построить любой объект-объект из Swift. Это быстрая версия[NSString stringWithFormat...
Дэвид Берри
Попался. Я еще не зашел так далеко в Swift iBook.
Дункан C
IIRC, которого не было в Swift iBook. Это было на одной из сессий WWDC. Быстрая совместимость в глубине
ahruss
2
Если вы реализуете%, как в Python, все должно быть наоборот. "% 5.3f"% M_PI
Энди Дент
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
Нечеткая вещь .. 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
neoneye
источник
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 между типами разных размеров.
двоичныеmochi
@binarymochi с бета-версией 6: "Hello %@, This is pi : %.2f" % ["World", M_PI]работает, но странным образом "%@ %@" % ["Hello", "World"]поднимается can't unsafeBitCast... Угадайте, это будет исправлено в следующей версии.
Винсент Гуерси
Не могли бы вы сделать ',' в оператор используется? '@infix func, (…', а затем напишите свои строки, например "Hello% @, это pi:% .2f", ["you", M_PI])?
Рик
@ Рик нет, вы не можете, ,это не допустимый символьный оператор, в Swift и большинстве языков. И, imo, лучше использовать %оператор, который уже существует на других языках. См developer.apple.com/library/ios/documentation/Swift/Conceptual/...
Винсент Guerci
8

Swift 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
onmyway133
источник
let temp: Float = div * 100 let string = String (формат: "% .2f", locale: Locale.current, arguments: temp), это дает мне ошибку. Невозможно преобразовать значение типа 'Float' в ожидаемый тип аргумента '[CVarArg]
Чандни
вам нужно поместить 15.123 в массив, чтобы он работал
Дориан Рой,
3
у меня работает: let string = String (формат: "% .2f", myString)
Гжегож Р. Кулеша
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 roundnded () -> Двойной

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

округленная функция (_ rule: 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

мутирующий раунд функции (_ rule: 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
Василий Боднарчук
источник
4
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)
Лукас Фарах
источник
3

Ответы, данные до сих пор и получившие наибольшее количество голосов, основаны на методах NSString и потребуют, чтобы вы импортировали Foundation.

Сделав это, вы по- прежнему имеете доступ к NSLog.

Поэтому я думаю, что ответ на вопрос, если вы спрашиваете, как продолжить использовать NSLog в Swift, просто:

import Foundation

FQDN
источник
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

Мухаммед Амир Али
источник
2

менее печатный способ:

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
пик
источник
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
ChikabuZ
источник
1

используйте метод ниже

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

println(output)
Рамкумар Чинтала
источник
1

Версия оператора ruby ​​/ python% Винсента Гуерчи, обновленная для Swift 2.1:

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

"Hello %@, This is pi : %.2f" % ["World", M_PI]
Пол Кинг
источник
1

Выше много хороших ответов, но иногда шаблон более уместен, чем «% .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 десятичных знака, но только третий, если он не равен нулю.

AlexT
источник
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
user3778351
источник
0

Я не знаю о двух десятичных разрядах, но вот как вы можете печатать числа с нулем после запятой, поэтому я думаю, что это может быть 2 места, 3 места ... (Примечание: вы должны преобразовать CGFloat в Double, чтобы передать в строку (формат :) или он будет видеть значение ноль)

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))
}
ClearLight
источник
0

Пример Swift2: ширина экрана устройства iOS, форматирующего Float, удаляющего десятичную

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
Гуннар Форсгрен - Mobimation
источник
-1

@ Кристиан Дитрих:

вместо:

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.
Обновление: я обнаружил, что наиболее целесообразно использовать тип возврата Double вместо String. Он работает так же для вывода String, то есть:

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

печатает: Pi примерно 3,142.
Таким образом, вы можете использовать его для Strings (вы можете даже написать: println (d ~> 2)), но дополнительно вы также можете использовать его для прямого округления значений, то есть:

d = Double(slider.value) ~> 2

или что вам нужно ...

Stuepfnick
источник
Это очевидно предназначено для комментария, я понимаю, что вам нужно больше места, чтобы подчеркнуть, и это ценно, но если вы собираетесь написать его как полноценный ответ, сделайте его полезным самостоятельно, независимо; Вы можете добавить полный код, например, а затем сделать замечание и подтвердить для Кристиана.
Хайме Гомес
@ Хайме Гомес: Мне не разрешено комментировать вышеуказанный ответ. Но в любом случае, у меня была какая-то ложная интерпретация *. Не знаю, стоит ли его хранить или его следует удалить. Конечно, это может быть использовано аналогичным образом только для округления (без преобразования строк) и может быть легко переведено на другие языки программирования. * Я предположил, что с Double он округляется до 8 цифр, что, конечно, было ошибкой, потому что я сделал округление с Float и преобразовал его в Double случайно.
Stuepfnick
PS: Я бы предпочел использовать подобные методы больше для округления в целом, а не для вывода в виде String, поэтому возвращайте тип Double (& обычный метод?) Sidenote : Если вы округлите Float таким образом (т.е. из ползунка) и результат для String it все будет в порядке, как «0.1», но если вы конвертируете этот Float в Double, а затем в String *, это будет: «0.100000001490116», так как Float не способен точно хранить 0.1, только очень близко. Я предполагаю, что то же самое с Double, только с двойной точностью ;) Так что всегда конвертируйте в Double перед округлением, так что он будет максимально точным и тоже преобразуется в String.
Stuepfnick
PPS: Конечно, с типом возврата Double иногда это немного отличается, т.е. если вам нужно установить текст метки, вам нужно написать: myLabel.text = "\ (d ~> 2)" вместо just: myLabel. text = d ~> 2 , но я все еще думаю, что эта функция более практична. (конечно каждый может делать, что хочет, только мои мысли…)
Stuepfnick
-2

использование

CGFloat 

или

Float.roundTo(places:2)
Nicson
источник
1
У CGFloat нет участников в раунде
Chandni