Округление двойного значения до x количества десятичных знаков в swift

Может ли кто-нибудь сказать мне, как округлить двойное значение до x десятичных знаков в Swift?

У меня есть:

var totalWorkTimeInHours = (totalWorkTime/60/60)

При этом totalWorkTime - это NSTimeInterval (double) в секунду.

totalWorkTimeInHours даст мне часы, но это даст мне количество времени в таком длинном точном числе, например. 1.543240952039 ......

Как мне округлить это, скажем, до 1,543, когда я печатаю totalWorkTimeInHours?


person Leighton    schedule 07.12.2014    source источник
comment
См. мой ответ, чтобы найти до 9 различных способов округления двойника с использованием Дарвина round(_:), Double round(), NSString инициализатор, String инициализатор , NumberFormatter, двойное расширение или даже NSDecimalNumber и Decimal.   -  person Imanou Petit    schedule 07.02.2018
comment
@Rounded, быстрая оболочка свойств 5.1: gist.github.com/abhijithpp/1cc41b41a5d1c8c8   -  person Abhijith    schedule 12.03.2020


Ответы (28)


Для этого вы можете использовать функцию Swift round.

Чтобы округлить Double с точностью до 3 цифр, сначала умножьте его на 1000, округлите и разделите результат округления на 1000:

let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y)  // 1.236

За исключением любых решений printf(...) или String(format: ...), результат этой операции по-прежнему имеет тип Double.

РЕДАКТИРОВАТЬ:
Что касается комментариев, которые иногда не работают, прочтите следующее:

Что каждый программист должен знать об арифметике с плавающей запятой

person zisoft    schedule 07.12.2014
comment
По некоторым причинам это не помогает .. Я использую это в следующем случае TransformOf ‹Double, String› (fromJSON: {Double (round (($ 0! As NSString) .doubleValue * 100) / 100)}, toJSON: {($ 0)}) - person Fawkes; 31.07.2015
comment
У меня не работает на детской площадке: let rate = 9.94999999999; Double(round(rate * 100) / 100); Вывод: 9.94999999999, 9.949999999999999 Работает только для печати, но как я могу назначить это переменной? - person Alexander Yakovlev; 05.05.2016
comment
Для этого вы должны использовать Decimal, а не просто Double. - person csotiriou; 12.12.2016
comment
То, что каждый компьютерный ученый должен знать об арифметике с плавающей запятой, занимает 73 страницы. Что за TL; DR по этому поводу? :) - person JaredH; 15.04.2018
comment
@SashaKid, какое решение для вашего вопроса. У меня такая же проблема. Я не могу присвоить это переменной - person HardikDG; 03.10.2018
comment
@HardikDG Не помню, извините :-) - person Alexander Yakovlev; 04.10.2018
comment
С двойным расширением ознакомьтесь с этим ответом: stackoverflow.com/a/54372912/7343596 - person balazs630; 13.04.2019
comment
@SashaKid Судя по всему, теперь работает. Только что получил 9,95 для вашего примера на детской площадке. Свифт 4. - person Kirill Kudaev; 15.04.2019

Расширение для Swift 2

Более общим решением является следующее расширение, которое работает со Swift 2 и iOS 9:

extension Double {
    /// Rounds the double to decimal places value
    func roundToPlaces(places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(self * divisor) / divisor
    }
}


Расширение для Swift 3

В Swift 3 round заменяется на rounded:

