Swift 3 i 4 - wykorzystując rounded(_:)
metodę zgodnie ze schematem w FloatingPoint
protokole
FloatingPoint
Protokół (w którym np Double
i Float
Przylega) plany na rounded(_:)
metodę
func rounded(_ rule: FloatingPointRoundingRule) -> Self
Gdzie FloatingPointRoundingRule
jest 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
, ceil
lub 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 floor
funkcji 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 round
funkcji 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 trunc
funkcji 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 Int
przez FloatPoint
inicjalizację po zaokrągleniu), możemy po prostu skorzystać z faktu, że podczas inicjalizacji za Int
pomocą a Double
(lub Float
itp.) 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 ceil
funkcji 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 FloatingPoint
celu sprawdzenia równoważności funkcji C z różnymi FloatingPointRoundingRule
regułami
Jeśli chcemy, możemy spojrzeć na kod źródłowy FloatingPoint
protokołu, aby bezpośrednio zobaczyć odpowiedniki funkcji C dla FloatingPointRoundingRule
reguł 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 FloatingPointRoundingRule
widoczna 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