Excerpt from struct FloatingPointControl: /** IEEE hardware exceptions. * By default, all exceptions are masked (disabled). */ enum : uint { inexactException = 0x20, underflowException = 0x10, overflowException = 0x08, divByZeroException = 0x04, invalidException = 0x01, /// Severe = The overflow, division by zero, and invalid exceptions. severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException | inexactException, }; A little further up the file in struct IeeeFlags: // The x87 FPU status register is 16 bits. // The Pentium SSE2 status register is 32 bits. uint flags; version (X86_Any) { // Applies to both x87 status word (16 bits) and SSE2 status word(32 bits). enum : int { INEXACT_MASK = 0x20, UNDERFLOW_MASK = 0x10, OVERFLOW_MASK = 0x08, DIVBYZERO_MASK = 0x04, INVALID_MASK = 0x01 } // Don't bother about denormals, they are not supported on most CPUs. // DENORMAL_MASK = 0x02; } else version (PPC) { Both implement the same thing, but have (rather confusingly) different names and one only implements for X86 whereas the other (at least tries) to implement PPC and SPARC too. IMO, as both structs take their values from <fpu_control.h> for GlibC (<machine/ieeeflags.h> for FreeBSD?? <float.h> for Windows???), these enums (and possibly the Get/Set/Clear CW functions too) should be consolidated into one place elsewhere. For example, std.internal.math.fpbits, or possibly DRuntime... Regards
Hmm... also found in <fenv.h>, so perhaps should just be importing core.stdc.fenv (merging any bits added by std.math).
Is this still an issue? I'd have a look at the source, but I'm afraid that I wouldn't be able to tell what's X86 or SPARC, etc.
(In reply to Infiltrator from comment #2) > Is this still an issue? I'd have a look at the source, but I'm afraid that > I wouldn't be able to tell what's X86 or SPARC, etc. Well, X86 code is guarded by a version(X86) block, SPARC code by a version(SPARC) block. :-)
Both struct FloatingPointControl and Ieeeflags still have their own private enums. Since these values should be mirrored somewhere in druntime stdc (it looks like the me of five years ago couldn't work out where when searching through the libc headers), then yes this is still a valid refactoring.
It seems to me that setting rounding mode and testing for inexact does not work correctly on x86_64. Correct code using the C bindings: void main() { import core.stdc.fenv; fesetround(FE_UPWARD); float x = 1.0f; x += float.min_normal; writefln("%.32g, inexact: %s", x, fetestexcept(FE_INEXACT) > 0); } > Output: 1.00000011920928955078125, inexact: true The same code using FloatingPointControl and IeeeFlags does not work at all (neither set round nor test except) void main() { resetIeeeFlags(); FloatingPointControl fpctrl; fpctrl.rounding = FloatingPointControl.roundUp; float x = 1.0f; x += float.min_normal; writefln("%.32g, inexact: %s", x, ieeeFlags.inexact); } > Output: 1, inexact: false Linked discussion: http://forum.dlang.org/post/qybweycrifqgtcssepgx@forum.dlang.org
Has been improved somewhat by: https://github.com/dlang/phobos/pull/4272 https://github.com/dlang/phobos/pull/5769
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9582 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB