tree-optimization/118653 - ICE in vectorizable_live_operation
[gcc.git] / libphobos / src / std / math / remainder.d
blob8766713916e65ed36ac0abc5a6d591aaffeccd22
1 // Written in the D programming language.
3 /**
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)
14 Macros:
15 TABLE_SV = <table border="1" cellpadding="4" cellspacing="0">
16 <caption>Special Values</caption>
17 $0</table>
18 NAN = $(RED NAN)
19 PLUSMN = &plusmn;
20 PLUSMNINF = &plusmn;&infin;
23 module std.math.remainder;
25 static import core.stdc.math;
27 /************************************
28 * Calculates the remainder from the calculation x/y.
29 * Returns:
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.
33 * $(TABLE_SV
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))
39 * )
41 real fmod(real x, real y) @trusted nothrow @nogc
43 version (CRuntime_Microsoft)
45 return x % y;
47 else
48 return core.stdc.math.fmodl(x, y);
51 ///
52 @safe unittest
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.
65 * Returns:
66 * The fractional part of x.
68 * $(TABLE_SV
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)))
71 * )
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;
80 i = trunc(x);
81 return copysign(isInfinity(x) ? 0.0 : x - i, x);
83 else
84 return core.stdc.math.modfl(x,&i);
87 ///
88 @safe unittest
90 import std.math.operations : feqrel;
92 real frac;
93 real intpart;
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
104 * value of x / y.
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`.
112 * $(TABLE_SV
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);
125 /// ditto
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;
150 int n;
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);