extension Double {
    /// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}


Пример, который возвращает значение Double с округлением до 4 знаков после запятой:

let x = Double(0.123456789).roundToPlaces(4)  // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4)  // Swift 3 version
person Sebastian    schedule 15.09.2015
comment
Добавил этот код в свое репо, спасибо! github.com/goktugyil/EZSwiftExtensions/blob/ - person Esqarrouth; 23.03.2016
comment
Природа Swift Double, похоже, может быть неточной - из-за способа хранения / доступа к ней в двоичном формате, даже использование этой функции округления не вернет число, округленное до трех знаков после запятой: например, round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0) возвращает 8.460000000000001. То же самое с Float, по крайней мере в этом сценарии, действительно, похоже, работает: round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0) дает 8.46. Стоит отметить кое-что. - person Ben Saufley; 08.07.2016
comment
К сожалению, это больше не работает в Swift 3, я получаю эту ошибку No '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule' - person koen; 20.08.2016
comment
Я обновил решение и добавил расширение для Swift 3. - person Sebastian; 22.08.2016
comment
Чтобы быть более быстрым 3 ... вы должны изменить на func round round (toPlaces places: Int) - ›Double - person FouZ; 07.09.2016
comment
согласен с ФоЗ. Но я думаю, что округление (до мест: Int) намного быстрее. - person Mark; 14.10.2016
comment
@BenSaufley Но тоже не работает, если ввести 98,68. В этом случае я получаю 98.6800003 - person Alexander Khitev; 21.12.2016
comment
Мне нравится более общее расширение для чисел с плавающей запятой: extension FloatingPoint { func roundTo(places:Int) -> Self { let divisor = Self(Int(pow(10.0, Double(places)))) return (self * divisor).rounded() / divisor } } - person Libor Zapletal; 19.03.2017
comment
С этим решением 8.104.ounded (toPlaces: 2) вернет 8.1, если отображать его как String, мне все равно нужно будет использовать String (format ...), чтобы отобразить его как 8.10 - person code4latte; 01.12.2017
comment
Куда в моей программе это вставить? - person Doug Null; 25.06.2021

Как округлить это значение, скажем, до 1,543 при печати totalWorkTimeInHours?

Чтобы округлить totalWorkTimeInHours до 3 цифр для печати, используйте конструктор String, который принимает строку format:

print(String(format: "%.3f", totalWorkTimeInHours))
person vacawama    schedule 07.12.2014
comment
Это усечение, а не округление - person Eyeball; 07.12.2014
comment
@Eyeball: На самом деле, он ДЕЙСТВИТЕЛЬНО круглый. Это то же поведение, что и функция printf C, которая округляет до запрошенных цифр. Итак, String(format: "%.3f", 1.23489) печатает 1.235 - person zisoft; 07.12.2014
comment
Это работает и на double? Или только float? - person Clifton Labrum; 25.06.2015
comment
Исходный плакат ищет числовое значение для использования, а не строку для отображения. - person pr1001; 16.02.2016
comment
@ pr1001, возможно, и так, но в то время это было неясно, и 46 других сочли мой ответ полезным. Stack Overflow - это больше, чем просто помощь OP. - person vacawama; 16.02.2016
comment
String(format: "%.1f", 10.45) печатает 10.4 на детской площадке. - person Clifton Labrum; 27.05.2016
comment
@CliftonLabrum, сделай String(format: "%.15f", 10.45), и правда откроется тебе. - person vacawama; 27.05.2016
comment
странно, каждый раз возвращается 0.00. - person Eric H; 24.06.2016
comment
Если вы делите числа, убедитесь, что они оба Double, а не Int - person spencer.sm; 03.05.2018
comment
@ pr1001 ОП специально спросил: Как мне округлить это, скажем, до 1,543, когда я печатаю totalWorkTimeInHours? Итак, OP говорит о том, как отображать число, поэтому решение String совершенно законно. - person Zonker.in.Geneva; 24.10.2018
comment
Такие вещи случаются со мной, когда я уже знал решение проблемы, но использую stackoverflow .. В любом случае, спасибо, что напомнили мне! :) - person Amber K; 23.11.2018
comment
Вы всегда можете преобразовать в значение String с помощью этого метода, а затем преобразовать новую строку с количеством десятичных знаков, которое вы хотите, обратно в двойное. - person D. Pratt; 26.03.2019

В Swift 5, в соответствии с вашими потребностями, вы можете выбрать один из 9 следующих стилей, чтобы получить округленный результат от Double.


№1. Использование метода FloatingPoint rounded()

В простейшем случае вы можете использовать метод Double rounded().

let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№2. Использование метода FloatingPoint rounded(_:)

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№3. Использование функции Дарвина round

Foundation предлагает round функцию через Дарвина.

import Foundation

let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№4. Использование пользовательского метода расширения Double, созданного с помощью функций Дарвина round и pow

Если вы хотите повторить предыдущую операцию много раз, хорошей идеей может быть рефакторинг вашего кода.

import Foundation

