Ozgur Vatansever
Ozgur Vatansever

Reputation: 52163

Round Half Down in Swift

Is there a rounding mode in Swift that behaves same as ROUND_HALF_DOWN in Java?

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. Behaves as for RoundingMode.UP if the discarded fraction is > 0.5; otherwise, behaves as for RoundingMode.DOWN.

Example:

For a negative number:

Upvotes: 2

Views: 1894

Answers (5)

Martin R
Martin R

Reputation: 539815

There is – as far as I can tell – no FloatingPointRoundingRule with the same behavior as Java's ROUND_HALF_DOWN, but you can get the result with a combination of rounded() and nextDown or nextUp:

func roundHalfDown(_ x: Double) -> Double {
    if x >= 0 {
        return x.nextDown.rounded()
    } else {
        return x.nextUp.rounded()
    }
}

Examples:

print(roundHalfDown(2.4)) // 2.0
print(roundHalfDown(2.5)) // 2.0
print(roundHalfDown(2.6)) // 3.0

print(roundHalfDown(-2.4)) // -2.0
print(roundHalfDown(-2.5)) // -2.0
print(roundHalfDown(-2.6)) // -3.0

Or as a generic extension method, so that it can be used with all floating point types (Float, Double, CGFloat):

extension FloatingPoint {
    func roundedHalfDown() -> Self {
        return self >= 0 ? nextDown.rounded() : nextUp.rounded()
    }
}

Examples:

print((2.4).roundedHalfDown()) // 2.0
print((2.5).roundedHalfDown()) // 2.0
print((2.6).roundedHalfDown()) // 3.0

print((-2.4).roundedHalfDown()) // -2.0
print((-2.5).roundedHalfDown()) // -2.0
print((-2.6).roundedHalfDown()) // -3.0

Upvotes: 5

Arash Etemad
Arash Etemad

Reputation: 1909

As @MohmmadS said those are built in methods for rounding.

You can implement custom rounding like this:

func round(_ value: Double, toNearest: Double) -> Double {
    return round(value / toNearest) * toNearest
}

func roundDown(_ value: Double, toNearest: Double) -> Double {
    return floor(value / toNearest) * toNearest
}

func roundUp(_ value: Double, toNearest: Double) -> Double {
    return ceil(value / toNearest) * toNearest
}

Example:

round(52.376, toNearest: 0.01) // 52.38
round(52.376, toNearest: 0.1)  // 52.4
round(52.376, toNearest: 0.25) // 52.5
round(52.376, toNearest: 0.5)  // 52.5
round(52.376, toNearest: 1)    // 52

Upvotes: 0

Deviyani Swami
Deviyani Swami

Reputation: 767

 var a = 6.54
        a.round(.toNearestOrAwayFromZero)
        // a == 7.0

        var b = 6.54
        b.round(.towardZero)
        // b == 6.0


        var c = 6.54
        c.round(.up)
        // c == 7.0


        var d = 6.54
        d.round(.down)
        // d == 6.0

You can do like this as well but need to take values after decimal as well.

Upvotes: 0

Mohmmad S
Mohmmad S

Reputation: 5088

Swift implements .round() function with rules, According to Apple

FloatingPointRoundingRule

case awayFromZero

Round to the closest allowed value whose magnitude is greater than or equal to that of the source.

case down

Round to the closest allowed value that is less than or equal to the source.

case toNearestOrAwayFromZero

Round to the closest allowed value; if two values are equally close, the one with greater magnitude is chosen.

case toNearestOrEven

Round to the closest allowed value; if two values are equally close, the even one is chosen.

case towardZero

Round to the closest allowed value whose magnitude is less than or equal to that of the source.

case up

Round to the closest allowed value that is greater than or equal to the source.

Upvotes: 1

Bhavin Kansagara
Bhavin Kansagara

Reputation: 2916

Yes, You can do the similar things using NSNumberFormatter and RoundingMode

Read them here

NSNumberFormatter

RoundingMode

Upvotes: 0

Related Questions