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.
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.