extension Double {
    func roundToDecimal(_ fractionDigits: Int) -> Double {
        let multiplier = pow(10, Double(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№5. Использование метода NSDecimalNumber rounding(accordingToBehavior:)

При необходимости NSDecimalNumber предлагает подробное, но мощное решение для округления десятичных чисел.

import Foundation

let scale: Int16 = 3

let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)

let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№6. Использование функции NSDecimalRound(_:_:_:_:)

import Foundation

let scale = 3

var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)

var roundedValue1 = Decimal()
var roundedValue2 = Decimal()

NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

№7. Использование инициализатора NSString init(format:arguments:)

Если вы хотите вернуть NSString из операции округления, использование инициализатора NSString - простое, но эффективное решение.

import Foundation

let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

№8. Использование инициализатора String init(format:_:)

Тип String Swift связан с классом NSString Foundation. Следовательно, вы можете использовать следующий код, чтобы вернуть String из операции округления:

import Foundation

let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

№9. Использование NumberFormatter

Если вы ожидаете получить String? от операции округления, NumberFormatter предлагает решение с широкими возможностями настройки.

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3

let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")
person Imanou Petit    schedule 26.06.2016
comment
Отличный ответ. Я мог бы предложить в пункте 5, что вы могли бы рассмотреть возможность использования Decimal, который является бесплатным мостом для NSDecimalNumber. Decimal - это собственный тип Swift, предлагающий более элегантную поддержку для собственных операторов, таких как +, - и т. Д. - person Rob; 05.02.2018
comment
@Rob Я обновил свой ответ функцией NSDecimalRound(_:_:_:_:). Спасибо. - person Imanou Petit; 07.02.2018
comment
Выбор # 9 гарантирует, что вы ожидаете фиксированную дробь (количество цифр точности), скажем, десятичное число 43,12345 и дробь = 6, вы получите 43,123450 - person Almas Adilbek; 20.04.2018
comment
@ImanouPetit Спасибо, что разместили это. Я могу взорвать пару расширений. - person Adrian; 03.06.2018
comment
Мне грустно, NumberFormatter - это последний вариант, хотя он должен быть первым для представления чисел пользователям. Никакой другой метод не генерирует правильно локализованные числа. - person Sulthan; 20.01.2019
comment
Что за код, если у меня есть 0,00639542871, чтобы ОБНАРУЖИТЬ ПЕРВОЕ ЧИСЛО ПОСЛЕ НУЛЕЙ, и делает его +1, чтобы результат был 0,007 - person Bogdan Bogdanov; 09.10.2019
comment
Это работает ТОЛЬКО, если вы явно передаете результат в float: let roundedValue1 = Float ((0.6856 * 100). Round (.up) / 100) - person Hadži Lazar Pešić; 06.03.2020
comment
Чрезвычайно настраиваемая природа NumberFormatter сделала это за меня! Рад, что прочитал ваш ответ до конца. - person Carl Smith; 09.04.2021

В Swift 5.3 и Xcode 12:

let pi: Double = 3.14159265358979
String(format:"%.2f", pi)

Пример:

введите описание изображения здесь

PS.: It still the same since Swift 2.0 and Xcode 7.2
person Claudio Guirunas    schedule 20.11.2015

Это полностью отработанный код

Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 и выше

let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)

выход - 123

let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)

выход - 123,3

let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)

выход - 123,33

let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)

выпуск - 123,326

person Krunal Patel    schedule 27.09.2017
comment
одна строчка?, вроде как 3 строчки;) - person Petter Friberg; 27.09.2017
comment
вы не можете рассчитывать вещи, используя строки, я не думаю, что это правильный ответ, потому что он предназначен только для отображения. - person JBarros35; 10.03.2020

Основываясь на ответе Йоги, вот функция Swift, которая выполняет эту работу:

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
}
person Ash    schedule 04.02.2015

В Swift 3.0 и Xcode 8.0:

