1 // Written in the D programming language.
4 This is a submodule of $(MREF std, math).
6 It contains several versions of remainder calculation.
8 Copyright: Copyright The D Language Foundation 2000 - 2011.
9 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
10 Authors: $(HTTP digitalmars.com, Walter Bright), Don Clugston,
11 Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
12 Source: $(PHOBOSSRC std/math/remainder.d)
15 TABLE_SV = <table border="1" cellpadding="4" cellspacing="0">
16 <caption>Special Values</caption>
20 PLUSMNINF = ±∞
23 module std
.math
.remainder
;
25 static import core
.stdc
.math
;
27 /************************************
28 * Calculates the remainder from the calculation x/y.
30 * The value of x - i * y, where i is the number of times that y can
31 * be completely subtracted from x. The result has the same sign as x.
34 * $(TR $(TH x) $(TH y) $(TH fmod(x, y)) $(TH invalid?))
35 * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD no))
36 * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(NAN)) $(TD yes))
37 * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(NAN)) $(TD yes))
38 * $(TR $(TD !=$(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD no))
41 real fmod(real x
, real y
) @trusted nothrow @nogc
43 version (CRuntime_Microsoft
)
48 return core
.stdc
.math
.fmodl(x
, y
);
54 import std
.math
.operations
: feqrel
;
55 import std
.math
.traits
: isIdentical
, isNaN
;
57 assert(isIdentical(fmod(0.0, 1.0), 0.0));
58 assert(fmod(5.0, 3.0).feqrel(2.0) > 16);
59 assert(isNaN(fmod(5.0, 0.0)));
62 /************************************
63 * Breaks x into an integral part and a fractional part, each of which has
64 * the same sign as x. The integral part is stored in i.
66 * The fractional part of x.
69 * $(TR $(TH x) $(TH i (on input)) $(TH modf(x, i)) $(TH i (on return)))
70 * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(PLUSMNINF)))
73 real modf(real x
, ref real i
) @trusted nothrow @nogc
75 version (CRuntime_Microsoft
)
77 import std
.math
.traits
: copysign
, isInfinity
;
78 import std
.math
.rounding
: trunc
;
81 return copysign(isInfinity(x
) ?
0.0 : x
- i
, x
);
84 return core
.stdc
.math
.modfl(x
,&i
);
90 import std
.math
.operations
: feqrel
;
95 frac
= modf(3.14159, intpart
);
96 assert(intpart
.feqrel(3.0) > 16);
97 assert(frac
.feqrel(0.14159) > 16);
100 /****************************************************
101 * Calculate the remainder x REM y, following IEC 60559.
103 * REM is the value of x - y * n, where n is the integer nearest the exact
105 * If |n - x / y| == 0.5, n is even.
106 * If the result is zero, it has the same sign as x.
107 * Otherwise, the sign of the result is the sign of x / y.
108 * Precision mode has no effect on the remainder functions.
110 * remquo returns `n` in the parameter `n`.
113 * $(TR $(TH x) $(TH y) $(TH remainder(x, y)) $(TH n) $(TH invalid?))
114 * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD 0.0) $(TD no))
115 * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD -$(NAN)) $(TD ?) $(TD yes))
116 * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)$(NAN)) $(TD ?) $(TD yes))
117 * $(TR $(TD != $(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD ?) $(TD no))
120 real remainder(real x
, real y
) @trusted nothrow @nogc
122 return core
.stdc
.math
.remainderl(x
, y
);
126 real remquo(real x
, real y
, out int n
) @trusted nothrow @nogc /// ditto
128 return core
.stdc
.math
.remquol(x
, y
, &n
);
132 @safe @nogc nothrow unittest
134 import std
.math
.operations
: feqrel
;
135 import std
.math
.traits
: isNaN
;
137 assert(remainder(5.1, 3.0).feqrel(-0.9) > 16);
138 assert(remainder(-5.1, 3.0).feqrel(0.9) > 16);
139 assert(remainder(0.0, 3.0) == 0.0);
141 assert(isNaN(remainder(1.0, 0.0)));
142 assert(isNaN(remainder(-1.0, 0.0)));
146 @safe @nogc nothrow unittest
148 import std
.math
.operations
: feqrel
;
152 assert(remquo(5.1, 3.0, n
).feqrel(-0.9) > 16 && n
== 2);
153 assert(remquo(-5.1, 3.0, n
).feqrel(0.9) > 16 && n
== -2);
154 assert(remquo(0.0, 3.0, n
) == 0.0 && n
== 0);