// Written in the D programming language. /**This is a submodule of $(MREF std, math). It contains several functions for rounding floating point numbers. Copyright: Copyright The D Language Foundation 2000 - 2011. D implementations of floor, ceil, and lrint functions are based on the CEPHES math library, which is Copyright (C) 2001 Stephen L. Moshier $(LT)steve@moshier.net$(GT) and are incorporated herein by permission of the author. The author reserves the right to distribute this material elsewhere under different copying permissions. These modifications are distributed here under the following terms:License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).Authors: $(HTTP digitalmars.com, Walter Bright), Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw and David NadlingerSource: $(PHOBOSSRC std/math/rounding.d) */ /* NOTE: This file has been patched from the original DMD distribution to * work with the GDC compiler. */module std.math.rounding; static import core.math;static import core.stdc.math; import std.traits : isFloatingPoint, isIntegral, Unqual; version (D_InlineAsm_X86) version = InlineAsm_X86_Any;version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; version (InlineAsm_X86_Any) version = InlineAsm_X87;version (InlineAsm_X87){ static assert(real.mant_dig == 64); version (CRuntime_Microsoft) version = InlineAsm_X87_MSVC;} /************************************** * Returns the value of x rounded upward to the next integer * (toward positive infinity). */real ceil(real x) @trusted pure nothrow @nogc{ version (InlineAsm_X87_MSVC) { version (X86_64) { asm pure nothrow @nogc { naked ; fld real ptr [RCX] ; fstcw 8[RSP] ; mov AL,9[RSP] ; mov DL,AL ; and AL,0xC3 ; or AL,0x08 ; // round to +infinity mov 9[RSP],AL ; fldcw 8[RSP] ; frndint ; mov 9[RSP],DL ; fldcw 8[RSP] ; ret ; } } else { short cw; asm pure nothrow @nogc { fld x ; fstcw cw ; mov AL,byte ptr cw+1 ; mov DL,AL ; and AL,0xC3 ; or AL,0x08 ; // round to +infinity mov byte ptr cw+1,AL ; fldcw cw ; frndint ; mov byte ptr cw+1,DL ; fldcw cw ; } } } else { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; real y = floorImpl(x); if (y < x) y += 1.0; return y; }} ///@safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(ceil(+123.456L) == +124); assert(ceil(-123.456L) == -123); assert(ceil(-1.234L) == -1); assert(ceil(-0.123L) == 0); assert(ceil(0.0L) == 0); assert(ceil(+0.123L) == 1); assert(ceil(+1.234L) == 2); assert(ceil(real.infinity) == real.infinity); assert(isNaN(ceil(real.nan))); assert(isNaN(ceil(real.init)));} /// dittodouble ceil(double x) @trusted pure nothrow @nogc{ import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; double y = floorImpl(x); if (y < x) y += 1.0; return y;} @safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(ceil(+123.456) == +124); assert(ceil(-123.456) == -123); assert(ceil(-1.234) == -1); assert(ceil(-0.123) == 0); assert(ceil(0.0) == 0); assert(ceil(+0.123) == 1); assert(ceil(+1.234) == 2); assert(ceil(double.infinity) == double.infinity); assert(isNaN(ceil(double.nan))); assert(isNaN(ceil(double.init)));} /// dittofloat ceil(float x) @trusted pure nothrow @nogc{ import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; float y = floorImpl(x); if (y < x) y += 1.0; return y;} @safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(ceil(+123.456f) == +124); assert(ceil(-123.456f) == -123); assert(ceil(-1.234f) == -1); assert(ceil(-0.123f) == 0); assert(ceil(0.0f) == 0); assert(ceil(+0.123f) == 1); assert(ceil(+1.234f) == 2); assert(ceil(float.infinity) == float.infinity); assert(isNaN(ceil(float.nan))); assert(isNaN(ceil(float.init)));} /************************************** * Returns the value of x rounded downward to the next integer * (toward negative infinity). */real floor(real x) @trusted pure nothrow @nogc{ version (InlineAsm_X87_MSVC) { version (X86_64) { asm pure nothrow @nogc { naked ; fld real ptr [RCX] ; fstcw 8[RSP] ; mov AL,9[RSP] ; mov DL,AL ; and AL,0xC3 ; or AL,0x04 ; // round to -infinity mov 9[RSP],AL ; fldcw 8[RSP] ; frndint ; mov 9[RSP],DL ; fldcw 8[RSP] ; ret ; } } else { short cw; asm pure nothrow @nogc { fld x ; fstcw cw ; mov AL,byte ptr cw+1 ; mov DL,AL ; and AL,0xC3 ; or AL,0x04 ; // round to -infinity mov byte ptr cw+1,AL ; fldcw cw ; frndint ; mov byte ptr cw+1,DL ; fldcw cw ; } } } else { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x); }} ///@safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(floor(+123.456L) == +123); assert(floor(-123.456L) == -124); assert(floor(+123.0L) == +123); assert(floor(-124.0L) == -124); assert(floor(-1.234L) == -2); assert(floor(-0.123L) == -1); assert(floor(0.0L) == 0); assert(floor(+0.123L) == 0); assert(floor(+1.234L) == 1); assert(floor(real.infinity) == real.infinity); assert(isNaN(floor(real.nan))); assert(isNaN(floor(real.init)));} /// dittodouble floor(double x) @trusted pure nothrow @nogc{ import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x);} @safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(floor(+123.456) == +123); assert(floor(-123.456) == -124); assert(floor(+123.0) == +123); assert(floor(-124.0) == -124); assert(floor(-1.234) == -2); assert(floor(-0.123) == -1); assert(floor(0.0) == 0); assert(floor(+0.123) == 0); assert(floor(+1.234) == 1); assert(floor(double.infinity) == double.infinity); assert(isNaN(floor(double.nan))); assert(isNaN(floor(double.init)));} /// dittofloat floor(float x) @trusted pure nothrow @nogc{ import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x);} @safe pure nothrow @nogc unittest{ import std.math.traits : isNaN; assert(floor(+123.456f) == +123); assert(floor(-123.456f) == -124); assert(floor(+123.0f) == +123); assert(floor(-124.0f) == -124); assert(floor(-1.234f) == -2); assert(floor(-0.123f) == -1); assert(floor(0.0f) == 0); assert(floor(+0.123f) == 0); assert(floor(+1.234f) == 1); assert(floor(float.infinity) == float.infinity); assert(isNaN(floor(float.nan))); assert(isNaN(floor(float.init)));} // https://issues.dlang.org/show_bug.cgi?id=6381// floor/ceil should be usable in pure function.@safe pure nothrow unittest{ auto x = floor(1.2); auto y = ceil(1.2);} /** * Round `val` to a multiple of `unit`. `rfunc` specifies the rounding * function to use; by default this is `rint`, which uses the current * rounding mode. */Unqual!F quantize(alias rfunc = rint, F)(const F val, const F unit)if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F){ import std.math.traits : isInfinity; typeof(return) ret = val; if (unit != 0) { const scaled = val / unit; if (!scaled.isInfinity) ret = rfunc(scaled) * unit; } return ret;} ///@safe pure nothrow @nogc unittest{ import std.math.operations : isClose; assert(isClose(12345.6789L.quantize(0.01L), 12345.68L)); assert(isClose(12345.6789L.quantize!floor(0.01L), 12345.67L)); assert(isClose(12345.6789L.quantize(22.0L), 12342.0L));} ///@safe pure nothrow @nogc unittest{ import std.math.operations : isClose; import std.math.traits : isNaN; assert(isClose(12345.6789L.quantize(0), 12345.6789L)); assert(12345.6789L.quantize(real.infinity).isNaN); assert(12345.6789L.quantize(real.nan).isNaN); assert(real.infinity.quantize(0.01L) == real.infinity); assert(real.infinity.quantize(real.nan).isNaN); assert(real.nan.quantize(0.01L).isNaN); assert(real.nan.quantize(real.infinity).isNaN); assert(real.nan.quantize(real.nan).isNaN);} /** * Round `val` to a multiple of `pow(base, exp)`. `rfunc` specifies the * rounding function to use; by default this is `rint`, which uses the * current rounding mode. */Unqual!F quantize(real base, alias rfunc = rint, F, E)(const F val, const E exp)if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E){ import std.math.exponential : pow; // TODO: Compile-time optimization for power-of-two bases? return quantize!rfunc(val, pow(cast(F) base, exp));} /// dittoUnqual!F quantize(real base, long exp = 1, alias rfunc = rint, F)(const F val)if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F){ import std.math.exponential : pow; enum unit = cast(F) pow(base, exp); return quantize!rfunc(val, unit);} ///@safe pure nothrow @nogc unittest{ import std.math.operations : isClose; assert(isClose(12345.6789L.quantize!10(-2), 12345.68L)); assert(isClose(12345.6789L.quantize!(10, -2), 12345.68L)); assert(isClose(12345.6789L.quantize!(10, floor)(-2), 12345.67L)); assert(isClose(12345.6789L.quantize!(10, -2, floor), 12345.67L)); assert(isClose(12345.6789L.quantize!22(1), 12342.0L)); assert(isClose(12345.6789L.quantize!22, 12342.0L));} @safe pure nothrow @nogc unittest{ import std.math.exponential : log10, pow; import std.math.operations : isClose; import std.meta : AliasSeq; static foreach (F; AliasSeq!(real, double, float)) {{ const maxL10 = cast(int) F.max.log10.floor; const maxR10 = pow(cast(F) 10, maxL10); assert(isClose((cast(F) 0.9L * maxR10).quantize!10(maxL10), maxR10)); assert(isClose((cast(F)-0.9L * maxR10).quantize!10(maxL10), -maxR10)); assert(F.max.quantize(F.min_normal) == F.max); assert((-F.max).quantize(F.min_normal) == -F.max); assert(F.min_normal.quantize(F.max) == 0); assert((-F.min_normal).quantize(F.max) == 0); assert(F.min_normal.quantize(F.min_normal) == F.min_normal); assert((-F.min_normal).quantize(F.min_normal) == -F.min_normal); }}} /****************************************** * Rounds x to the nearest integer value, using the current rounding * mode. * * Unlike the rint functions, nearbyint does not raise the * FE_INEXACT exception. */pragma(inline, true)real nearbyint(real x) @safe pure nothrow @nogc{ return core.stdc.math.nearbyintl(x);} ///@safe pure unittest{ import std.math.traits : isNaN; assert(nearbyint(0.4) == 0); assert(nearbyint(0.5) == 0); assert(nearbyint(0.6) == 1); assert(nearbyint(100.0) == 100); assert(isNaN(nearbyint(real.nan))); assert(nearbyint(real.infinity) == real.infinity); assert(nearbyint(-real.infinity) == -real.infinity);} /********************************** * Rounds x to the nearest integer value, using the current rounding * mode. * * If the return value is not equal to x, the FE_INEXACT * exception is raised. * * $(LREF nearbyint) performs the same operation, but does * not set the FE_INEXACT exception. */pragma(inline, true)real rint(real x) @safe pure nothrow @nogc{ return core.math.rint(x);}///dittopragma(inline, true)double rint(double x) @safe pure nothrow @nogc{ return core.math.rint(x);}///dittopragma(inline, true)float rint(float x) @safe pure nothrow @nogc{ return core.math.rint(x);} ///@safe unittest{ import std.math.traits : isNaN; version (IeeeFlagsSupport) resetIeeeFlags(); assert(rint(0.4) == 0); version (GNU) { /* inexact bit not set with enabled optimizations */ } else version (IeeeFlagsSupport) assert(ieeeFlags.inexact); Lines 1–500 of 999. Load more
// Written in the D programming language. /** This is a submodule of $(MREF std, math). It contains several functions for rounding floating point numbers. Copyright: Copyright The D Language Foundation 2000 - 2011. D implementations of floor, ceil, and lrint functions are based on the CEPHES math library, which is Copyright (C) 2001 Stephen L. Moshier $(LT)steve@moshier.net$(GT) and are incorporated herein by permission of the author. The author reserves the right to distribute this material elsewhere under different copying permissions. These modifications are distributed here under the following terms: License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP digitalmars.com, Walter Bright), Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger Source: $(PHOBOSSRC std/math/rounding.d) */ /* NOTE: This file has been patched from the original DMD distribution to * work with the GDC compiler. */ module std.math.rounding; static import core.math; static import core.stdc.math; import std.traits : isFloatingPoint, isIntegral, Unqual; version (D_InlineAsm_X86) version = InlineAsm_X86_Any; version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; version (InlineAsm_X86_Any) version = InlineAsm_X87; version (InlineAsm_X87) { static assert(real.mant_dig == 64); version (CRuntime_Microsoft) version = InlineAsm_X87_MSVC; } /************************************** * Returns the value of x rounded upward to the next integer * (toward positive infinity). */ real ceil(real x) @trusted pure nothrow @nogc { version (InlineAsm_X87_MSVC) { version (X86_64) { asm pure nothrow @nogc { naked ; fld real ptr [RCX] ; fstcw 8[RSP] ; mov AL,9[RSP] ; mov DL,AL ; and AL,0xC3 ; or AL,0x08 ; // round to +infinity mov 9[RSP],AL ; fldcw 8[RSP] ; frndint ; mov 9[RSP],DL ; fldcw 8[RSP] ; ret ; } } else { short cw; asm pure nothrow @nogc { fld x ; fstcw cw ; mov AL,byte ptr cw+1 ; mov DL,AL ; and AL,0xC3 ; or AL,0x08 ; // round to +infinity mov byte ptr cw+1,AL ; fldcw cw ; frndint ; mov byte ptr cw+1,DL ; fldcw cw ; } } } else { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; real y = floorImpl(x); if (y < x) y += 1.0; return y; } } /// @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(ceil(+123.456L) == +124); assert(ceil(-123.456L) == -123); assert(ceil(-1.234L) == -1); assert(ceil(-0.123L) == 0); assert(ceil(0.0L) == 0); assert(ceil(+0.123L) == 1); assert(ceil(+1.234L) == 2); assert(ceil(real.infinity) == real.infinity); assert(isNaN(ceil(real.nan))); assert(isNaN(ceil(real.init))); } /// ditto double ceil(double x) @trusted pure nothrow @nogc { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; double y = floorImpl(x); if (y < x) y += 1.0; return y; } @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(ceil(+123.456) == +124); assert(ceil(-123.456) == -123); assert(ceil(-1.234) == -1); assert(ceil(-0.123) == 0); assert(ceil(0.0) == 0); assert(ceil(+0.123) == 1); assert(ceil(+1.234) == 2); assert(ceil(double.infinity) == double.infinity); assert(isNaN(ceil(double.nan))); assert(isNaN(ceil(double.init))); } /// ditto float ceil(float x) @trusted pure nothrow @nogc { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) return x; float y = floorImpl(x); if (y < x) y += 1.0; return y; } @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(ceil(+123.456f) == +124); assert(ceil(-123.456f) == -123); assert(ceil(-1.234f) == -1); assert(ceil(-0.123f) == 0); assert(ceil(0.0f) == 0); assert(ceil(+0.123f) == 1); assert(ceil(+1.234f) == 2); assert(ceil(float.infinity) == float.infinity); assert(isNaN(ceil(float.nan))); assert(isNaN(ceil(float.init))); } /************************************** * Returns the value of x rounded downward to the next integer * (toward negative infinity). */ real floor(real x) @trusted pure nothrow @nogc { version (InlineAsm_X87_MSVC) { version (X86_64) { asm pure nothrow @nogc { naked ; fld real ptr [RCX] ; fstcw 8[RSP] ; mov AL,9[RSP] ; mov DL,AL ; and AL,0xC3 ; or AL,0x04 ; // round to -infinity mov 9[RSP],AL ; fldcw 8[RSP] ; frndint ; mov 9[RSP],DL ; fldcw 8[RSP] ; ret ; } } else { short cw; asm pure nothrow @nogc { fld x ; fstcw cw ; mov AL,byte ptr cw+1 ; mov DL,AL ; and AL,0xC3 ; or AL,0x04 ; // round to -infinity mov byte ptr cw+1,AL ; fldcw cw ; frndint ; mov byte ptr cw+1,DL ; fldcw cw ; } } } else { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x); } } /// @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(floor(+123.456L) == +123); assert(floor(-123.456L) == -124); assert(floor(+123.0L) == +123); assert(floor(-124.0L) == -124); assert(floor(-1.234L) == -2); assert(floor(-0.123L) == -1); assert(floor(0.0L) == 0); assert(floor(+0.123L) == 0); assert(floor(+1.234L) == 1); assert(floor(real.infinity) == real.infinity); assert(isNaN(floor(real.nan))); assert(isNaN(floor(real.init))); } /// ditto double floor(double x) @trusted pure nothrow @nogc { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x); } @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(floor(+123.456) == +123); assert(floor(-123.456) == -124); assert(floor(+123.0) == +123); assert(floor(-124.0) == -124); assert(floor(-1.234) == -2); assert(floor(-0.123) == -1); assert(floor(0.0) == 0); assert(floor(+0.123) == 0); assert(floor(+1.234) == 1); assert(floor(double.infinity) == double.infinity); assert(isNaN(floor(double.nan))); assert(isNaN(floor(double.init))); } /// ditto float floor(float x) @trusted pure nothrow @nogc { import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) return x; return floorImpl(x); } @safe pure nothrow @nogc unittest { import std.math.traits : isNaN; assert(floor(+123.456f) == +123); assert(floor(-123.456f) == -124); assert(floor(+123.0f) == +123); assert(floor(-124.0f) == -124); assert(floor(-1.234f) == -2); assert(floor(-0.123f) == -1); assert(floor(0.0f) == 0); assert(floor(+0.123f) == 0); assert(floor(+1.234f) == 1); assert(floor(float.infinity) == float.infinity); assert(isNaN(floor(float.nan))); assert(isNaN(floor(float.init))); } // https://issues.dlang.org/show_bug.cgi?id=6381 // floor/ceil should be usable in pure function. @safe pure nothrow unittest { auto x = floor(1.2); auto y = ceil(1.2); } /** * Round `val` to a multiple of `unit`. `rfunc` specifies the rounding * function to use; by default this is `rint`, which uses the current * rounding mode. */ Unqual!F quantize(alias rfunc = rint, F)(const F val, const F unit) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) { import std.math.traits : isInfinity; typeof(return) ret = val; if (unit != 0) { const scaled = val / unit; if (!scaled.isInfinity) ret = rfunc(scaled) * unit; } return ret; } /// @safe pure nothrow @nogc unittest { import std.math.operations : isClose; assert(isClose(12345.6789L.quantize(0.01L), 12345.68L)); assert(isClose(12345.6789L.quantize!floor(0.01L), 12345.67L)); assert(isClose(12345.6789L.quantize(22.0L), 12342.0L)); } /// @safe pure nothrow @nogc unittest { import std.math.operations : isClose; import std.math.traits : isNaN; assert(isClose(12345.6789L.quantize(0), 12345.6789L)); assert(12345.6789L.quantize(real.infinity).isNaN); assert(12345.6789L.quantize(real.nan).isNaN); assert(real.infinity.quantize(0.01L) == real.infinity); assert(real.infinity.quantize(real.nan).isNaN); assert(real.nan.quantize(0.01L).isNaN); assert(real.nan.quantize(real.infinity).isNaN); assert(real.nan.quantize(real.nan).isNaN); } /** * Round `val` to a multiple of `pow(base, exp)`. `rfunc` specifies the * rounding function to use; by default this is `rint`, which uses the * current rounding mode. */ Unqual!F quantize(real base, alias rfunc = rint, F, E)(const F val, const E exp) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E) { import std.math.exponential : pow; // TODO: Compile-time optimization for power-of-two bases? return quantize!rfunc(val, pow(cast(F) base, exp)); } /// ditto Unqual!F quantize(real base, long exp = 1, alias rfunc = rint, F)(const F val) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) { import std.math.exponential : pow; enum unit = cast(F) pow(base, exp); return quantize!rfunc(val, unit); } /// @safe pure nothrow @nogc unittest { import std.math.operations : isClose; assert(isClose(12345.6789L.quantize!10(-2), 12345.68L)); assert(isClose(12345.6789L.quantize!(10, -2), 12345.68L)); assert(isClose(12345.6789L.quantize!(10, floor)(-2), 12345.67L)); assert(isClose(12345.6789L.quantize!(10, -2, floor), 12345.67L)); assert(isClose(12345.6789L.quantize!22(1), 12342.0L)); assert(isClose(12345.6789L.quantize!22, 12342.0L)); } @safe pure nothrow @nogc unittest { import std.math.exponential : log10, pow; import std.math.operations : isClose; import std.meta : AliasSeq; static foreach (F; AliasSeq!(real, double, float)) {{ const maxL10 = cast(int) F.max.log10.floor; const maxR10 = pow(cast(F) 10, maxL10); assert(isClose((cast(F) 0.9L * maxR10).quantize!10(maxL10), maxR10)); assert(isClose((cast(F)-0.9L * maxR10).quantize!10(maxL10), -maxR10)); assert(F.max.quantize(F.min_normal) == F.max); assert((-F.max).quantize(F.min_normal) == -F.max); assert(F.min_normal.quantize(F.max) == 0); assert((-F.min_normal).quantize(F.max) == 0); assert(F.min_normal.quantize(F.min_normal) == F.min_normal); assert((-F.min_normal).quantize(F.min_normal) == -F.min_normal); }} } /****************************************** * Rounds x to the nearest integer value, using the current rounding * mode. * * Unlike the rint functions, nearbyint does not raise the * FE_INEXACT exception. */ pragma(inline, true) real nearbyint(real x) @safe pure nothrow @nogc { return core.stdc.math.nearbyintl(x); } /// @safe pure unittest { import std.math.traits : isNaN; assert(nearbyint(0.4) == 0); assert(nearbyint(0.5) == 0); assert(nearbyint(0.6) == 1); assert(nearbyint(100.0) == 100); assert(isNaN(nearbyint(real.nan))); assert(nearbyint(real.infinity) == real.infinity); assert(nearbyint(-real.infinity) == -real.infinity); } /********************************** * Rounds x to the nearest integer value, using the current rounding * mode. * * If the return value is not equal to x, the FE_INEXACT * exception is raised. * * $(LREF nearbyint) performs the same operation, but does * not set the FE_INEXACT exception. */ pragma(inline, true) real rint(real x) @safe pure nothrow @nogc { return core.math.rint(x); } ///ditto pragma(inline, true) double rint(double x) @safe pure nothrow @nogc { return core.math.rint(x); } ///ditto pragma(inline, true) float rint(float x) @safe pure nothrow @nogc { return core.math.rint(x); } /// @safe unittest { import std.math.traits : isNaN; version (IeeeFlagsSupport) resetIeeeFlags(); assert(rint(0.4) == 0); version (GNU) { /* inexact bit not set with enabled optimizations */ } else version (IeeeFlagsSupport) assert(ieeeFlags.inexact);