extension Double {
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

Используйте это расширение так:

let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
person jaiswal Rajan    schedule 19.12.2016

Swift 4, Xcode 10

yourLabel.text =  String(format:"%.2f", yourDecimalValue)
person Naishta    schedule 21.01.2019
comment
Я не голосовал против, но думаю, причина может быть в том, что это возвращает строковое представление числа, а не числа. Это нормально, если это все, что вам нужно, но вы можете захотеть округлить само число для дальнейшего использования. OP сказал, когда я печатаю, поэтому я считаю, что в данном случае это приемлемое, простое и чистое решение. - person Ben Stahl; 20.02.2019
comment
Идеально. Однострочное решение. Мне просто нужно было отображать десятичные значения в виде строк в моих ярлыках. - person zeeshan; 06.03.2019

Код для конкретных цифр после десятичных знаков:

var a = 1.543240952039
var roundedString = String(format: "%.3f", a)

Здесь% .3f сообщает Swift округлить это число до трех знаков после запятой. Если вам нужно двойное число, вы можете использовать этот код:

// Строка для удвоения

var roundedString = Double(String(format: "%.3f", b))

person Merichle    schedule 10.02.2018

Используйте встроенную библиотеку Foundation Darwin

SWIFT 3

extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return Darwin.round(self * divisor) / divisor
    }
}

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

let number:Double = 12.987654321
print(number.round(to: 3)) 

Выходы: 12.988

person George Filippakos    schedule 30.04.2017

Если вы хотите округлить Double значения, вы можете использовать Swift Decimal, чтобы не вводить никаких ошибок, которые могут возникнуть при математических вычислениях с этими округленными значениями. Если вы используете Decimal, он может точно представлять десятичные значения этого округленного значения с плавающей запятой.

Итак, вы можете:

extension Double {
    /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
    ///
    /// - Parameters:
    ///   - scale: How many decimal places to round to. Defaults to `0`.
    ///   - mode:  The preferred rounding mode. Defaults to `.plain`.
    /// - Returns: The rounded `Decimal` value.

    func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
        var decimalValue = Decimal(self)
        var result = Decimal()
        NSDecimalRound(&result, &decimalValue, scale, mode)
        return result
    }
}

Затем вы можете получить округленное значение Decimal следующим образом:

let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30

И если вы хотите отобразить его с указанным количеством десятичных знаков (а также локализовать строку для текущего языкового стандарта пользователя), вы можете использовать NumberFormatter:

let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

