Zaokrąglanie podwójnej wartości do x liczby miejsc po przecinku w języku swift
Czy ktoś może mi powiedzieć, jak zaokrąglić podwójną wartość do X liczby miejsc po przecinku w Swift?
Mam:
var totalWorkTimeInHours = (totalWorkTime/60/60)
Z totalWorkTime
jako NSTimeInterval (double) w sekundzie.
totalWorkTimeInHours
da mi godziny, ale daje mi ilość czasu w tak długiej dokładnej liczbie np. 1.543240952039......
Jak zaokrąglić to do, powiedzmy, 1.543 przy drukowaniu totalWorkTimeInHours
?
21 answers
Możesz użyć funkcji Swift round
, aby to osiągnąć.
Aby zaokrąglić a Double
z dokładnością do 3 cyfr, najpierw pomnóż ją przez 1000, zaokrągl i podziel wynik zaokrąglenia przez 1000:
let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y) // 1.236
INNE niż jakiekolwiek rozwiązania printf(...)
lub String(format: ...)
, wynik tej operacji jest nadal typu Double
.
EDIT:
Jeśli chodzi o komentarze, że czasami nie działa, przeczytaj to:
O Czym Powinien Wiedzieć Każdy Informatyk Arytmetyka Zmiennoprzecinkowa
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 18:34:26
Rozszerzenie dla Swift 2
[7]} bardziej ogólnym rozwiązaniem jest następujące rozszerzenie, które działa z Swift 2 i 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
}
}
Rozszerzenie dla Swift 3
W języku Swift 3 round
zastępuje się przez 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
}
}
Przykład zwracający Podwójne zaokrąglenie do 4 miejsc po przecinku:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 05:18:43
Użyj konstruktora String
, który przyjmuje format
string:
print(String(format: "%.3f", totalWorkTimeInHours))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-01 16:43:30
Z Swift 4, w zależności od potrzeb, możesz wybrać jeden z 9 następujących stylów , aby uzyskać zaokrąglony wynik z Double
.
#1. Za pomocą FloatingPoint
rounded()
metoda
W najprostszym przypadku możesz użyć Double
round()
metoda.
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. Za pomocą FloatingPoint
rounded(_:)
metoda
var roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
var roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#3. Korzystanie z funkcji Darwina round
Fundacja oferuje round
funkcję poprzez Darwin.
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. Wykorzystanie niestandardowej metody rozszerzenia Double
zbudowanej z funkcji Darwin round
i pow
Jeśli chcesz powtórzyć poprzednią operację wiele razy, refaktoryzacja kodu może być dobrym pomysłem.
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. Za pomocą NSDecimalNumber
rounding(accordingToBehavior:)
metoda
W razie potrzeby, NSDecimalNumber
oferuje obszerne, ale potężne rozwiązanie do zaokrąglania liczb dziesiętnych.
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. Za pomocą NSDecimalRound(_:_:_:_:)
function
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. Za pomocą NSString
init(format:arguments:)
initializer
Jeśli chcesz zwrócić NSString
z operacji zaokrąglania, użycie inicjalizatora NSString
jest prostym, ale wydajnym rozwiązaniem.
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. Za pomocą String
init(format:_:)
initializer
Typ Swift String
jest łączony z klasą Foundation NSString
(możesz dowiedzieć się więcej o tym czytając język programowania Swift ). Dlatego możesz użyć poniższego kodu w aby zwrócić String
z operacji zaokrąglania:
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. Za pomocą NumberFormatter
Jeśli spodziewasz się uzyskać String?
z operacji zaokrąglania, NumberFormatter
oferuje wysoce konfigurowalne rozwiązanie.
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")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 01:07:08
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 10:32:40
Na podstawie odpowiedzi Yogi ' ego, oto funkcja Swift, która wykonuje zadanie:
func roundToPlaces(value:Double, places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(value * divisor) / divisor
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 11:22:19
Jest to w pełni działający kod
Swift 3.0 / 4.0, Xcode 9.0 GM / 9.2
let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)
Wyjście-123
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)
Wyjście-123.3
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)
Wyjście-123.33
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)
Wyjście-123.326
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 10:45:20
W Swift 3.0 i Xcode 8.0:
extension Double {
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
Użyj tego rozszerzenia w ten sposób,
let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 05:00:06
Kod dla konkretnych cyfr po dziesiętnych to:
var a = 1.543240952039
var roundedString = String(format: "%.3f", a)
Tutaj %.3f nakazuje swift, aby liczba ta została zaokrąglona do 3 miejsc po przecinku.a jeśli chcesz podwójną liczbę, możesz użyć tego kodu:
// String to Double
var roundedString = Double(String(format: "%.3f", b))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 06:30:24
Poręcznym sposobem może być użycie rozszerzenia typu Double
extension Double {
var roundTo2f: Double {return Double(round(100 *self)/100) }
var roundTo3f: Double {return Double(round(1000*self)/1000) }
}
Użycie:
let regularPie: Double = 3.14159
var smallerPie: Double = regularPie.roundTo3f // results 3.142
var smallestPie: Double = regularPie.roundTo2f // results 3.14
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-11 12:56:43
Użyj wbudowanej biblioteki Darwina
SWIFT 3
extension Double {
func round(to places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
Użycie:
let number:Double = 12.987654321
print(number.round(to: 3))
Wyjścia: 12.988
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-30 23:41:21
Jest to rodzaj długiego obejścia, które może się przydać, jeśli twoje potrzeby są trochę bardziej złożone. Możesz użyć programu do formatowania liczb w języku Swift.
let numberFormatter: NSNumberFormatter = {
let nf = NSNumberFormatter()
nf.numberStyle = .DecimalStyle
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
Załóżmy, że zmienna, którą chcesz wydrukować to
var printVar = 3.567
To upewni się, że zostanie zwrócony w żądanym formacie:
numberFormatter.StringFromNumber(printVar)
Wynik będzie więc "3.6" (zaokrąglony). O ile nie jest to najbardziej ekonomiczne rozwiązanie, to podaję je, ponieważ wspomniany druk OP (w takim przypadku ciąg nie jest niepożądany), a ponieważ klasa ta pozwala na ustawienie wielu parametrów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-14 22:08:59
Użyłbym
print(String(format: "%.3f", totalWorkTimeInHours))
I zmienić .3f do dowolnej liczby cyfr dziesiętnych, które potrzebujesz
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 12:24:59
Nie szybko, ale jestem pewien, że masz pomysł.
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 00:12:22
Jest to bardziej elastyczny algorytm zaokrąglania do N cyfr znaczących
Swift 3 solution
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-07 19:44:13
Zaokrąglenie podwójnej wartości do X liczby dziesiętnej
Nie. cyfry po przecinku
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 11:53:24
Najlepszym sposobem sformatowania podwójnej właściwości jest użycie predefiniowanych metod Apple.
mutating func round(_ rule: FloatingPointRoundingRule)
FloatingPointRoundingRule jest enum, które ma następujące możliwości
Przypadki Wyliczenia:
Case awayFromZero Zaokrąglić do najbliższej dozwolonej wartości, której wielkość jest większa lub równa wielkości źródła.
Case down Zaokrąglenie do najbliższej dozwolonej wartości, która jest mniejsza lub równa źródłu.
Case toNearestOrAwayFromZero Zaokrąglenie do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest ta o większej wielkości.
Case toNearestOrEven Zaokrąglenie do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest parzysta.
Case towardZero Zaokrąglić do najbliższej dozwolonej wartości, której wielkość jest mniejsza lub równa wielkości źródła.
Case up Zaokrąglenie do najbliższej dozwolonej wartości, która jest większa niż lub równa się źródłu.
var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 14:22:55
Albo:
-
Używając
String(format:)
:-
Wpisz
Double
doString
ze specyfikatorem formatu%.3f
, a następnie z powrotem doDouble
Double(String(format: "%.3f", 10.123546789))!
-
Lub rozszerzyć
Double
, aby obsłużyć N-miejsca dziesiętne:extension Double { func rounded(toDecimalPlaces n: Int) -> Double { return Double(String(format: "%.\(n)f", self))! } }
-
-
Przez obliczenie
-
Pomnóż przez 10^3, zaokrągl i podziel przez 10^3...
(1000 * 10.123546789).rounded()/1000
-
Lub rozszerzyć
Double
, aby obsłużyć N-dziesiętne miejsca:extension Double { func rounded(toDecimalPlaces n: Int) -> Double { let multiplier = pow(10, Double(n)) return (multiplier * self).rounded()/multiplier } }
-
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-20 09:39:01
Jeśli chcesz zaokrąglać Double
wartości, możesz użyć Swift Decimal
, aby nie wprowadzać żadnych błędów, które mogą pojawić się podczas prób obliczenia z tymi zaokrąglonymi wartościami. Jeśli użyjesz Decimal
, może ona dokładnie reprezentować wartości dziesiętne tej zaokrąglonej wartości zmiennoprzecinkowej.
Więc możesz zrobić:
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
}
}
Następnie można uzyskać zaokrągloną wartość Decimal
w następujący sposób:
let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30
I jeśli chcesz wyświetlić go z określoną liczbą miejsc po przecinku (a także zlokalizować łańcuch dla aktualne ustawienia regionalne użytkownika), możesz użyć NumberFormatter
:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-05 07:36:38
Znalazłem to zastanawiając się, czy jest możliwe, aby poprawić dane wejściowe użytkownika. To jest, jeśli wprowadzą trzy po przecinku zamiast dwóch dla kwoty dolara. Powiedzmy 1.111 zamiast 1.11 Czy można to naprawić przez zaokrąglenie? Odpowiedź z wielu powodów brzmi: nie! Z pieniędzy coś ponad tj. 0.001 W końcu spowodować problemy w prawdziwej książeczce czekowej.
Tutaj znajduje się funkcja sprawdzająca wprowadzanie przez użytkowników zbyt wielu wartości po okresie. Ale co pozwoli 1., 1.1 i 1.11.
Zakłada się, że wartość została już sprawdzona pod kątem pomyślnej konwersji z ciągu znaków na podwojenie.
//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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-06 01:03:59
//find the distance between two points
let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 )
let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599)
let distanceInMeters = coordinateSource.distance(from: coordinateDestination)
let valueInKms = distanceInMeters/1000
let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000)
self.lblTotalDistance.text = "Distance is : \(preciseValueUptoThreeDigit) kms"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-28 09:45:52