mirror of
https://github.com/dlang/phobos.git
synced 2025-05-05 17:42:58 +03:00
Merge pull request #1208 from denis-sh/std.math.FloatingPointControl-fixes
`std.math.FloatingPointControl` fixes
This commit is contained in:
commit
73aa70f716
1 changed files with 50 additions and 19 deletions
53
std/math.d
53
std/math.d
|
@ -2780,20 +2780,33 @@ void resetIeeeFlags() { IeeeFlags.resetIeeeFlags(); }
|
|||
Example:
|
||||
----
|
||||
{
|
||||
FloatingPointControl fpctrl;
|
||||
|
||||
// Enable hardware exceptions for division by zero, overflow to infinity,
|
||||
// invalid operations, and uninitialized floating-point variables.
|
||||
|
||||
FloatingPointControl fpctrl;
|
||||
fpctrl.enableExceptions(FloatingPointControl.severeExceptions);
|
||||
|
||||
double y = x*3.0; // will generate a hardware exception, if x is uninitialized.
|
||||
//
|
||||
fpctrl.rounding = FloatingPointControl.roundUp;
|
||||
// This will generate a hardware exception, if x is a
|
||||
// default-initialized floating point variable:
|
||||
real x; // Add `= 0` or even `= real.nan` to not throw the exception.
|
||||
real y = x * 3.0;
|
||||
|
||||
// The hardware exceptions will be disabled when leaving this scope.
|
||||
// The exception is only thrown for default-uninitialized NaN-s.
|
||||
// NaN-s with other payload are valid:
|
||||
real z = y * real.nan; // ok
|
||||
|
||||
// Changing the rounding mode:
|
||||
fpctrl.rounding = FloatingPointControl.roundUp;
|
||||
assert(rint(1.1) == 2);
|
||||
|
||||
// The set hardware exceptions will be disabled when leaving this scope.
|
||||
// The original rounding mode will also be restored.
|
||||
}
|
||||
|
||||
// Ensure previous values are returned:
|
||||
assert(!FloatingPointControl.enabledExceptions);
|
||||
assert(FloatingPointControl.rounding == FloatingPointControl.roundToNearest);
|
||||
assert(rint(1.1) == 1);
|
||||
----
|
||||
|
||||
*/
|
||||
|
@ -2852,8 +2865,8 @@ public:
|
|||
//// Change the floating-point hardware rounding mode
|
||||
@property void rounding(RoundingMode newMode)
|
||||
{
|
||||
ushort old = getControlState();
|
||||
setControlState((old & ~ROUNDING_MASK) | (newMode & ROUNDING_MASK));
|
||||
initialize();
|
||||
setControlState((getControlState() & ~ROUNDING_MASK) | (newMode & ROUNDING_MASK));
|
||||
}
|
||||
|
||||
/// Return the exceptions which are currently enabled (unmasked)
|
||||
|
@ -2872,6 +2885,7 @@ public:
|
|||
~this()
|
||||
{
|
||||
clearExceptions();
|
||||
if (initialized)
|
||||
setControlState(savedState);
|
||||
}
|
||||
|
||||
|
@ -2963,6 +2977,25 @@ private:
|
|||
|
||||
unittest
|
||||
{
|
||||
void ensureDefaults()
|
||||
{
|
||||
assert(FloatingPointControl.rounding
|
||||
== FloatingPointControl.roundToNearest);
|
||||
assert(FloatingPointControl.enabledExceptions == 0);
|
||||
}
|
||||
|
||||
{
|
||||
FloatingPointControl ctrl;
|
||||
}
|
||||
ensureDefaults();
|
||||
|
||||
{
|
||||
FloatingPointControl ctrl;
|
||||
ctrl.rounding = FloatingPointControl.roundDown;
|
||||
assert(FloatingPointControl.rounding == FloatingPointControl.roundDown);
|
||||
}
|
||||
ensureDefaults();
|
||||
|
||||
{
|
||||
FloatingPointControl ctrl;
|
||||
ctrl.enableExceptions(FloatingPointControl.divByZeroException
|
||||
|
@ -2974,9 +3007,7 @@ unittest
|
|||
ctrl.rounding = FloatingPointControl.roundUp;
|
||||
assert(FloatingPointControl.rounding == FloatingPointControl.roundUp);
|
||||
}
|
||||
assert(FloatingPointControl.rounding
|
||||
== FloatingPointControl.roundToNearest);
|
||||
assert(FloatingPointControl.enabledExceptions ==0);
|
||||
ensureDefaults();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue