zig icon indicating copy to clipboard operation
zig copied to clipboard

Managing floating point rounding mode

Open daurnimator opened this issue 5 years ago • 3 comments

A discussion with @Rhodiumtoad brought up how FPU rounding modes are handled with zig.

e.g. what rounding mode state does zig expect the FPU to be in when an extern function is called? If zig doesn't specify or check this, then it means that comptime evaluations may not be correct (as they could be computed with the wrong rounding mode).

Do we need a @setFloatingPointRoundingMode? Could we have the rounding mode be .Unknown on entrance to a extern or export function, and ban most comptime floating point operations when in the unknown mode?

daurnimator avatar May 22 '19 02:05 daurnimator

Reading docs on LLVM Constrained Floating-Point Intrinsics I spotted:

By default, LLVM optimization passes assume that the rounding mode is round-to-nearest and that floating-point exceptions will not be monitored.

I haven't looked at what IR zig emits: does it use constrained FP intrinsics?

daurnimator avatar May 22 '19 02:05 daurnimator

What is the default behavior of zig currently? The language documentation has @setFloatMode() which by default is on 'Strict', but does this also imply a rounding mode? This is currently a breaking point for me to migrate a few (numeric-computing related) personal projects to zig, because any floating point operations done in zig are currently underspecified (or essentially undefined behavior) because the rounding behavior is not specified. I would also be willing to help contribute these features to the zig compiler, but for that a direction first needs to be decided by the core team.

rolfvdhulst avatar Oct 19 '23 08:10 rolfvdhulst

At least, with SSE2 for f32 and f64: Zig's default rounding mode seems to be Round to Nearest, halfway-ties round to even. Which is also the default IEEE-754-2008 rounding mode[1].

Zig provides @round which seems to be: Round to Nearest, halfway-tires away from zero.

So Zig seems to be missing @roundeven [2]. @nearbyint could be needed, if the rounding mode can change.

Also note: std.math.isNan seems to be missing cases that _mm_cmpunord_ps would catch. I don't know what compatibility concerns come into play there.

aqrit avatar Dec 14 '23 16:12 aqrit