if let string = formatter.string(for: value) {
    print(string)
}
person Rob    schedule 05.02.2018
comment
Лучший ответ на данный момент. - person Codetard; 23.09.2018
comment
(4.81).roundedDecimal(to: 2, mode: .down) вернет 4,8 вместо 4,81, используйте Decimal(string: self.description)! для точного decimalValue - person vk.edward.li; 22.11.2018
comment
@ vk.edward.li - Да, следует опасаться округления десятичных дробей вверх / вниз, потому что такие значения, как 4.81, просто не могут быть точно представлены с помощью Double (он становится 4.8099999999999996). Но я бы не советовал использовать description (поскольку округление, которое он использует, не задокументировано и может быть изменено). Если вы действительно хотите выполнять вычисления с точностью до десятичной дроби, вам следует полностью избегать Double и вместо этого использовать напрямую Decimal (например, Decimal(sign: .plus, exponent: -2, significand: 481) или Decimal(string: "4.81"). Но не используйте description. - person Rob; 26.11.2018
comment
@Rob обычно невозможно получить строковое значение 4.81, если оно хранится как Double, поэтому вам нужно использовать self.description (модифицированный алгоритм Grisu2), чтобы исправить уже потерянную точность - person vk.edward.li; 10.12.2018
comment
Я понимаю вашу точку зрения. Я просто не согласен с твоим решением. Поведение метода description округления не документировано и не гарантируется. Кроме того, он не локализован. ИМХО, неправильно использовать description для чего-либо, кроме ведения журнала. Я бы либо использовал Decimal, избегая использования Double полностью, либо просто использовал другой режим округления. Или, если необходимо, используйте свой собственный локализованный метод, который использует алгоритм в стиле Гризу (но это кажется ненужным, если вы знаете, сколько десятичных знаков вы хотите округлить). Но я бы не стал полагаться на это вспомогательное поведение description. - person Rob; 12.12.2018

Удобным способом может быть использование расширения типа Double.

extension Double {
    var roundTo2f: Double {return Double(round(100 *self)/100)  }
    var roundTo3f: Double {return Double(round(1000*self)/1000) }
}

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

let regularPie:  Double = 3.14159
var smallerPie:  Double = regularPie.roundTo3f  // results 3.142
var smallestPie: Double = regularPie.roundTo2f  // results 3.14
person Marco Leong    schedule 11.09.2015

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

let numberFormatter: NSNumberFormatter = {
    let nf = NSNumberFormatter()
    nf.numberStyle = .DecimalStyle
    nf.minimumFractionDigits = 0
    nf.maximumFractionDigits = 1
    return nf
}()

Предположим, ваша переменная, которую вы хотите напечатать,

var printVar = 3.567

Это гарантирует, что он будет возвращен в желаемом формате:

numberFormatter.StringFromNumber(printVar)

Таким образом, результат здесь будет «3,6» (округлено). Хотя это не самое экономичное решение, я даю его, потому что OP упоминал печать (в этом случае String не является нежелательным), и потому что этот класс позволяет устанавливать несколько параметров.

person Inkidu616    schedule 14.03.2016
comment
Небольшое замечание, что любой модуль форматирования является довольно дорогостоящим программно, что делает его нецелесообразным для задач, которые необходимо выполнять быстро или повторно. - person Jonathan Thornton; 07.08.2017

Или:

  1. Использование String(format:):

    • Приведите тип Double в String с %.3f спецификатором формата, а затем обратно в Double

      Double(String(format: "%.3f", 10.123546789))!
      
    • Или расширите Double для обработки N десятичных знаков:

      extension Double {
          func rounded(toDecimalPlaces n: Int) -> Double {
              return Double(String(format: "%.\(n)f", self))!
          }
      }
      
  2. По расчету

    • умножьте на 10 ^ 3, округлите и затем разделите на 10 ^ 3 ...

      (1000 * 10.123546789).rounded()/1000
      
    • Или расширите Double для обработки N десятичных знаков:

      extension Double {    
          func rounded(toDecimalPlaces n: Int) -> Double {
              let multiplier = pow(10, Double(n))
              return (multiplier * self).rounded()/multiplier
          }
      }
      
person staticVoidMan    schedule 20.08.2018

я хотел бы использовать

print(String(format: "%.3f", totalWorkTimeInHours))

и измените .3f на любое количество десятичных чисел, которое вам нужно

person Mohsen Hossein pour    schedule 27.10.2016
comment
Он хотел печатать с 3-мя цифрами, а не в NSTimeInterval - person Mohsen Hossein pour; 01.11.2016

Это более гибкий алгоритм округления до N значащих цифр.

Решение Swift 3

extension Double {
// Rounds the double to 'places' significant digits
  func roundTo(places:Int) -> Double {
    guard self != 0.0 else {
        return 0
    }
    let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
    return (self * divisor).rounded() / divisor
  }
}


// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200
person Nikita Ivaniushchenko    schedule 07.02.2017

Лучший способ отформатировать свойство типа double - использовать предопределенные методы Apple.

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule - это перечисление, которое имеет следующие возможности

Случаи перечисления:

case awayFromZero Округлить до ближайшего допустимого значения, величина которого больше или равна значению источника.

case down Округлить до ближайшего допустимого значения, которое меньше или равно исходному.

case toNearestOrAwayFromZero Округлить до ближайшего допустимого значения; если два значения одинаково близки, выбирается одно с большей величиной.

case toNearestOrEven Округлить до ближайшего допустимого значения; если два значения одинаково близки, выбирается четное.

case по направлению к нулю. Округление до ближайшего допустимого значения, величина которого меньше или равна значению источника.

case up Округлить до ближайшего допустимого значения, которое больше или равно исходному.

var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
person Abuzar Manzoor    schedule 05.06.2017

округлить двойное значение до десятичного числа x
NO. цифр после запятой

var x = 1.5657676754
var y = (x*10000).rounded()/10000
print(y)  // 1.5658 

var x = 1.5657676754 
var y = (x*100).rounded()/100
print(y)  // 1.57 

var x = 1.5657676754
var y = (x*10).rounded()/10
print(y)  // 1.6
person Ayman Badr    schedule 26.08.2017
comment
Что происходит в этом коде? Что демонстрируют три примера? - person rene; 26.08.2017
comment
Ответы только на код бесполезны, попробуйте объяснить, что делает каждый из этих примеров. - person Mo Abdul-Hameed; 26.08.2017

Не Свифт, но я уверен, что вы уловили идею.

pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
person yogi    schedule 07.12.2014

Кажется, это работает в Swift 5.

Очень удивлен, что для этого уже нет стандартной функции.

// Усечение двойного числа до n десятичных знаков с округлением

extension Double {

    func truncate(to places: Int) -> Double {
    return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
    }

}
person Matiu Awaiti    schedule 19.07.2019

Чтобы избежать дефектов Float, используйте Decimal

extension Float {
    func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
        var result: Decimal = 0
        var decimalSelf = NSNumber(value: self).decimalValue
        NSDecimalRound(&result, &decimalSelf, scale, rule)
        return (result as NSNumber).floatValue
    }
}

