Jak zaokrąglić sobowtóra do najbliższego Int w swift?

Próbuję stworzyć Kalkulator szybkości wzrostu (Double), który zaokrągli wynik do najbliższej liczby całkowitej i przeliczy stamtąd, jako taki:

let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0


while users < 14 {
    println("week \(week) has \(users) users")
    users += users * growth
    week += 1
}
Ale do tej pory nie byłem w stanie.

edytuj Ja tak to zrobilem:

var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0


while users <= 14 {
    println("week \(week) has \(users) users")
    firstUsers += firstUsers * growth
    users = Int(firstUsers)
    week += 1
}

Chociaż nie przeszkadza mi to, że zawsze jest zaokrąglanie w dół, nie podoba mi się to, ponieważ firstUsers musiał stać się zmienną i zmieniać się w całym programie( aby wykonać następne obliczenia), czego nie chcę, aby tak się stało.

Author: Suragch, 2014-10-14

7 answers

Istnieje round dostępna w Foundation biblioteka (w rzeczywistości jest w Darwin, ale Foundation importuje Darwin i przez większość czasu będziesz chciał używać Foundation zamiast bezpośrednio używać Darwin) .

import Foundation

users = round(users)

Uruchamianie kodu na placu zabaw, a następnie wywołanie:

print(round(users))

Wyjścia:

15.0

round() zawsze zaokrągla się w górę, gdy miejsce po przecinku wynosi >= .5 i w dół, gdy jest < .5 (standardowe zaokrąglenie). Można użyć floor(), aby wymusić zaokrąglenie w dół, a ceil() aby wymusić zaokrąglenie.

Jeśli trzeba zaokrąglić do określonego miejsca, to mnożymy przez pow(10.0, number of places), round, a następnie podzielić przez pow(10, number of places):

Runda do 2 miejsc po przecinku:

let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)

Wyjścia:

10.12

Uwaga: ze względu na sposób działania matematyki zmiennoprzecinkowej, rounded może nie zawsze być idealnie dokładna. Najlepiej myśleć o tym bardziej jako o przybliżeniu zaokrąglenia. Jeśli robisz to dla celów wyświetlania, lepiej użyj formatowania łańcuchów, aby sformatować liczbę, zamiast zaokrąglać ją za pomocą matematyki.

 181
Author: Mike S,
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-09-24 06:11:02

Aby zaokrąglić dublet do najbliższej liczby całkowitej, wystarczy użyć round().

var x = 3.7
x.round() // x = 4.0

Jeśli nie chcesz modyfikować oryginalnej wartości, użyj rounded():

let x = 3.7
let y = x.rounded() // y = 4.0. x = 3.7

Jak można się spodziewać ( lub nie ), liczba taka jak 3.5 jest zaokrąglana w górę, a liczba taka jak -3.5 jest zaokrąglana w dół. Jeśli potrzebujesz innego zachowania zaokrąglania niż to, możesz użyć jednej z reguł zaokrąglania . Na przykład:

var x = 3.7
x.round(.towardZero) // 3.0

Jeśli potrzebujesz prawdziwego {[8] } to po prostu rzuć go do jednego:

let myInt = Int(myDouble.rounded())

Uwagi

  • ta odpowiedź jest całkowicie przepisana. Moja stara odpowiedź dotyczyła funkcji matematycznych C takich jak round, lround, floor, i ceil. Jednak teraz, gdy Swift ma wbudowaną tę funkcjonalność, nie mogę już zalecać korzystania z tych funkcji. Dzięki @dfri za wskazanie mi tego. Sprawdź @dfri doskonałą odpowiedź tutaj . Zrobiłem też coś podobnego dla zaokrąglenia a CGFloat.
 112
Author: Suragch,
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-05-23 10:31:15

Swift 3 & 4 - wykorzystanie metody rounded(_:) jako wzorca protokołu FloatingPoint

The FloatingPoint protokół (do którego np. Double i Float odpowiada) rounded(_:) metoda

func rounded(_ rule: FloatingPointRoundingRule) -> Self

Gdzie FloatingPointRoundingRule jest enumem wyliczającym szereg różnych reguł zaokrąglania:

case awayFromZero

Zaokrąglenie do najbliższej dozwolonej wartości, której wielkość jest większa niż lub równym źródło.

case down

Zaokrąglenie do najbliższej dozwolonej wartości, która jest mniejsza lub równa źródło.

case toNearestOrAwayFromZero

Zaokrąglić do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierany jest ten o większej wielkości.

case toNearestOrEven

Zaokrąglić do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierany jest parzysty.

case towardZero

