Описатель точного формата строки в Swift

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

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

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


person user3524868    schedule 05.06.2014    source источник


Ответы (28)


Мое лучшее решение, следующее из ответа Дэвида:

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

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

person Anton Tcholakov    schedule 05.06.2014
comment
Это излишне сложно. Реальный ответ работает и намного более краток. - person Steven Marlowe; 20.12.2014
comment
Конечно, если вы используете его только один раз. Но если вы хотите иметь больше параметров форматирования с использованием строковой интерполяции (что гораздо более читабельно), вы можете поместить все расширения форматирования в файл в другом месте и ссылаться на него во всем проекте. Конечно, в идеале Apple должна предоставить библиотеку форматирования. - person Anton Tcholakov; 20.12.2014
comment
Это решение не будет работать в Swift 1.2 без преобразования результата в String. - person ibesora; 10.04.2015
comment
Хороший, но не Swift 2 Friend. - person LastMove; 29.02.2016
comment
В SwiftU я использую Text("\(someDouble, specifier: "%.3f")") - person multitudes; 02.10.2020

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

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

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
person realityone    schedule 08.06.2014
comment
Я считаю, что это лучший ответ, чем принятый. Он намного ближе к стандартному c-стилю printf без необходимости писать отдельные расширения. - person Keith Morris; 20.09.2014
comment
Не забудьте импортировать Foundation в верхней части файла. - person Chris Gregg; 03.11.2014
comment
Это лучше, чем принятый ответ, но все еще используются методы Foundation (подключенные к Swift). - person ; 04.01.2015
comment
FWIW Мне нужно было преобразовать Float в 2 десятичных разряда и использовать var valueAsString = String (формат: 0.2f, value), и он работал без импорта Foundation с использованием Xcode 6.3 - person Andrew H; 07.07.2015
comment
Обязательно import Foundation - person NaN; 30.04.2016
comment
Также можно использовать import Cocoa. - person RobG; 22.03.2018
comment
удивительно, что Swift, похоже, не поддерживает собственное форматирование строк в print (). Хотя это может показаться тривиальным, у этого типа решения есть некоторые проблемы с эффективностью, поскольку он создает объект String для выполнения такой тривиальной задачи. - person galactica; 27.02.2019

Я обнаружил, что String.localizedStringWithFormat работает достаточно хорошо:

Пример:

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

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
person Valentin    schedule 18.09.2014
comment
Вопрос не имеет отношения к единицам обработки. localizedStringWithFormat хорош, но не связан. - person AmitP; 14.11.2016
comment
Я согласен с AmitP, его спросили до того, как String (format: ..., arguments: ...) был доступен - person Valentin; 14.11.2016

Это очень быстрый и простой способ, не требующий сложных решений.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
person fatihyildizhan    schedule 03.01.2016
comment
Это не компилируется (с использованием 3.0.2 в песочнице IBM Swift): Col 16: 'init' has been renamed to 'init(describing:)' - person Peter Dillinger; 30.01.2017
comment
@PeterDillinger вы передаете необязательное значение вместо развернутого значения. - person Michael; 27.02.2018

Большинство ответов здесь действительны. Однако, если вы будете часто форматировать число, подумайте о расширении класса 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)"
    }
}
person Donn    schedule 02.10.2014
comment
Я бы хотел, чтобы больше людей использовали NSNumberFormatter, как этот ответ. Другие ответы, получившие большое количество голосов, просто не отражают настройки локали устройства (например, в некоторых регионах они используют запятую для десятичного знака; это отражает это; другие ответы нет). - person Rob; 31.03.2015
comment
Единственное улучшение, которое я хотел бы видеть, - это сохранение средства форматирования для любого заданного числа - создание NSNumberFormatters дорого обходится. - person Kendall Helmstetter Gelner; 02.04.2015
comment
именно то, что я искал! Спасибо - person gunjot singh; 19.11.2016
comment
Я знаю, что это довольно старый вопрос, но NSNumberFormatter довольно медленно инициализируется. Если возможно, это помогает определить один и использовать его повторно. Тем не менее, я читаю этот вопрос, потому что в моем случае это невозможно. - person promacuser; 22.06.2017

