| // 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 = <table border="1" cellpadding="4" cellspacing="0"> | |
| <caption>Special Values</caption> | |
| $0</table> | |
| 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); | |
| } |