Zaokrąglenie do najbliższej dozwolonej wartości, której wielkość jest mniejsza lub równym źródłu.

case up

Zaokrąglenie do najbliższej dozwolonej wartości, która jest większa lub równa źródło.

Używamy podobnych przykładów do tych z @suragch ' s excellent answer aby pokazać te różne opcje zaokrąglania w praktyce.

.awayFromZero

Zaokrąglenie do najbliższej dozwolonej wartości, której wielkość jest większe lub równe źródłu; nie ma bezpośredniego odpowiednika między funkcjami C, jak to ma zastosowanie, warunkowo na znak self, ceil lub floor, odpowiednio dla wartości dodatnich i ujemnych self.

3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0

(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0

.down

Odpowiednik funkcji C floor.

3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0

(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0

.toNearestOrAwayFromZero

Odpowiednik funkcji C round.

3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0

(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0

Ta reguła zaokrąglania może być również dostępna za pomocą argumentu zerowego rounded() metoda .

3.000.rounded() // 3.0
// ...

(-3.000).rounded() // -3.0
// ...

.toNearestOrEven

Zaokrąglić do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest parzysta; odpowiednik funkcji C rint (/bardzo podobny do funkcji nearbyint).

3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0

4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 4.0

.towardZero

Odpowiednik funkcji C trunc.

3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0

(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0

Jeśli celem zaokrąglenia jest przygotowanie do pracy z liczbą całkowitą( np. użycie Int przez FloatPoint inicjalizacji po zaokrągleniu), możemy po prostu skorzystać z faktu, że podczas inicjalizacji an Int używając Double (lub Float itd), część dziesiętna zostanie skrócona.

Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3

Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3

.up

Odpowiednik funkcji C ceil.

3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0

(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0

Dodatek: przeglądanie kodu źródłowego dla FloatingPoint w celu sprawdzenia równoważności funkcji C z różnymi regułami FloatingPointRoundingRule

Jeśli chcemy, możemy spojrzeć na kod źródłowy protokołu FloatingPoint, aby bezpośrednio zobaczyć odpowiedniki funkcji C do publicznych reguł FloatingPointRoundingRule.

Od swift/stdlib/public/core / FloatingPoint.swift.gyb widzimy, że domyślna implementacja metody rounded(_:) czyni nas metodą mutacji round(_:):

public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
    var lhs = self
    lhs.round(rule)
    return lhs
}

From swift/stdlib/public/core/FloatingPointTypes.swift.gyb znajdujemy domyślną implementację round(_:), w której równoważność między regułamiFloatingPointRoundingRule a funkcjami zaokrąglania C jest pozorna:

public mutating func round(_ rule: FloatingPointRoundingRule) {
    switch rule {
    case .toNearestOrAwayFromZero:
        _value = Builtin.int_round_FPIEEE${bits}(_value)
    case .toNearestOrEven:
        _value = Builtin.int_rint_FPIEEE${bits}(_value)
    case .towardZero:
        _value = Builtin.int_trunc_FPIEEE${bits}(_value)
    case .awayFromZero:
        if sign == .minus {
            _value = Builtin.int_floor_FPIEEE${bits}(_value)
        }
        else {
            _value = Builtin.int_ceil_FPIEEE${bits}(_value)
        }
    case .up:
        _value = Builtin.int_ceil_FPIEEE${bits}(_value)
    case .down:
        _value = Builtin.int_floor_FPIEEE${bits}(_value)
    }
}
 54
Author: dfri,
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-16 11:53:13

Swift 3: 5.678434 - > 5.68 można po prostu połączyć funkcję round() lub roundf () z mnożeniem:

    let value:Float = 5.678434
    let roundedValue = roundf(value * 100) / 100
    print(roundedValue) //5.68
 4
Author: Thoms,
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-09-21 00:43:29

Swift 3

Var myNum = 8.09

MyNum.rounded () / / wynik = 8, który jest przechowywany w myNum

 1
Author: Dattatray Deokar,
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-29 15:43:43

Możesz również rozszerzyć FloatingPoint w Swift 3 w następujący sposób:

extension FloatingPoint {
    func rounded(to n: Int) -> Self {
        return (self / Self(n)).rounded() * Self(n)

    }
}

324.0.rounded(to: 5)   // 325
 1
Author: Leo Dabus,
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-01-14 02:34:31
**In Swift**

var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789

a.rounded(.up)                      //15
b.rounded(.down)                    //14
c.rounded(.awayFromZero)            //15
d.rounded(.towardZero)              //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven)         //14
 1
Author: Sai kumar Reddy,
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-09-26 05:15:20