Вы не можете сделать это (пока) с помощью строковой интерполяции. Лучшим вариантом будет форматирование 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"
person David Berry    schedule 05.06.2014
comment
где вы нашли этот синтаксис `NSString (format: formatString, val) '. Я не вижу этого в документе iBooks от Apple. - person Duncan C; 05.06.2014
comment
Это то же самое, что и создание любого объекта objective-c из swift. Это быстрая версия [NSString stringWithFormat... - person David Berry; 05.06.2014
comment
Попался. Я еще не продвинулся так далеко в Swift iBook. - person Duncan C; 06.06.2014
comment
IIRC, которого не было в Swift iBook. Это было на одной из сессий WWDC. Подробная информация о совместимости Swift - person ahruss; 08.06.2014
comment
@ Дэвид, посмотри мой ответ, это может тебя заинтересовать;) - person Vincent Guerci; 14.06.2014
comment
@VincentGuerci на самом деле у меня где-то есть еще один вопрос, на который я отвечаю глобальным решением для опции%. См. Вопрос и мой ответ здесь - person David Berry; 14.06.2014
comment
Если бы вы реализовывали% как в Python, должно быть наоборот. % 5.3f% M_PI - person Andy Dent; 19.06.2014
comment
@AndyDent хороший момент. Хорошо, что я не зацикливаюсь на семантике :) - person David Berry; 19.06.2014

Зачем все усложнять? Вместо этого вы можете использовать это:

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

Посмотрите, как это работает в Playground.

PS: Решение от: http://rrike.sh/xcode/rounding-various-decimal-places-swift/

person Steyn Viljoen    schedule 09.07.2015
comment
Это, безусловно, лучшее решение, я не понимаю, почему это не наверху. - person pjtnt11; 26.07.2015
comment
мелочь .. 1.500000000 будет только 1.5, а не 1.50 - person tango whiskey double; 22.09.2015

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
person neoneye    schedule 02.04.2016

Более элегантное и универсальное решение - переписать оператор 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]
person Vincent Guerci    schedule 14.06.2014
comment
К сожалению, это умирает в бета-версии 6: фатальная ошибка: невозможно unsafeBitCast между типами разных размеров. - person binarymochi; 22.08.2014
comment
@binarymochi В Beta 6: "Hello %@, This is pi : %.2f" % ["World", M_PI] работает, но, как ни странно, "%@ %@" % ["Hello", "World"] поднять _3 _... Думаю, это будет исправлено в следующей версии. - person Vincent Guerci; 22.08.2014
comment
Не могли бы вы превратить ',' в используемый оператор? '@infix func, (…', а затем напишите свои строки как Hello% @, это pi:% .2f, [you, M_PI])? - person Rick; 19.10.2014
comment
@Rick нет, вы не можете, , не является допустимым символьным оператором в Swift и большинстве языков. И я думаю, лучше использовать оператор %, который уже существует на других языках. См. developer.apple.com/library/ios/documentation/Swift/Conceptual/ - person Vincent Guerci; 23.10.2014

Подробности

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

Решение 1

func rounded () -> Double

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

func rounded (_ 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"

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

изменение раунда функции (_ правило: 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
person Vasily Bodnarchuk    schedule 21.10.2017

Swift 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
person onmyway133    schedule 09.03.2018
comment
let temp: Float = div * 100 let string = String (формат:% .2f, locale: Locale.current, arguments: temp) дает мне ошибку. Невозможно преобразовать значение типа Float в ожидаемый тип аргумента [CVarArg] - person Chandni; 17.05.2018
comment
вам нужно поместить это 15.123 в массив, чтобы он работал - person Dorian Roy; 26.09.2018
comment
у меня работает: let string = String (формат:% .2f, myString) - person Grzegorz R. Kulesza; 19.03.2019

Вы по-прежнему можете использовать 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
person hol    schedule 12.07.2014

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

Однако после этого у вас все еще есть доступ к NSLog.

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

import Foundation

person fqdn    schedule 08.06.2014

здесь "чистое" быстрое решение

 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)")
person Christian Dietrich    schedule 19.06.2014

Сила расширения

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.

person Muhammad Aamir Ali    schedule 21.01.2016

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

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
person peak    schedule 27.02.2016

А как насчет расширений на типах 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

person M Wilm    schedule 03.02.2019

Вы также можете создать оператора таким образом

operator infix <- {}

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

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

Также с округлением:

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
person ChikabuZ    schedule 03.10.2014

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

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

println(output)
person Ramkumar chintala    schedule 10.07.2015

Версия оператора 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]
person Paul King    schedule 05.11.2015

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

person AlexT    schedule 07.05.2017

Обновление 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 ""
    }
}
person Leanid Vouk    schedule 04.11.2018

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

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))
}
person clearlight    schedule 07.02.2015

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

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))
person Gunnar Forsgren - Mobimation    schedule 04.11.2015

После iOS 15+ рекомендуется следующее решение:

2.31234.formatted(.number.precision(.fractionalLength(1)))
person Tiago Almeida    schedule 11.06.2021

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

вместо того:

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, то есть:

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

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

d = Double(slider.value) ~> 2

или что угодно…

person Stuepfnick    schedule 22.02.2015
comment
Очевидно, это комментарий, я понимаю, что вам нужно больше места, чтобы изложить точку зрения, и это ценно, но если вы собираетесь написать его как полноценный ответ, сделайте его полезным сам по себе, независимо; вы можете, например, добавить полный код, а затем сделать замечание и поблагодарить Кристиана. - person Hanuman; 23.02.2015
comment
@ Хайме Гомес: Мне не разрешено комментировать приведенный выше ответ. Но в любом случае у меня было какое-то ложное толкование * в этом. Не знаю, стоит ли его сохранить или удалить. Конечно, это может быть использовано аналогичным образом только для округления (без преобразования String) и может быть легко переведено на другие языки программирования. * Я предполагал, что с помощью Double оно округляется примерно до 8 цифр, что, конечно, было ошибкой, потому что я округлил его с помощью Float и случайно преобразовал в Double. - person Stuepfnick; 23.02.2015
comment
PS: Я бы предпочел использовать аналогичные методы больше для округления в целом, а не для вывода String, поэтому возвращаемый тип Double (& обычный метод?) Sidenote: если вы округляете Float таким образом (то есть из Slider ) и результат в String будет хорошо, например 0.1, но если вы конвертируете Float в Double, а затем в String *, это будет: 0.100000001490116, поскольку Float не может точно хранить 0.1, только очень близко. Я думаю, что то же самое и с Double, только с двойной точностью;) Итак, всегда преобразовывать в Double перед округлением, поэтому оно будет таким же точным, как возможно и также преобразуется в String. - person Stuepfnick; 02.03.2015
comment
PPS: Конечно, с Return Type Double иногда немного по-другому, например, если вам нужно установить текст метки, вам нужно вместо этого написать: myLabel.text = \ (d ~ ›2) всего: myLabel.text = d ~ ›2, но я все же думаю, что в этом случае функция более практична. (конечно, каждый может делать, что хочет, только мои мысли ...) - person Stuepfnick; 07.03.2015

использовать

CGFloat 

or

Float.roundTo(places:2)
person Nicson    schedule 10.12.2017
comment
У CGFloat нет участников раунда, чтобы - person Chandni; 17.05.2018