Czy ktoś może mi powiedzieć, jak zaokrąglić podwójną wartość do x liczby miejsc dziesiętnych w Swift?
Mam:
var totalWorkTimeInHours = (totalWorkTime/60/60)
Z totalWorkTime
bycia NSTimeInterval (dwukrotnie) na drugim.
totalWorkTimeInHours
da mi godziny, ale da mi tyle czasu w tak długiej, precyzyjnej liczbie, np. 1,543240952039 ......
Jak zaokrąglić to w dół, powiedzmy, 1,543 podczas drukowania totalWorkTimeInHours
?
ios
swift
double
nstimeinterval
Leighton
źródło
źródło
round(_:)
,Double
round()
,NSString
inicjator,String
inicjująca,NumberFormatter
, podwójne rozszerzenie lub nawetNSDecimalNumber
iDecimal
.Odpowiedzi:
round
Aby tego dokonać, możesz użyć funkcji Swift .Aby zaokrąglić a
Double
z dokładnością 3 cyfr, najpierw pomnóż ją przez 1000, zaokrągl ją i podziel zaokrąglony wynik przez 1000:Inne niż jakiekolwiek rozwiązania
printf(...)
lubString(format: ...)
rozwiązania, wynik tej operacji jest nadal tego samego typuDouble
.EDYCJA:
Jeśli chodzi o komentarze, że czasami nie działa, przeczytaj to:
Co każdy programista powinien wiedzieć o arytmetyki zmiennoprzecinkowej
źródło
let rate = 9.94999999999; Double(round(rate * 100) / 100);
Wyjście:9.94999999999, 9.949999999999999
działa tylko w przypadku wydruku, ale jak mogę przypisać go do zmiennej?Rozszerzenie do Swift 2
Bardziej ogólnym rozwiązaniem jest następujące rozszerzenie, które działa z Swift 2 i iOS 9:
Rozszerzenie do Swift 3
W Swift 3
round
otrzymuje brzmienierounded
:Przykład, który zwraca Podwójne zaokrąglone do 4 miejsc po przecinku:
źródło
round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)
Zwraca8.460000000000001
. Robienie tego samego z Float, przynajmniej w tym scenariuszu , w rzeczywistości wydaje się działać:round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)
plony8.46
. Po prostu coś wartego odnotowania.No '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
Aby zaokrąglić
totalWorkTimeInHours
do 3 cyfr w celu wydrukowania, użyjString
konstruktora, który pobieraformat
ciąg znaków:źródło
String(format: "%.3f", 1.23489)
drukuje1.235
Z Swift 5, w zależności od potrzeb, możesz wybrać jeden z 9 następujących stylów , aby uzyskać zaokrąglony wynik od
Double
.# 1. Przy użyciu
FloatingPoint
rounded()
metodyW najprostszym przypadku możesz użyć tej
Double
rounded()
metody.# 2. Przy użyciu
FloatingPoint
rounded(_:)
metody# 3. Korzystanie z
round
funkcji DarwinFundacja oferuje
round
funkcję za pośrednictwem Darwina.# 4. Korzystanie z
Double
niestandardowej metody rozszerzenia zbudowanej za pomocą Darwinaround
ipow
funkcjiJeśli chcesz powtórzyć poprzednią operację wiele razy, dobrym pomysłem może być refaktoryzacja kodu.
# 5. Przy użyciu
NSDecimalNumber
rounding(accordingToBehavior:)
metodyW razie potrzeby
NSDecimalNumber
oferuje pełne, ale potężne rozwiązanie do zaokrąglania liczb dziesiętnych.# 6. Korzystanie z
NSDecimalRound(_:_:_:_:)
funkcji# 7. Korzystanie z
NSString
init(format:arguments:)
inicjalizatoraJeśli chcesz zwrócić wynik
NSString
z operacji zaokrąglania, użycieNSString
inicjatora jest prostym, ale wydajnym rozwiązaniem.# 8. Korzystanie z
String
init(format:_:)
inicjalizatoraString
Typ Swift jest połączony zNSString
klasą Foundation . Dlatego możesz użyć następującego kodu, aby zwrócić wynikString
operacji zaokrąglania:# 9. Za pomocą
NumberFormatter
Jeśli spodziewasz się, że skorzystasz
String?
z operacji zaokrąglania,NumberFormatter
oferuje wysoce konfigurowalne rozwiązanie.źródło
Decimal
, który jest bezpłatny do mostuNSDecimalNumber
.Decimal
Pochodzi rodzaj i oferty Swift bardziej elegancki wsparcie dla rodzimych operatorów, takich jak+
,-
itpNSDecimalRound(_:_:_:_:)
funkcją. Dzięki.NumberFormatter
to ostatnia opcja, podczas gdy powinna być pierwsza do prezentowania liczb użytkownikom. Żadna inna metoda nie generuje poprawnie zlokalizowanych liczb.W Swift 2.0 i Xcode 7.2:
Przykład:
źródło
To jest w pełni działający kod
Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 i nowsze
wyjście - 123
wyjście - 123,3
wyjście - 123,33
wyjście - 123.326
źródło
Opierając się na odpowiedzi Jogina, oto funkcja Swift, która wykonuje to zadanie:
źródło
W Swift 3.0 i Xcode 8.0:
Użyj tego rozszerzenia tak:
źródło
Swift 4, Xcode 10
źródło
Kod dla określonych cyfr po przecinku to:
Tutaj% .3f mówi szybkiemu, aby ta liczba została zaokrąglona do 3 miejsc po przecinku. A jeśli chcesz podwójną liczbę, możesz użyć tego kodu:
var roundedString = Double(String(format: "%.3f", b))
źródło
Skorzystaj z wbudowanej biblioteki Foundation Darwin
SWIFT 3
Stosowanie:
Wyjścia: 12,988
źródło
Przydatnym sposobem może być użycie rozszerzenia typu Double
Stosowanie:
źródło
Jeśli chcesz zaokrąglić
Double
wartości, możesz użyć Swift,Decimal
aby nie wprowadzać żadnych błędów, które mogą pojawić się podczas próby obliczenia matematycznego za pomocą tych zaokrąglonych wartości. Jeśli używaszDecimal
, może dokładnie reprezentować wartości dziesiętne tej zaokrąglonej wartości zmiennoprzecinkowej.Możesz więc zrobić:
Następnie możesz uzyskać zaokrągloną
Decimal
wartość w następujący sposób:A jeśli chcesz wyświetlić go z określoną liczbą miejsc dziesiętnych (a także zlokalizować ciąg dla bieżących ustawień narodowych użytkownika), możesz użyć
NumberFormatter
:źródło
(4.81).roundedDecimal(to: 2, mode: .down)
zwróci 4,8 zamiast 4,81, użyjDecimal(string: self.description)!
do dokładnegodecimalValue
Double
(staje się4.8099999999999996
). Ale odradzam używaniedescription
(ponieważ zaokrąglanie, które stosuje, nie jest udokumentowane i może ulec zmianie). Jeśli naprawdę chcesz robić matematykę z dokładnością dziesiętną, powinieneś unikaćDouble
całkowicie i zamiast tego powinieneś używaćDecimal
bezpośrednio (np .Decimal(sign: .plus, exponent: -2, significand: 481)
LubDecimal(string: "4.81")
. Ale nie używajdescription
.description
metody nie jest ani udokumentowane, ani gwarantowane. Ponadto nie jest zlokalizowany. IMHO, błędem jest używaniedescription
do celów innych niż logowanie. Albo używałbymDecimal
całego, unikając używaniaDouble
całkowicie, albo po prostu używałbym innego trybu zaokrąglania. Lub, jeśli musisz, użyj własnej zlokalizowanej metody wykorzystującej algorytm w stylu Grisu (ale wydaje się to niepotrzebne, gdy wiesz, ile miejsc po przecinku chcesz zaokrąglić). Ale unikałbym polegania na tym pomocniczym zachowaniudescription
.Jest to rodzaj długiego obejścia, które może się przydać, jeśli Twoje potrzeby są nieco bardziej złożone. Możesz użyć formatera liczb w Swift.
Załóżmy, że twoja zmienna, którą chcesz wydrukować, to
Zapewni to, że zostanie zwrócony w żądanym formacie:
Wynik będzie więc wynosić „3,6” (w zaokrągleniu). Chociaż nie jest to najbardziej ekonomiczne rozwiązanie, daję to, ponieważ OP wspomniało o drukowaniu (w którym to przypadku String nie jest niepożądany) i ponieważ ta klasa pozwala na ustawienie wielu parametrów.
źródło
użyłbym
i zmień .3f na dowolną liczbę potrzebnych liczb dziesiętnych
źródło
Zarówno:
Używanie
String(format:)
:Typecast
Double
doString
ze%.3f
specyfikatorem formatu, a następnie z powrotem doDouble
Lub rozszerz,
Double
aby obsłużyć miejsca N-dziesiętne:Według obliczeń
pomnożyć przez 10 ^ 3, zaokrąglić, a następnie podzielić przez 10 ^ 3 ...
Lub rozszerz,
Double
aby obsłużyć miejsca N-dziesiętne:źródło
Jest to bardziej elastyczny algorytm zaokrąglania do N cyfr znaczących
Rozwiązanie Swift 3
źródło
Najlepszym sposobem sformatowania podwójnej właściwości jest użycie predefiniowanych metod Apple.
FloatingPointRoundingRule to wyliczenie, które ma następujące możliwości
Przypadki wyliczenia:
case awayFromZero Zaokrąglij do najbliższej dozwolonej wartości, której wielkość jest większa lub równa wielkości źródła.
case down Zaokrąglij do najbliższej dozwolonej wartości, która jest mniejsza lub równa źródłu.
case toNearestOrAwayFromZero Round 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ąglij do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest parzysta.
w kierunku Zero Round do najbliższej dozwolonej wartości, której wielkość jest mniejsza lub równa wielkości źródła.
case up Zaokrąglij do najbliższej dozwolonej wartości, która jest większa lub równa źródłu.
źródło
zaokrąglić podwójną wartość do x liczby dziesiętnej
NO. cyfr po przecinku
źródło
Nie szybkie, ale jestem pewien, że masz pomysł.
źródło
Wydaje się, że działa to w Swift 5.
Zaskoczony, że nie ma już w tym celu standardowej funkcji.
// Obcięcie miejsc podwójnych do n-dziesiętnych z zaokrągleniem
źródło
Możesz dodać to rozszerzenie:
i nazwij to tak:
źródło
Aby uniknąć niedoskonałości pływaka, użyj opcji Dziesiętny
dawny.
1075,58 zaokrągla do 1075,57 przy użyciu pływaka ze skalą: 2 i. Down
1075.58 zaokrągla do 1075,58 przy użyciu dziesiętnego ze skalą: 2 i. Down
źródło
Zastanawiam się, czy można poprawić dane wejściowe użytkownika. To znaczy, jeśli wprowadzą trzy miejsca po przecinku zamiast dwóch dla kwoty w dolarach. Powiedz 1.111 zamiast 1.11 czy możesz to naprawić zaokrąglając? Odpowiedź z wielu powodów brzmi „nie”! Przy pieniądzach przekraczających np. 0,001 ostatecznie spowoduje problemy w prawdziwym książeczce czekowej.
Oto funkcja służąca do sprawdzania, czy użytkownicy wprowadzają zbyt wiele wartości po okresie. Ale które pozwolą 1., 1.1 i 1.11.
Zakłada się, że wartość została już sprawdzona pod kątem pomyślnej konwersji z ciągu na podwójne.
źródło
źródło
Stosowanie :
źródło
Oto jeden dla SwiftUI, jeśli potrzebujesz elementu Text o wartości liczbowej.
źródło