Пример
1075,58 округляет до 1075,57 при использовании Float со шкалой: 2 и .down
1075,58 округляет до 1075,58 при использовании Decimal со шкалой: 2 и .down

person Yervand Saribekyan    schedule 09.10.2019

Мне интересно, можно ли исправить ввод пользователя. Это если они вводят три десятичных знака вместо двух для суммы в долларах. Скажем, 1.111 вместо 1.11 можно исправить округлением? Ответ по многим причинам - нет! С деньгами, превышающими 0,001, в конечном итоге возникнут проблемы в реальной чековой книжке.

Вот функция для проверки ввода слишком большого количества значений после периода. Но что позволит 1., 1.1 и 1.11.

Предполагается, что значение уже было проверено на предмет успешного преобразования из String в Double.

//func need to be where transactionAmount.text is in scope

func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{


    var theTransactionCharacterMinusThree: Character = "A"
    var theTransactionCharacterMinusTwo: Character = "A"
    var theTransactionCharacterMinusOne: Character = "A"

    var result = false

    var periodCharacter:Character = "."


    var myCopyString = transactionAmount.text!

    if myCopyString.containsString(".") {

         if( myCopyString.characters.count >= 3){
                        theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)]
         }

        if( myCopyString.characters.count >= 2){
            theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)]
        }

        if( myCopyString.characters.count > 1){
            theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)]
        }


          if  theTransactionCharacterMinusThree  == periodCharacter {

                            result = true
          }


        if theTransactionCharacterMinusTwo == periodCharacter {

            result = true
        }



        if theTransactionCharacterMinusOne == periodCharacter {

            result = true
        }

    }else {

        //if there is no period and it is a valid double it is good          
        result = true

    }

    return result


}
person Mountain Man    schedule 25.01.2016

Вы можете добавить это расширение:

extension Double {
    var clean: String {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
    }
}

и назовите это так:

let ex: Double = 10.123546789
print(ex.clean) // 10.12
person TOUZENE Mohamed Wassim    schedule 02.04.2019
comment
Это изящная реализация представления его в виде строки. Интересно, возможно ли или рационально написать расширение представления числа цифр после периода, по-прежнему сохраняя его как Double. - person thinkswift; 16.07.2019

extension String{
  var roundedValue:String {
     return String(format: "%.3f", self)
}}

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

totalWorkTimeInHours.roundedValue
person Bhargav Sejpal    schedule 27.03.2019

Вот один для SwiftUI, если вам нужен текстовый элемент с числовым значением.

struct RoundedDigitText : View {
    let digits : Int
    let number : Double

    var body : some View {
        Text(String(format: "%.\(digits)f", number))
    }
}
person OwlOCR    schedule 20.09.2019

var n = 123.111222333
n = Double(Int(n * 10.0)) / 10.0

Результат: n = 123,1

Измените 10.0 (1 десятичный разряд) на любое из 100.0 (2 десятичных знака), 1000.0 (3 десятичных знака) и так далее для количества цифр после запятой.

person Amais Sheikh    schedule 03.11.2020

Если вы хотите, чтобы после запятой оставалось только 0 для раунда, посмотрите на этот пример ниже:

extension Double {
    func isInteger() -> Any {
        let check = floor(self) == self
        if check {
            return Int(self)
        } else {
            return self
        }
    }
}

let toInt: Double = 10.0
let stillDouble: Double = 9.12

print(toInt.isInteger) // 10
print(stillDouble.isInteger) // 9.12
person Jeri P.M    schedule 22.12.2020