// Written in the D programming language. /** This is a submodule of $(MREF std, math). It contains several versions of remainder calculation. Copyright: Copyright The D Language Foundation 2000 - 2011. 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/remainder.d) Macros: TABLE_SV = $0
Special Values
NAN = $(RED NAN) PLUSMN = ± PLUSMNINF = ±∞ */ module std.math.remainder; static import core.stdc.math; /************************************ * Calculates the remainder from the calculation x/y. * Returns: * The value of x - i * y, where i is the number of times that y can * be completely subtracted from x. The result has the same sign as x. * * $(TABLE_SV * $(TR $(TH x) $(TH y) $(TH fmod(x, y)) $(TH invalid?)) * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD no)) * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(NAN)) $(TD yes)) * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(NAN)) $(TD yes)) * $(TR $(TD !=$(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD no)) * ) */ real fmod(real x, real y) @trusted nothrow @nogc { version (CRuntime_Microsoft) { return x % y; } else return core.stdc.math.fmodl(x, y); } /// @safe unittest { import std.math.operations : feqrel; import std.math.traits : isIdentical, isNaN; assert(isIdentical(fmod(0.0, 1.0), 0.0)); assert(fmod(5.0, 3.0).feqrel(2.0) > 16); assert(isNaN(fmod(5.0, 0.0))); } /************************************ * Breaks x into an integral part and a fractional part, each of which has * the same sign as x. The integral part is stored in i. * Returns: * The fractional part of x. * * $(TABLE_SV * $(TR $(TH x) $(TH i (on input)) $(TH modf(x, i)) $(TH i (on return))) * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(PLUSMNINF))) * ) */ real modf(real x, ref real i) @trusted nothrow @nogc { version (CRuntime_Microsoft) { import std.math.traits : copysign, isInfinity; import std.math.rounding : trunc; i = trunc(x); return copysign(isInfinity(x) ? 0.0 : x - i, x); } else return core.stdc.math.modfl(x,&i); } /// @safe unittest { import std.math.operations : feqrel; real frac; real intpart; frac = modf(3.14159, intpart); assert(intpart.feqrel(3.0) > 16); assert(frac.feqrel(0.14159) > 16); } /**************************************************** * Calculate the remainder x REM y, following IEC 60559. * * REM is the value of x - y * n, where n is the integer nearest the exact * value of x / y. * If |n - x / y| == 0.5, n is even. * If the result is zero, it has the same sign as x. * Otherwise, the sign of the result is the sign of x / y. * Precision mode has no effect on the remainder functions. * * remquo returns `n` in the parameter `n`. * * $(TABLE_SV * $(TR $(TH x) $(TH y) $(TH remainder(x, y)) $(TH n) $(TH invalid?)) * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD 0.0) $(TD no)) * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD -$(NAN)) $(TD ?) $(TD yes)) * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)$(NAN)) $(TD ?) $(TD yes)) * $(TR $(TD != $(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD ?) $(TD no)) * ) */ real remainder(real x, real y) @trusted nothrow @nogc { return core.stdc.math.remainderl(x, y); } /// ditto real remquo(real x, real y, out int n) @trusted nothrow @nogc /// ditto { return core.stdc.math.remquol(x, y, &n); } /// @safe @nogc nothrow unittest { import std.math.operations : feqrel; import std.math.traits : isNaN; assert(remainder(5.1, 3.0).feqrel(-0.9) > 16); assert(remainder(-5.1, 3.0).feqrel(0.9) > 16); assert(remainder(0.0, 3.0) == 0.0); assert(isNaN(remainder(1.0, 0.0))); assert(isNaN(remainder(-1.0, 0.0))); } /// @safe @nogc nothrow unittest { import std.math.operations : feqrel; int n; assert(remquo(5.1, 3.0, n).feqrel(-0.9) > 16 && n == 2); assert(remquo(-5.1, 3.0, n).feqrel(0.9) > 16 && n == -2); assert(remquo(0.0, 3.0, n) == 0.0 && n == 0); }