Swift 3 i 4 - wykorzystując rounded(_:)metodę zgodnie ze schematem w FloatingPointprotokole
FloatingPointProtokół (w którym np Doublei FloatPrzylega) plany na rounded(_:)metodę
func rounded(_ rule: FloatingPointRoundingRule) -> Self
Gdzie FloatingPointRoundingRulejest wyliczenie wyliczające kilka różnych reguł zaokrąglania:
case awayFromZero
Zaokrąglij do najbliższej dozwolonej wartości, której wielkość jest większa lub równa wartoś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
Zaokrąglij do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest ta o większej wartości.
case toNearestOrEven
Zaokrąglij do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo zbliżone, wybierana jest ta parzysta.
case towardZero
Zaokrąglij do najbliższej dozwolonej wartości, której wielkość jest mniejsza lub równa wartoś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.
Korzystamy z przykładów podobnych do tych z doskonałej odpowiedzi @ Suragcha, aby pokazać te różne opcje zaokrąglania w praktyce.
.awayFromZero
Zaokrąglić do najbliższej dozwolonej wartości, której wielkość jest większa lub równa wartości źródła; Brak bezpośredniego odpowiednik wśród funkcji C, jak ta wykorzystuje, warunkowo na znak self, ceillub floor, dla dodatnich i ujemnych wartości self, odpowiednio.
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 floorfunkcji C.
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 roundfunkcji C.
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
Dostęp do tej reguły zaokrąglania można również uzyskać przy użyciu rounded()metody z zerowym argumentem .
3.000.rounded() // 3.0
// ...
(-3.000).rounded() // -3.0
// ...
.toNearestOrEven
Zaokrąglij do najbliższej dozwolonej wartości; jeśli dwie wartości są jednakowo bliskie, wybierana jest parzysta; odpowiednik funkcji C rint(/ bardzo podobny do 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) // 5.0 (up to nearest)
.towardZero
Odpowiednik truncfunkcji C.
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ąglania jest przygotowanie do pracy z liczbą całkowitą (np. Użycie Intprzez FloatPointinicjalizację po zaokrągleniu), możemy po prostu skorzystać z faktu, że podczas inicjalizacji za Intpomocą a Double(lub Floatitp.) Część dziesiętna zostanie obcięta.
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 ceilfunkcji C.
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: odwiedzenie kodu źródłowego w FloatingPointcelu sprawdzenia równoważności funkcji C z różnymi FloatingPointRoundingRuleregułami
Jeśli chcemy, możemy spojrzeć na kod źródłowy FloatingPointprotokołu, aby bezpośrednio zobaczyć odpowiedniki funkcji C dla FloatingPointRoundingRulereguł publicznych .
Ze swift / stdlib / public / core / FloatingPoint.swift.gyb widzimy, że domyślna implementacja rounded(_:)metody czyni nas round(_:)metodą mutującą :
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
Ze swift / stdlib / public / core / FloatingPointTypes.swift.gyb znajdujemy domyślną implementację round(_:), w której FloatingPointRoundingRulewidoczna jest równoważność między regułami a funkcjami zaokrąglającymi w C.
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)
}
}
pow()niestety nie jest dostępny na placu zabaw