How to set floating-point rounding mode in Swift?

I want to write a function that performs a floating-point calculation with a specified rounding mode. For example, a call-site might look like this:

let x = Float.withRoundingMode(.roundDown) {
  // Some floating-point calculation
}

The implementation would be along the lines of:

extension Float {
    enum RoundingMode {
        case nearestTiesToEven, nearestTiesAwayFromZero, roundUp, roundDown, towardZero
    }
    
    static func withRoundingMode(_ roundingMode: RoundingMode, calculate: ()->Float) -> Float {
        // Store the current rounding mode
        // Set the rounding mode
        let result = calculate()
        // Restore the original rounding mode
        return result
    }
}

However, I don’t know how to access and modify the floating-point rounding mode in Swift. Is there a way to do this?

The floating-point environment is not accessible from Swift; floating-point operations implemented natively in Swift round to nearest.

LLVM only recently gained intrinsics that would permit operations with a specified rounding mode; down the road, I believe @scanon has plans to expose these in some way, but that is not the case today.

Okay, thanks for the info @xwu

You can change the rounding mode via the C fenv.h function fesetround( ), and it will probably mostly work, but there’s not yet a formal guarantee that Swift stdlib operations won’t change it back, nor that the compiler won’t evaluate your arithmetic at compile time using default rounding, or re-order it with respect to your rounding mode manipulations.

So, it’s likely possible to get a semi-useful result, but not in a stable or guaranteed fashion at the moment. This is something that I’d like to have a story for, but we first need a story at the LLVM IR level.

7 Likes

Any new word on this?

1 Like
Terms of Service

Privacy Policy

Cookie Policy