1 // Written in the D programming language.
2 
3 /**
4  * Contains the elementary mathematical functions (powers, roots,
5  * and trigonometric functions), and low-level floating-point operations.
6  * Mathematical special functions are available in `std.mathspecial`.
7  *
8 $(SCRIPT inhibitQuickIndex = 1;)
9 
10 $(DIVC quickindex,
11 $(BOOKTABLE ,
12 $(TR $(TH Category) $(TH Members) )
13 $(TR $(TDNW Constants) $(TD
14     $(MYREF E) $(MYREF PI) $(MYREF PI_2) $(MYREF PI_4) $(MYREF M_1_PI)
15     $(MYREF M_2_PI) $(MYREF M_2_SQRTPI) $(MYREF LN10) $(MYREF LN2)
16     $(MYREF LOG2) $(MYREF LOG2E) $(MYREF LOG2T) $(MYREF LOG10E)
17     $(MYREF SQRT2) $(MYREF SQRT1_2)
18 ))
19 $(TR $(TDNW Classics) $(TD
20     $(MYREF abs) $(MYREF fabs) $(MYREF sqrt) $(MYREF cbrt) $(MYREF hypot)
21     $(MYREF poly) $(MYREF nextPow2) $(MYREF truncPow2)
22 ))
23 $(TR $(TDNW Trigonometry) $(TD
24     $(MYREF sin) $(MYREF cos) $(MYREF tan) $(MYREF asin) $(MYREF acos)
25     $(MYREF atan) $(MYREF atan2) $(MYREF sinh) $(MYREF cosh) $(MYREF tanh)
26     $(MYREF asinh) $(MYREF acosh) $(MYREF atanh)
27 ))
28 $(TR $(TDNW Rounding) $(TD
29     $(MYREF ceil) $(MYREF floor) $(MYREF round) $(MYREF lround)
30     $(MYREF trunc) $(MYREF rint) $(MYREF lrint) $(MYREF nearbyint)
31     $(MYREF rndtol) $(MYREF quantize)
32 ))
33 $(TR $(TDNW Exponentiation & Logarithms) $(TD
34     $(MYREF pow) $(MYREF exp) $(MYREF exp2) $(MYREF expm1) $(MYREF ldexp)
35     $(MYREF frexp) $(MYREF log) $(MYREF log2) $(MYREF log10) $(MYREF logb)
36     $(MYREF ilogb) $(MYREF log1p) $(MYREF scalbn)
37 ))
38 $(TR $(TDNW Modulus) $(TD
39     $(MYREF fmod) $(MYREF modf) $(MYREF remainder)
40 ))
41 $(TR $(TDNW Floating-point operations) $(TD
42     $(MYREF approxEqual) $(MYREF feqrel) $(MYREF fdim) $(MYREF fmax)
43     $(MYREF fmin) $(MYREF fma) $(MYREF isClose) $(MYREF nextDown) $(MYREF nextUp)
44     $(MYREF nextafter) $(MYREF NaN) $(MYREF getNaNPayload)
45     $(MYREF cmp)
46 ))
47 $(TR $(TDNW Introspection) $(TD
48     $(MYREF isFinite) $(MYREF isIdentical) $(MYREF isInfinity) $(MYREF isNaN)
49     $(MYREF isNormal) $(MYREF isSubnormal) $(MYREF signbit) $(MYREF sgn)
50     $(MYREF copysign) $(MYREF isPowerOf2)
51 ))
52 $(TR $(TDNW Hardware Control) $(TD
53     $(MYREF IeeeFlags) $(MYREF FloatingPointControl)
54 ))
55 )
56 )
57 
58  * The functionality closely follows the IEEE754-2008 standard for
59  * floating-point arithmetic, including the use of camelCase names rather
60  * than C99-style lower case names. All of these functions behave correctly
61  * when presented with an infinity or NaN.
62  *
63  * The following IEEE 'real' formats are currently supported:
64  * $(UL
65  * $(LI 64 bit Big-endian  'double' (eg PowerPC))
66  * $(LI 128 bit Big-endian 'quadruple' (eg SPARC))
67  * $(LI 64 bit Little-endian 'double' (eg x86-SSE2))
68  * $(LI 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium))
69  * $(LI 128 bit Little-endian 'quadruple' (not implemented on any known processor!))
70  * $(LI Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support)
71  * )
72  * Unlike C, there is no global 'errno' variable. Consequently, almost all of
73  * these functions are pure nothrow.
74  *
75  * Macros:
76  *      TABLE_SV = <table border="1" cellpadding="4" cellspacing="0">
77  *              <caption>Special Values</caption>
78  *              $0</table>
79  *      SVH = $(TR $(TH $1) $(TH $2))
80  *      SV  = $(TR $(TD $1) $(TD $2))
81  *      TH3 = $(TR $(TH $1) $(TH $2) $(TH $3))
82  *      TD3 = $(TR $(TD $1) $(TD $2) $(TD $3))
83  *      TABLE_DOMRG = <table border="1" cellpadding="4" cellspacing="0">
84  *              $(SVH Domain X, Range Y)
85                 $(SV $1, $2)
86  *              </table>
87  *      DOMAIN=$1
88  *      RANGE=$1
89 
90  *      NAN = $(RED NAN)
91  *      SUP = <span style="vertical-align:super;font-size:smaller">$0</span>
92  *      GAMMA = &#915;
93  *      THETA = &theta;
94  *      INTEGRAL = &#8747;
95  *      INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)
96  *      POWER = $1<sup>$2</sup>
97  *      SUB = $1<sub>$2</sub>
98  *      BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)
99  *      CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)
100  *      PLUSMN = &plusmn;
101  *      INFIN = &infin;
102  *      PLUSMNINF = &plusmn;&infin;
103  *      PI = &pi;
104  *      LT = &lt;
105  *      GT = &gt;
106  *      SQRT = &radic;
107  *      HALF = &frac12;
108  *
109  * Copyright: Copyright The D Language Foundation 2000 - 2011.
110  *            D implementations of tan, atan, atan2, exp, expm1, exp2, log, log10, log1p,
111  *            log2, floor, ceil and lrint functions are based on the CEPHES math library,
112  *            which is Copyright (C) 2001 Stephen L. Moshier $(LT)steve@moshier.net$(GT)
113  *            and are incorporated herein by permission of the author.  The author
114  *            reserves the right to distribute this material elsewhere under different
115  *            copying permissions.  These modifications are distributed here under
116  *            the following terms:
117  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
118  * Authors:   $(HTTP digitalmars.com, Walter Bright), Don Clugston,
119  *            Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
120  * Source: $(PHOBOSSRC std/math.d)
121  */
122 module std.math;
123 
124 version (Win64)
125 {
126     version (D_InlineAsm_X86_64)
127         version = Win64_DMD_InlineAsm;
128 }
129 
130 static import core.math;
131 static import core.stdc.math;
132 static import core.stdc.fenv;
133 import std.traits :  CommonType, isFloatingPoint, isIntegral, isNumeric,
134     isSigned, isUnsigned, Largest, Unqual;
135 
136 // @@@DEPRECATED_2.102@@@
137 // Note: Exposed accidentally, should be deprecated / removed
138 deprecated("std.meta.AliasSeq was unintentionally available from std.math "
139            ~ "and will be removed after 2.102. Please import std.meta instead")
140 public import std.meta : AliasSeq;
141 
142 version (DigitalMars)
143 {
144     version = INLINE_YL2X;        // x87 has opcodes for these
145 }
146 
147 version (X86)       version = X86_Any;
148 version (X86_64)    version = X86_Any;
149 version (PPC)       version = PPC_Any;
150 version (PPC64)     version = PPC_Any;
151 version (MIPS32)    version = MIPS_Any;
152 version (MIPS64)    version = MIPS_Any;
153 version (AArch64)   version = ARM_Any;
154 version (ARM)       version = ARM_Any;
155 version (S390)      version = IBMZ_Any;
156 version (SPARC)     version = SPARC_Any;
157 version (SPARC64)   version = SPARC_Any;
158 version (SystemZ)   version = IBMZ_Any;
159 version (RISCV32)   version = RISCV_Any;
160 version (RISCV64)   version = RISCV_Any;
161 
162 version (D_InlineAsm_X86)
163 {
164     version = InlineAsm_X86_Any;
165 }
166 else version (D_InlineAsm_X86_64)
167 {
168     version = InlineAsm_X86_Any;
169 }
170 
171 version (CRuntime_Microsoft)
172 {
173     version (InlineAsm_X86_Any)
174         version = MSVC_InlineAsm;
175 }
176 
177 version (X86_64) version = StaticallyHaveSSE;
178 version (X86) version (OSX) version = StaticallyHaveSSE;
179 
180 version (StaticallyHaveSSE)
181 {
182     private enum bool haveSSE = true;
183 }
184 else version (X86)
185 {
186     static import core.cpuid;
187     private alias haveSSE = core.cpuid.sse;
188 }
189 
190 version (D_SoftFloat)
191 {
192     // Some soft float implementations may support IEEE floating flags.
193     // The implementation here supports hardware flags only and is so currently
194     // only available for supported targets.
195 }
196 else version (X86_Any)   version = IeeeFlagsSupport;
197 else version (PPC_Any)   version = IeeeFlagsSupport;
198 else version (RISCV_Any) version = IeeeFlagsSupport;
199 else version (MIPS_Any)  version = IeeeFlagsSupport;
200 else version (ARM_Any)   version = IeeeFlagsSupport;
201 
202 // Struct FloatingPointControl is only available if hardware FP units are available.
203 version (D_HardFloat)
204 {
205     // FloatingPointControl.clearExceptions() depends on version IeeeFlagsSupport
206     version (IeeeFlagsSupport) version = FloatingPointControlSupport;
207 }
208 
209 version (StdUnittest) private
210 {
211     static if (real.sizeof > double.sizeof)
212         enum uint useDigits = 16;
213     else
214         enum uint useDigits = 15;
215 
216     /******************************************
217      * Compare floating point numbers to n decimal digits of precision.
218      * Returns:
219      *  1       match
220      *  0       nomatch
221      */
222 
223     private bool equalsDigit(real x, real y, uint ndigits) @safe nothrow @nogc
224     {
225         import core.stdc.stdio : sprintf;
226 
227         if (signbit(x) != signbit(y))
228             return 0;
229 
230         if (isInfinity(x) && isInfinity(y))
231             return 1;
232         if (isInfinity(x) || isInfinity(y))
233             return 0;
234 
235         if (isNaN(x) && isNaN(y))
236             return 1;
237         if (isNaN(x) || isNaN(y))
238             return 0;
239 
240         char[30] bufx;
241         char[30] bufy;
242         assert(ndigits < bufx.length);
243 
244         int ix;
245         int iy;
246         version (CRuntime_Microsoft)
247             alias real_t = double;
248         else
249             alias real_t = real;
250 
251         () @trusted {
252             ix = sprintf(bufx.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) x);
253             iy = sprintf(bufy.ptr, is(real_t == real) ? "%.*Lg" : "%.*g", ndigits, cast(real_t) y);
254         } ();
255 
256         assert(ix < bufx.length && ix > 0);
257         assert(ix < bufy.length && ix > 0);
258 
259         return bufx[0 .. ix] == bufy[0 .. iy];
260     }
261 }
262 
263 
264 // Values obtained from Wolfram Alpha. 116 bits ought to be enough for anybody.
265 // Wolfram Alpha LLC. 2011. Wolfram|Alpha. http://www.wolframalpha.com/input/?i=e+in+base+16 (access July 6, 2011).
266 enum real E =          0x1.5bf0a8b1457695355fb8ac404e7a8p+1L; /** e = 2.718281... */
267 enum real LOG2T =      0x1.a934f0979a3715fc9257edfe9b5fbp+1L; /** $(SUB log, 2)10 = 3.321928... */
268 enum real LOG2E =      0x1.71547652b82fe1777d0ffda0d23a8p+0L; /** $(SUB log, 2)e = 1.442695... */
269 enum real LOG2 =       0x1.34413509f79fef311f12b35816f92p-2L; /** $(SUB log, 10)2 = 0.301029... */
270 enum real LOG10E =     0x1.bcb7b1526e50e32a6ab7555f5a67cp-2L; /** $(SUB log, 10)e = 0.434294... */
271 enum real LN2 =        0x1.62e42fefa39ef35793c7673007e5fp-1L; /** ln 2  = 0.693147... */
272 enum real LN10 =       0x1.26bb1bbb5551582dd4adac5705a61p+1L; /** ln 10 = 2.302585... */
273 enum real PI =         0x1.921fb54442d18469898cc51701b84p+1L; /** &pi; = 3.141592... */
274 enum real PI_2 =       PI/2;                                  /** $(PI) / 2 = 1.570796... */
275 enum real PI_4 =       PI/4;                                  /** $(PI) / 4 = 0.785398... */
276 enum real M_1_PI =     0x1.45f306dc9c882a53f84eafa3ea69cp-2L; /** 1 / $(PI) = 0.318309... */
277 enum real M_2_PI =     2*M_1_PI;                              /** 2 / $(PI) = 0.636619... */
278 enum real M_2_SQRTPI = 0x1.20dd750429b6d11ae3a914fed7fd8p+0L; /** 2 / $(SQRT)$(PI) = 1.128379... */
279 enum real SQRT2 =      0x1.6a09e667f3bcc908b2fb1366ea958p+0L; /** $(SQRT)2 = 1.414213... */
280 enum real SQRT1_2 =    SQRT2/2;                               /** $(SQRT)$(HALF) = 0.707106... */
281 // Note: Make sure the magic numbers in compiler backend for x87 match these.
282 
283 /***********************************
284  * Calculates the absolute value of a number.
285  *
286  * Params:
287  *     Num = (template parameter) type of number
288  *       x = real number value
289  *
290  * Returns:
291  *     The absolute value of the number. If floating-point or integral,
292  *     the return type will be the same as the input.
293  *
294  * Limitations:
295  *     Does not work correctly for signed intergal types and value `Num`.min.
296  */
297 auto abs(Num)(Num x) @nogc pure nothrow
298 if ((is(immutable Num == immutable short) || is(immutable Num == immutable byte)) ||
299     (is(typeof(Num.init >= 0)) && is(typeof(-Num.init))))
300 {
301     static if (isFloatingPoint!(Num))
302         return fabs(x);
303     else
304     {
305         static if (is(immutable Num == immutable short) || is(immutable Num == immutable byte))
306             return x >= 0 ? x : cast(Num) -int(x);
307         else
308             return x >= 0 ? x : -x;
309     }
310 }
311 
312 /// ditto
313 @safe pure nothrow @nogc unittest
314 {
315     assert(isIdentical(abs(-0.0L), 0.0L));
316     assert(isNaN(abs(real.nan)));
317     assert(abs(-real.infinity) == real.infinity);
318     assert(abs(-56) == 56);
319     assert(abs(2321312L)  == 2321312L);
320 }
321 
322 @safe pure nothrow @nogc unittest
323 {
324     short s = -8;
325     byte b = -8;
326     assert(abs(s) == 8);
327     assert(abs(b) == 8);
328     immutable(byte) c = -8;
329     assert(abs(c) == 8);
330 }
331 
332 @safe pure nothrow @nogc unittest
333 {
334     import std.meta : AliasSeq;
335     static foreach (T; AliasSeq!(float, double, real))
336     {{
337         T f = 3;
338         assert(abs(f) == f);
339         assert(abs(-f) == f);
340     }}
341 }
342 
343 // see https://issues.dlang.org/show_bug.cgi?id=20205
344 // to avoid falling into the trap again
345 @safe pure nothrow @nogc unittest
346 {
347     assert(50 - abs(-100) == -50);
348 }
349 
350 // https://issues.dlang.org/show_bug.cgi?id=19162
351 @safe unittest
352 {
353     struct Vector(T, int size)
354     {
355         T x, y, z;
356     }
357 
358     static auto abs(T, int size)(auto ref const Vector!(T, size) v)
359     {
360         return v;
361     }
362     Vector!(int, 3) v;
363     assert(abs(v) == v);
364 }
365 
366 /***********************************
367  * Returns cosine of x. x is in radians.
368  *
369  *      $(TABLE_SV
370  *      $(TR $(TH x)                 $(TH cos(x)) $(TH invalid?))
371  *      $(TR $(TD $(NAN))            $(TD $(NAN)) $(TD yes)     )
372  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN)) $(TD yes)     )
373  *      )
374  * Bugs:
375  *      Results are undefined if |x| >= $(POWER 2,64).
376  */
377 
378 real cos(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.cos(x); }
379 //FIXME
380 ///ditto
381 double cos(double x) @safe pure nothrow @nogc { return cos(cast(real) x); }
382 //FIXME
383 ///ditto
384 float cos(float x) @safe pure nothrow @nogc { return cos(cast(real) x); }
385 
386 ///
387 @safe unittest
388 {
389     assert(cos(0.0) == 1.0);
390     assert(cos(1.0).approxEqual(0.540));
391     assert(cos(3.0).approxEqual(-0.989));
392 }
393 
394 @safe unittest
395 {
396     real function(real) pcos = &cos;
397     assert(pcos != null);
398 }
399 
400 /***********************************
401  * Returns $(HTTP en.wikipedia.org/wiki/Sine, sine) of x. x is in $(HTTP en.wikipedia.org/wiki/Radian, radians).
402  *
403  *      $(TABLE_SV
404  *      $(TH3 x           ,  sin(x)      ,  invalid?)
405  *      $(TD3 $(NAN)      ,  $(NAN)      ,  yes     )
406  *      $(TD3 $(PLUSMN)0.0,  $(PLUSMN)0.0,  no      )
407  *      $(TD3 $(PLUSMNINF),  $(NAN)      ,  yes     )
408  *      )
409  *
410  * Params:
411  *      x = angle in radians (not degrees)
412  * Returns:
413  *      sine of x
414  * See_Also:
415  *      $(MYREF cos), $(MYREF tan), $(MYREF asin)
416  * Bugs:
417  *      Results are undefined if |x| >= $(POWER 2,64).
418  */
419 
420 real sin(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.sin(x); }
421 //FIXME
422 ///ditto
423 double sin(double x) @safe pure nothrow @nogc { return sin(cast(real) x); }
424 //FIXME
425 ///ditto
426 float sin(float x) @safe pure nothrow @nogc { return sin(cast(real) x); }
427 
428 ///
429 @safe unittest
430 {
431     import std.math : sin, PI;
432     import std.stdio : writefln;
433 
434     void someFunc()
435     {
436       real x = 30.0;
437       auto result = sin(x * (PI / 180)); // convert degrees to radians
438       writefln("The sine of %s degrees is %s", x, result);
439     }
440 }
441 
442 @safe unittest
443 {
444     real function(real) psin = &sin;
445     assert(psin != null);
446 }
447 
448 /****************************************************************************
449  * Returns tangent of x. x is in radians.
450  *
451  *      $(TABLE_SV
452  *      $(TR $(TH x)             $(TH tan(x))       $(TH invalid?))
453  *      $(TR $(TD $(NAN))        $(TD $(NAN))       $(TD yes))
454  *      $(TR $(TD $(PLUSMN)0.0)  $(TD $(PLUSMN)0.0) $(TD no))
455  *      $(TR $(TD $(PLUSMNINF))  $(TD $(NAN))       $(TD yes))
456  *      )
457  */
458 real tan(real x) @trusted pure nothrow @nogc // TODO: @safe
459 {
460     version (InlineAsm_X86_Any)
461     {
462         if (!__ctfe)
463             return tanAsm(x);
464     }
465     return tanImpl(x);
466 }
467 
468 /// ditto
469 double tan(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) tan(cast(real) x) : tanImpl(x); }
470 
471 /// ditto
472 float tan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) tan(cast(real) x) : tanImpl(x); }
473 
474 ///
475 @safe unittest
476 {
477     assert(isIdentical(tan(0.0), 0.0));
478     assert(tan(PI).approxEqual(0));
479     assert(tan(PI / 3).approxEqual(sqrt(3.0)));
480 }
481 
482 version (InlineAsm_X86_Any)
483 private real tanAsm(real x) @trusted pure nothrow @nogc
484 {
485     version (D_InlineAsm_X86)
486     {
487     asm pure nothrow @nogc
488     {
489         fld     x[EBP]                  ; // load theta
490         fxam                            ; // test for oddball values
491         fstsw   AX                      ;
492         sahf                            ;
493         jc      trigerr                 ; // x is NAN, infinity, or empty
494                                           // 387's can handle subnormals
495 SC18:   fptan                           ;
496         fstsw   AX                      ;
497         sahf                            ;
498         jnp     Clear1                  ; // C2 = 1 (x is out of range)
499 
500         // Do argument reduction to bring x into range
501         fldpi                           ;
502         fxch                            ;
503 SC17:   fprem1                          ;
504         fstsw   AX                      ;
505         sahf                            ;
506         jp      SC17                    ;
507         fstp    ST(1)                   ; // remove pi from stack
508         jmp     SC18                    ;
509 
510 trigerr:
511         jnp     Lret                    ; // if theta is NAN, return theta
512         fstp    ST(0)                   ; // dump theta
513     }
514     return real.nan;
515 
516 Clear1: asm pure nothrow @nogc{
517         fstp    ST(0)                   ; // dump X, which is always 1
518     }
519 
520 Lret: {}
521     }
522     else version (D_InlineAsm_X86_64)
523     {
524         version (Win64)
525         {
526             asm pure nothrow @nogc
527             {
528                 fld     real ptr [RCX]  ; // load theta
529             }
530         }
531         else
532         {
533             asm pure nothrow @nogc
534             {
535                 fld     x[RBP]          ; // load theta
536             }
537         }
538     asm pure nothrow @nogc
539     {
540         fxam                            ; // test for oddball values
541         fstsw   AX                      ;
542         test    AH,1                    ;
543         jnz     trigerr                 ; // x is NAN, infinity, or empty
544                                           // 387's can handle subnormals
545 SC18:   fptan                           ;
546         fstsw   AX                      ;
547         test    AH,4                    ;
548         jz      Clear1                  ; // C2 = 1 (x is out of range)
549 
550         // Do argument reduction to bring x into range
551         fldpi                           ;
552         fxch                            ;
553 SC17:   fprem1                          ;
554         fstsw   AX                      ;
555         test    AH,4                    ;
556         jnz     SC17                    ;
557         fstp    ST(1)                   ; // remove pi from stack
558         jmp     SC18                    ;
559 
560 trigerr:
561         test    AH,4                    ;
562         jz      Lret                    ; // if theta is NAN, return theta
563         fstp    ST(0)                   ; // dump theta
564     }
565     return real.nan;
566 
567 Clear1: asm pure nothrow @nogc{
568         fstp    ST(0)                   ; // dump X, which is always 1
569     }
570 
571 Lret: {}
572     }
573     else
574         static assert(0);
575 }
576 
577 private T tanImpl(T)(T x) @safe pure nothrow @nogc
578 {
579     // Coefficients for tan(x) and PI/4 split into three parts.
580     enum realFormat = floatTraits!T.realFormat;
581     static if (realFormat == RealFormat.ieeeQuadruple)
582     {
583         static immutable T[6] P = [
584             2.883414728874239697964612246732416606301E10L,
585             -2.307030822693734879744223131873392503321E9L,
586             5.160188250214037865511600561074819366815E7L,
587             -4.249691853501233575668486667664718192660E5L,
588             1.272297782199996882828849455156962260810E3L,
589             -9.889929415807650724957118893791829849557E-1L
590         ];
591         static immutable T[7] Q = [
592             8.650244186622719093893836740197250197602E10L,
593             -4.152206921457208101480801635640958361612E10L,
594             2.758476078803232151774723646710890525496E9L,
595             -5.733709132766856723608447733926138506824E7L,
596             4.529422062441341616231663543669583527923E5L,
597             -1.317243702830553658702531997959756728291E3L,
598             1.0
599         ];
600 
601         enum T P1 =
602             7.853981633974483067550664827649598009884357452392578125E-1L;
603         enum T P2 =
604             2.8605943630549158983813312792950660807511260829685741796657E-18L;
605         enum T P3 =
606             2.1679525325309452561992610065108379921905808E-35L;
607     }
608     else static if (realFormat == RealFormat.ieeeExtended ||
609                     realFormat == RealFormat.ieeeDouble)
610     {
611         static immutable T[3] P = [
612            -1.7956525197648487798769E7L,
613             1.1535166483858741613983E6L,
614            -1.3093693918138377764608E4L,
615         ];
616         static immutable T[5] Q = [
617            -5.3869575592945462988123E7L,
618             2.5008380182335791583922E7L,
619            -1.3208923444021096744731E6L,
620             1.3681296347069295467845E4L,
621             1.0000000000000000000000E0L,
622         ];
623 
624         enum T P1 = 7.853981554508209228515625E-1L;
625         enum T P2 = 7.946627356147928367136046290398E-9L;
626         enum T P3 = 3.061616997868382943065164830688E-17L;
627     }
628     else static if (realFormat == RealFormat.ieeeSingle)
629     {
630         static immutable T[6] P = [
631             3.33331568548E-1,
632             1.33387994085E-1,
633             5.34112807005E-2,
634             2.44301354525E-2,
635             3.11992232697E-3,
636             9.38540185543E-3,
637         ];
638 
639         enum T P1 = 0.78515625;
640         enum T P2 = 2.4187564849853515625E-4;
641         enum T P3 = 3.77489497744594108E-8;
642     }
643     else
644         static assert(0, "no coefficients for tan()");
645 
646     // Special cases.
647     if (x == cast(T) 0.0 || isNaN(x))
648         return x;
649     if (isInfinity(x))
650         return T.nan;
651 
652     // Make argument positive but save the sign.
653     bool sign = false;
654     if (signbit(x))
655     {
656         sign = true;
657         x = -x;
658     }
659 
660     // Compute x mod PI/4.
661     static if (realFormat == RealFormat.ieeeSingle)
662     {
663         enum T FOPI = 4 / PI;
664         int j = cast(int) (FOPI * x);
665         T y = j;
666         T z;
667     }
668     else
669     {
670         T y = floor(x / cast(T) PI_4);
671         // Strip high bits of integer part.
672         enum T highBitsFactor = (realFormat == RealFormat.ieeeDouble ? 0x1p3 : 0x1p4);
673         enum T highBitsInv = 1.0 / highBitsFactor;
674         T z = y * highBitsInv;
675         // Compute y - 2^numHighBits * (y / 2^numHighBits).
676         z = y - highBitsFactor * floor(z);
677 
678         // Integer and fraction part modulo one octant.
679         int j = cast(int)(z);
680     }
681 
682     // Map zeros and singularities to origin.
683     if (j & 1)
684     {
685         j += 1;
686         y += cast(T) 1.0;
687     }
688 
689     z = ((x - y * P1) - y * P2) - y * P3;
690     const T zz = z * z;
691 
692     enum T zzThreshold = (realFormat == RealFormat.ieeeSingle ? 1.0e-4L :
693                           realFormat == RealFormat.ieeeDouble ? 1.0e-14L : 1.0e-20L);
694     if (zz > zzThreshold)
695     {
696         static if (realFormat == RealFormat.ieeeSingle)
697             y = z + z * (zz * poly(zz, P));
698         else
699             y = z + z * (zz * poly(zz, P) / poly(zz, Q));
700     }
701     else
702         y = z;
703 
704     if (j & 2)
705         y = (cast(T) -1.0) / y;
706 
707     return (sign) ? -y : y;
708 }
709 
710 @safe @nogc nothrow unittest
711 {
712     static void testTan(T)()
713     {
714         // ±0
715         const T zero = 0.0;
716         assert(isIdentical(tan(zero), zero));
717         assert(isIdentical(tan(-zero), -zero));
718         // ±∞
719         const T inf = T.infinity;
720         assert(isNaN(tan(inf)));
721         assert(isNaN(tan(-inf)));
722         // NaN
723         const T specialNaN = NaN(0x0123L);
724         assert(isIdentical(tan(specialNaN), specialNaN));
725 
726         static immutable T[2][] vals =
727         [
728             // angle, tan
729             [   .5,  .5463024898],
730             [   1,   1.557407725],
731             [   1.5, 14.10141995],
732             [   2,  -2.185039863],
733             [   2.5,-.7470222972],
734             [   3,  -.1425465431],
735             [   3.5, .3745856402],
736             [   4,   1.157821282],
737             [   4.5, 4.637332055],
738             [   5,  -3.380515006],
739             [   5.5,-.9955840522],
740             [   6,  -.2910061914],
741             [   6.5, .2202772003],
742             [   10,  .6483608275],
743 
744             // special angles
745             [   PI_4,   1],
746             //[   PI_2,   T.infinity], // PI_2 is not _exactly_ pi/2.
747             [   3*PI_4, -1],
748             [   PI,     0],
749             [   5*PI_4, 1],
750             //[   3*PI_2, -T.infinity],
751             [   7*PI_4, -1],
752             [   2*PI,   0],
753          ];
754 
755         foreach (ref val; vals)
756         {
757             T x = val[0];
758             T r = val[1];
759             T t = tan(x);
760 
761             //printf("tan(%Lg) = %Lg, should be %Lg\n", cast(real) x, cast(real) t, cast(real) r);
762             assert(approxEqual(r, t));
763 
764             x = -x;
765             r = -r;
766             t = tan(x);
767             //printf("tan(%Lg) = %Lg, should be %Lg\n", cast(real) x, cast(real) t, cast(real) r);
768             assert(approxEqual(r, t));
769         }
770     }
771 
772     import std.meta : AliasSeq;
773     foreach (T; AliasSeq!(real, double, float))
774         testTan!T();
775 
776     assert(equalsDigit(tan(PI / 3), std.math.sqrt(3.0L), useDigits));
777 }
778 
779 /***************
780  * Calculates the arc cosine of x,
781  * returning a value ranging from 0 to $(PI).
782  *
783  *      $(TABLE_SV
784  *      $(TR $(TH x)         $(TH acos(x)) $(TH invalid?))
785  *      $(TR $(TD $(GT)1.0)  $(TD $(NAN))  $(TD yes))
786  *      $(TR $(TD $(LT)-1.0) $(TD $(NAN))  $(TD yes))
787  *      $(TR $(TD $(NAN))    $(TD $(NAN))  $(TD yes))
788  *  )
789  */
790 real acos(real x) @safe pure nothrow @nogc
791 {
792     return atan2(sqrt(1-x*x), x);
793 }
794 
795 /// ditto
796 double acos(double x) @safe pure nothrow @nogc { return acos(cast(real) x); }
797 
798 /// ditto
799 float acos(float x) @safe pure nothrow @nogc  { return acos(cast(real) x); }
800 
801 ///
802 @safe unittest
803 {
804     assert(acos(0.0).approxEqual(1.570));
805     assert(acos(0.5).approxEqual(std.math.PI / 3));
806     assert(acos(PI).isNaN);
807 }
808 
809 @safe @nogc nothrow unittest
810 {
811     assert(equalsDigit(acos(0.5), std.math.PI / 3, useDigits));
812 }
813 
814 /***************
815  * Calculates the arc sine of x,
816  * returning a value ranging from -$(PI)/2 to $(PI)/2.
817  *
818  *      $(TABLE_SV
819  *      $(TR $(TH x)            $(TH asin(x))      $(TH invalid?))
820  *      $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
821  *      $(TR $(TD $(GT)1.0)     $(TD $(NAN))       $(TD yes))
822  *      $(TR $(TD $(LT)-1.0)    $(TD $(NAN))       $(TD yes))
823  *  )
824  */
825 real asin(real x) @safe pure nothrow @nogc
826 {
827     return atan2(x, sqrt(1-x*x));
828 }
829 
830 /// ditto
831 double asin(double x) @safe pure nothrow @nogc { return asin(cast(real) x); }
832 
833 /// ditto
834 float asin(float x) @safe pure nothrow @nogc  { return asin(cast(real) x); }
835 
836 ///
837 @safe unittest
838 {
839     assert(isIdentical(asin(0.0), 0.0));
840     assert(asin(0.5).approxEqual(PI / 6));
841     assert(asin(PI).isNaN);
842 }
843 
844 @safe @nogc nothrow unittest
845 {
846     assert(equalsDigit(asin(0.5), PI / 6, useDigits));
847 }
848 
849 /***************
850  * Calculates the arc tangent of x,
851  * returning a value ranging from -$(PI)/2 to $(PI)/2.
852  *
853  *      $(TABLE_SV
854  *      $(TR $(TH x)                 $(TH atan(x))      $(TH invalid?))
855  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) $(TD no))
856  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN))       $(TD yes))
857  *  )
858  */
859 real atan(real x) @safe pure nothrow @nogc
860 {
861     version (InlineAsm_X86_Any)
862     {
863         if (!__ctfe)
864             return atan2Asm(x, 1.0L);
865     }
866     return atanImpl(x);
867 }
868 
869 /// ditto
870 double atan(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) atan(cast(real) x) : atanImpl(x); }
871 
872 /// ditto
873 float atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan(cast(real) x) : atanImpl(x); }
874 
875 ///
876 @safe unittest
877 {
878     assert(isIdentical(atan(0.0), 0.0));
879     assert(atan(sqrt(3.0)).approxEqual(PI / 3));
880 }
881 
882 private T atanImpl(T)(T x) @safe pure nothrow @nogc
883 {
884     // Coefficients for atan(x)
885     enum realFormat = floatTraits!T.realFormat;
886     static if (realFormat == RealFormat.ieeeQuadruple)
887     {
888         static immutable T[9] P = [
889             -6.880597774405940432145577545328795037141E2L,
890             -2.514829758941713674909996882101723647996E3L,
891             -3.696264445691821235400930243493001671932E3L,
892             -2.792272753241044941703278827346430350236E3L,
893             -1.148164399808514330375280133523543970854E3L,
894             -2.497759878476618348858065206895055957104E2L,
895             -2.548067867495502632615671450650071218995E1L,
896             -8.768423468036849091777415076702113400070E-1L,
897             -6.635810778635296712545011270011752799963E-4L
898         ];
899         static immutable T[9] Q = [
900             2.064179332321782129643673263598686441900E3L,
901             8.782996876218210302516194604424986107121E3L,
902             1.547394317752562611786521896296215170819E4L,
903             1.458510242529987155225086911411015961174E4L,
904             7.928572347062145288093560392463784743935E3L,
905             2.494680540950601626662048893678584497900E3L,
906             4.308348370818927353321556740027020068897E2L,
907             3.566239794444800849656497338030115886153E1L,
908             1.0
909         ];
910     }
911     else static if (realFormat == RealFormat.ieeeExtended)
912     {
913         static immutable T[5] P = [
914            -5.0894116899623603312185E1L,
915            -9.9988763777265819915721E1L,
916            -6.3976888655834347413154E1L,
917            -1.4683508633175792446076E1L,
918            -8.6863818178092187535440E-1L,
919         ];
920         static immutable T[6] Q = [
921             1.5268235069887081006606E2L,
922             3.9157570175111990631099E2L,
923             3.6144079386152023162701E2L,
924             1.4399096122250781605352E2L,
925             2.2981886733594175366172E1L,
926             1.0000000000000000000000E0L,
927         ];
928     }
929     else static if (realFormat == RealFormat.ieeeDouble)
930     {
931         static immutable T[5] P = [
932            -6.485021904942025371773E1L,
933            -1.228866684490136173410E2L,
934            -7.500855792314704667340E1L,
935            -1.615753718733365076637E1L,
936            -8.750608600031904122785E-1L,
937         ];
938         static immutable T[6] Q = [
939             1.945506571482613964425E2L,
940             4.853903996359136964868E2L,
941             4.328810604912902668951E2L,
942             1.650270098316988542046E2L,
943             2.485846490142306297962E1L,
944             1.000000000000000000000E0L,
945         ];
946 
947         enum T MOREBITS = 6.123233995736765886130E-17L;
948     }
949     else static if (realFormat == RealFormat.ieeeSingle)
950     {
951         static immutable T[4] P = [
952            -3.33329491539E-1,
953             1.99777106478E-1,
954            -1.38776856032E-1,
955             8.05374449538E-2,
956         ];
957     }
958     else
959         static assert(0, "no coefficients for atan()");
960 
961     // tan(PI/8)
962     enum T TAN_PI_8 = 0.414213562373095048801688724209698078569672L;
963     // tan(3 * PI/8)
964     enum T TAN3_PI_8 = 2.414213562373095048801688724209698078569672L;
965 
966     // Special cases.
967     if (x == cast(T) 0.0)
968         return x;
969     if (isInfinity(x))
970         return copysign(cast(T) PI_2, x);
971 
972     // Make argument positive but save the sign.
973     bool sign = false;
974     if (signbit(x))
975     {
976         sign = true;
977         x = -x;
978     }
979 
980     static if (realFormat == RealFormat.ieeeDouble) // special case for double precision
981     {
982         short flag = 0;
983         T y;
984         if (x > TAN3_PI_8)
985         {
986             y = PI_2;
987             flag = 1;
988             x = -(1.0 / x);
989         }
990         else if (x <= 0.66)
991         {
992             y = 0.0;
993         }
994         else
995         {
996             y = PI_4;
997             flag = 2;
998             x = (x - 1.0)/(x + 1.0);
999         }
1000 
1001         T z = x * x;
1002         z = z * poly(z, P) / poly(z, Q);
1003         z = x * z + x;
1004         if (flag == 2)
1005             z += 0.5 * MOREBITS;
1006         else if (flag == 1)
1007             z += MOREBITS;
1008         y = y + z;
1009     }
1010     else
1011     {
1012         // Range reduction.
1013         T y;
1014         if (x > TAN3_PI_8)
1015         {
1016             y = PI_2;
1017             x = -((cast(T) 1.0) / x);
1018         }
1019         else if (x > TAN_PI_8)
1020         {
1021             y = PI_4;
1022             x = (x - cast(T) 1.0)/(x + cast(T) 1.0);
1023         }
1024         else
1025             y = 0.0;
1026 
1027         // Rational form in x^^2.
1028         const T z = x * x;
1029         static if (realFormat == RealFormat.ieeeSingle)
1030             y += poly(z, P) * z * x + x;
1031         else
1032             y = y + (poly(z, P) / poly(z, Q)) * z * x + x;
1033     }
1034 
1035     return (sign) ? -y : y;
1036 }
1037 
1038 @safe @nogc nothrow unittest
1039 {
1040     static void testAtan(T)()
1041     {
1042         // ±0
1043         const T zero = 0.0;
1044         assert(isIdentical(atan(zero), zero));
1045         assert(isIdentical(atan(-zero), -zero));
1046         // ±∞
1047         const T inf = T.infinity;
1048         assert(approxEqual(atan(inf), cast(T) PI_2));
1049         assert(approxEqual(atan(-inf), cast(T) -PI_2));
1050         // NaN
1051         const T specialNaN = NaN(0x0123L);
1052         assert(isIdentical(atan(specialNaN), specialNaN));
1053 
1054         static immutable T[2][] vals =
1055         [
1056             // x, atan(x)
1057             [ 0.25, 0.2449786631 ],
1058             [ 0.5,  0.4636476090 ],
1059             [ 1,    PI_4         ],
1060             [ 1.5,  0.9827937232 ],
1061             [ 10,   1.4711276743 ],
1062         ];
1063 
1064         foreach (ref val; vals)
1065         {
1066             T x = val[0];
1067             T r = val[1];
1068             T a = atan(x);
1069 
1070             //printf("atan(%Lg) = %Lg, should be %Lg\n", cast(real) x, cast(real) a, cast(real) r);
1071             assert(approxEqual(r, a));
1072 
1073             x = -x;
1074             r = -r;
1075             a = atan(x);
1076             //printf("atan(%Lg) = %Lg, should be %Lg\n", cast(real) x, cast(real) a, cast(real) r);
1077             assert(approxEqual(r, a));
1078         }
1079     }
1080 
1081     import std.meta : AliasSeq;
1082     foreach (T; AliasSeq!(real, double, float))
1083         testAtan!T();
1084 
1085     assert(equalsDigit(atan(std.math.sqrt(3.0L)), PI / 3, useDigits));
1086 }
1087 
1088 /***************
1089  * Calculates the arc tangent of y / x,
1090  * returning a value ranging from -$(PI) to $(PI).
1091  *
1092  *      $(TABLE_SV
1093  *      $(TR $(TH y)                 $(TH x)            $(TH atan(y, x)))
1094  *      $(TR $(TD $(NAN))            $(TD anything)     $(TD $(NAN)) )
1095  *      $(TR $(TD anything)          $(TD $(NAN))       $(TD $(NAN)) )
1096  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(GT)0.0)     $(TD $(PLUSMN)0.0) )
1097  *      $(TR $(TD $(PLUSMN)0.0)      $(TD +0.0)         $(TD $(PLUSMN)0.0) )
1098  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(LT)0.0)     $(TD $(PLUSMN)$(PI)))
1099  *      $(TR $(TD $(PLUSMN)0.0)      $(TD -0.0)         $(TD $(PLUSMN)$(PI)))
1100  *      $(TR $(TD $(GT)0.0)          $(TD $(PLUSMN)0.0) $(TD $(PI)/2) )
1101  *      $(TR $(TD $(LT)0.0)          $(TD $(PLUSMN)0.0) $(TD -$(PI)/2) )
1102  *      $(TR $(TD $(GT)0.0)          $(TD $(INFIN))     $(TD $(PLUSMN)0.0) )
1103  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD anything)     $(TD $(PLUSMN)$(PI)/2))
1104  *      $(TR $(TD $(GT)0.0)          $(TD -$(INFIN))    $(TD $(PLUSMN)$(PI)) )
1105  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(INFIN))     $(TD $(PLUSMN)$(PI)/4))
1106  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD -$(INFIN))    $(TD $(PLUSMN)3$(PI)/4))
1107  *      )
1108  */
1109 real atan2(real y, real x) @trusted pure nothrow @nogc // TODO: @safe
1110 {
1111     version (InlineAsm_X86_Any)
1112     {
1113         if (!__ctfe)
1114             return atan2Asm(y, x);
1115     }
1116     return atan2Impl(y, x);
1117 }
1118 
1119 /// ditto
1120 double atan2(double y, double x) @safe pure nothrow @nogc
1121 {
1122     return __ctfe ? cast(double) atan2(cast(real) y, cast(real) x) : atan2Impl(y, x);
1123 }
1124 
1125 /// ditto
1126 float atan2(float y, float x) @safe pure nothrow @nogc
1127 {
1128     return __ctfe ? cast(float) atan2(cast(real) y, cast(real) x) : atan2Impl(y, x);
1129 }
1130 
1131 ///
1132 @safe unittest
1133 {
1134     assert(atan2(1.0, sqrt(3.0)).approxEqual(PI / 6));
1135 }
1136 
1137 version (InlineAsm_X86_Any)
1138 private real atan2Asm(real y, real x) @trusted pure nothrow @nogc
1139 {
1140     version (Win64)
1141     {
1142         asm pure nothrow @nogc {
1143             naked;
1144             fld real ptr [RDX]; // y
1145             fld real ptr [RCX]; // x
1146             fpatan;
1147             ret;
1148         }
1149     }
1150     else
1151     {
1152         asm pure nothrow @nogc {
1153             fld y;
1154             fld x;
1155             fpatan;
1156         }
1157     }
1158 }
1159 
1160 private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc
1161 {
1162     // Special cases.
1163     if (isNaN(x) || isNaN(y))
1164         return T.nan;
1165     if (y == cast(T) 0.0)
1166     {
1167         if (x >= 0 && !signbit(x))
1168             return copysign(0, y);
1169         else
1170             return copysign(cast(T) PI, y);
1171     }
1172     if (x == cast(T) 0.0)
1173         return copysign(cast(T) PI_2, y);
1174     if (isInfinity(x))
1175     {
1176         if (signbit(x))
1177         {
1178             if (isInfinity(y))
1179                 return copysign(3 * cast(T) PI_4, y);
1180             else
1181                 return copysign(cast(T) PI, y);
1182         }
1183         else
1184         {
1185             if (isInfinity(y))
1186                 return copysign(cast(T) PI_4, y);
1187             else
1188                 return copysign(cast(T) 0.0, y);
1189         }
1190     }
1191     if (isInfinity(y))
1192         return copysign(cast(T) PI_2, y);
1193 
1194     // Call atan and determine the quadrant.
1195     T z = atan(y / x);
1196 
1197     if (signbit(x))
1198     {
1199         if (signbit(y))
1200             z = z - cast(T) PI;
1201         else
1202             z = z + cast(T) PI;
1203     }
1204 
1205     if (z == cast(T) 0.0)
1206         return copysign(z, y);
1207 
1208     return z;
1209 }
1210 
1211 @safe @nogc nothrow unittest
1212 {
1213     static void testAtan2(T)()
1214     {
1215         // NaN
1216         const T nan = T.nan;
1217         assert(isNaN(atan2(nan, cast(T) 1)));
1218         assert(isNaN(atan2(cast(T) 1, nan)));
1219 
1220         const T inf = T.infinity;
1221         static immutable T[3][] vals =
1222         [
1223             // y, x, atan2(y, x)
1224 
1225             // ±0
1226             [  0.0,  1.0,  0.0 ],
1227             [ -0.0,  1.0, -0.0 ],
1228             [  0.0,  0.0,  0.0 ],
1229             [ -0.0,  0.0, -0.0 ],
1230             [  0.0, -1.0,  PI ],
1231             [ -0.0, -1.0, -PI ],
1232             [  0.0, -0.0,  PI ],
1233             [ -0.0, -0.0, -PI ],
1234             [  1.0,  0.0,  PI_2 ],
1235             [  1.0, -0.0,  PI_2 ],
1236             [ -1.0,  0.0, -PI_2 ],
1237             [ -1.0, -0.0, -PI_2 ],
1238 
1239             // ±∞
1240             [  1.0,  inf,  0.0 ],
1241             [ -1.0,  inf, -0.0 ],
1242             [  1.0, -inf,  PI ],
1243             [ -1.0, -inf, -PI ],
1244             [  inf,  1.0,  PI_2 ],
1245             [  inf, -1.0,  PI_2 ],
1246             [ -inf,  1.0, -PI_2 ],
1247             [ -inf, -1.0, -PI_2 ],
1248             [  inf,  inf,  PI_4 ],
1249             [ -inf,  inf, -PI_4 ],
1250             [  inf, -inf,  3 * PI_4 ],
1251             [ -inf, -inf, -3 * PI_4 ],
1252 
1253             [  1.0,  1.0,  PI_4 ],
1254             [ -2.0,  2.0, -PI_4 ],
1255             [  3.0, -3.0,  3 * PI_4 ],
1256             [ -4.0, -4.0, -3 * PI_4 ],
1257 
1258             [  0.75,  0.25,   1.249045772398 ],
1259             [ -0.5,   0.375, -0.927295218002 ],
1260             [  0.5,  -0.125,  1.815774989922 ],
1261             [ -0.75, -0.5,   -2.158798930342 ],
1262         ];
1263 
1264         foreach (ref val; vals)
1265         {
1266             const T y = val[0];
1267             const T x = val[1];
1268             const T r = val[2];
1269             const T a = atan2(y, x);
1270 
1271             //printf("atan2(%Lg, %Lg) = %Lg, should be %Lg\n", cast(real) y, cast(real) x, cast(real) a, cast(real) r);
1272             if (r == 0)
1273                 assert(isIdentical(r, a)); // check sign
1274             else
1275                 assert(approxEqual(r, a));
1276         }
1277     }
1278 
1279     import std.meta : AliasSeq;
1280     foreach (T; AliasSeq!(real, double, float))
1281         testAtan2!T();
1282 
1283     assert(equalsDigit(atan2(1.0L, std.math.sqrt(3.0L)), PI / 6, useDigits));
1284 }
1285 
1286 /***********************************
1287  * Calculates the hyperbolic cosine of x.
1288  *
1289  *      $(TABLE_SV
1290  *      $(TR $(TH x)                 $(TH cosh(x))      $(TH invalid?))
1291  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)0.0) $(TD no) )
1292  *      )
1293  */
1294 real cosh(real x) @safe pure nothrow @nogc
1295 {
1296     //  cosh = (exp(x)+exp(-x))/2.
1297     // The naive implementation works correctly.
1298     const real y = exp(x);
1299     return (y + 1.0/y) * 0.5;
1300 }
1301 
1302 /// ditto
1303 double cosh(double x) @safe pure nothrow @nogc { return cosh(cast(real) x); }
1304 
1305 /// ditto
1306 float cosh(float x) @safe pure nothrow @nogc  { return cosh(cast(real) x); }
1307 
1308 ///
1309 @safe unittest
1310 {
1311     assert(cosh(0.0) == 1.0);
1312     assert(cosh(1.0).approxEqual((E + 1.0 / E) / 2));
1313 }
1314 
1315 @safe @nogc nothrow unittest
1316 {
1317     assert(equalsDigit(cosh(1.0), (E + 1.0 / E) / 2, useDigits));
1318 }
1319 
1320 /***********************************
1321  * Calculates the hyperbolic sine of x.
1322  *
1323  *      $(TABLE_SV
1324  *      $(TR $(TH x)                 $(TH sinh(x))           $(TH invalid?))
1325  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0)      $(TD no))
1326  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no))
1327  *      )
1328  */
1329 real sinh(real x) @safe pure nothrow @nogc
1330 {
1331     //  sinh(x) =  (exp(x)-exp(-x))/2;
1332     // Very large arguments could cause an overflow, but
1333     // the maximum value of x for which exp(x) + exp(-x)) != exp(x)
1334     // is x = 0.5 * (real.mant_dig) * LN2. // = 22.1807 for real80.
1335     if (fabs(x) > real.mant_dig * LN2)
1336     {
1337         return copysign(0.5 * exp(fabs(x)), x);
1338     }
1339 
1340     const real y = expm1(x);
1341     return 0.5 * y / (y+1) * (y+2);
1342 }
1343 
1344 /// ditto
1345 double sinh(double x) @safe pure nothrow @nogc { return sinh(cast(real) x); }
1346 
1347 /// ditto
1348 float sinh(float x) @safe pure nothrow @nogc  { return sinh(cast(real) x); }
1349 
1350 ///
1351 @safe unittest
1352 {
1353     assert(isIdentical(sinh(0.0), 0.0));
1354     assert(sinh(1.0).approxEqual((E - 1.0 / E) / 2));
1355 }
1356 
1357 @safe @nogc nothrow unittest
1358 {
1359     assert(equalsDigit(sinh(1.0), (E - 1.0 / E) / 2, useDigits));
1360 }
1361 
1362 /***********************************
1363  * Calculates the hyperbolic tangent of x.
1364  *
1365  *      $(TABLE_SV
1366  *      $(TR $(TH x)                 $(TH tanh(x))      $(TH invalid?))
1367  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) $(TD no) )
1368  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)1.0) $(TD no))
1369  *      )
1370  */
1371 real tanh(real x) @safe pure nothrow @nogc
1372 {
1373     //  tanh(x) = (exp(x) - exp(-x))/(exp(x)+exp(-x))
1374     if (fabs(x) > real.mant_dig * LN2)
1375     {
1376         return copysign(1, x);
1377     }
1378 
1379     const real y = expm1(2*x);
1380     return y / (y + 2);
1381 }
1382 
1383 /// ditto
1384 double tanh(double x) @safe pure nothrow @nogc { return tanh(cast(real) x); }
1385 
1386 /// ditto
1387 float tanh(float x) @safe pure nothrow @nogc { return tanh(cast(real) x); }
1388 
1389 ///
1390 @safe unittest
1391 {
1392     assert(isIdentical(tanh(0.0), 0.0));
1393     assert(tanh(1.0).approxEqual(sinh(1.0) / cosh(1.0)));
1394 }
1395 
1396 @safe @nogc nothrow unittest
1397 {
1398     assert(equalsDigit(tanh(1.0), sinh(1.0) / cosh(1.0), 15));
1399 }
1400 
1401 /***********************************
1402  * Calculates the inverse hyperbolic cosine of x.
1403  *
1404  *  Mathematically, acosh(x) = log(x + sqrt( x*x - 1))
1405  *
1406  * $(TABLE_DOMRG
1407  *    $(DOMAIN 1..$(INFIN)),
1408  *    $(RANGE  0..$(INFIN))
1409  * )
1410  *
1411  *  $(TABLE_SV
1412  *    $(SVH  x,     acosh(x) )
1413  *    $(SV  $(NAN), $(NAN) )
1414  *    $(SV  $(LT)1,     $(NAN) )
1415  *    $(SV  1,      0       )
1416  *    $(SV  +$(INFIN),+$(INFIN))
1417  *  )
1418  */
1419 real acosh(real x) @safe pure nothrow @nogc
1420 {
1421     if (x > 1/real.epsilon)
1422         return LN2 + log(x);
1423     else
1424         return log(x + sqrt(x*x - 1));
1425 }
1426 
1427 /// ditto
1428 double acosh(double x) @safe pure nothrow @nogc { return acosh(cast(real) x); }
1429 
1430 /// ditto
1431 float acosh(float x) @safe pure nothrow @nogc  { return acosh(cast(real) x); }
1432 
1433 ///
1434 @safe @nogc nothrow unittest
1435 {
1436     assert(isNaN(acosh(0.9)));
1437     assert(isNaN(acosh(real.nan)));
1438     assert(isIdentical(acosh(1.0), 0.0));
1439     assert(acosh(real.infinity) == real.infinity);
1440     assert(isNaN(acosh(0.5)));
1441 }
1442 
1443 @safe @nogc nothrow unittest
1444 {
1445     assert(equalsDigit(acosh(cosh(3.0)), 3, useDigits));
1446 }
1447 
1448 /***********************************
1449  * Calculates the inverse hyperbolic sine of x.
1450  *
1451  *  Mathematically,
1452  *  ---------------
1453  *  asinh(x) =  log( x + sqrt( x*x + 1 )) // if x >= +0
1454  *  asinh(x) = -log(-x + sqrt( x*x + 1 )) // if x <= -0
1455  *  -------------
1456  *
1457  *    $(TABLE_SV
1458  *    $(SVH x,                asinh(x)       )
1459  *    $(SV  $(NAN),           $(NAN)         )
1460  *    $(SV  $(PLUSMN)0,       $(PLUSMN)0      )
1461  *    $(SV  $(PLUSMN)$(INFIN),$(PLUSMN)$(INFIN))
1462  *    )
1463  */
1464 real asinh(real x) @safe pure nothrow @nogc
1465 {
1466     return (fabs(x) > 1 / real.epsilon)
1467        // beyond this point, x*x + 1 == x*x
1468        ?  copysign(LN2 + log(fabs(x)), x)
1469        // sqrt(x*x + 1) ==  1 + x * x / ( 1 + sqrt(x*x + 1) )
1470        : copysign(log1p(fabs(x) + x*x / (1 + sqrt(x*x + 1)) ), x);
1471 }
1472 
1473 /// ditto
1474 double asinh(double x) @safe pure nothrow @nogc { return asinh(cast(real) x); }
1475 
1476 /// ditto
1477 float asinh(float x) @safe pure nothrow @nogc { return asinh(cast(real) x); }
1478 
1479 ///
1480 @safe @nogc nothrow unittest
1481 {
1482     assert(isIdentical(asinh(0.0), 0.0));
1483     assert(isIdentical(asinh(-0.0), -0.0));
1484     assert(asinh(real.infinity) == real.infinity);
1485     assert(asinh(-real.infinity) == -real.infinity);
1486     assert(isNaN(asinh(real.nan)));
1487 }
1488 
1489 @safe unittest
1490 {
1491     assert(equalsDigit(asinh(sinh(3.0)), 3, useDigits));
1492 }
1493 
1494 /***********************************
1495  * Calculates the inverse hyperbolic tangent of x,
1496  * returning a value from ranging from -1 to 1.
1497  *
1498  * Mathematically, atanh(x) = log( (1+x)/(1-x) ) / 2
1499  *
1500  * $(TABLE_DOMRG
1501  *    $(DOMAIN -$(INFIN)..$(INFIN)),
1502  *    $(RANGE  -1 .. 1)
1503  * )
1504  * $(BR)
1505  * $(TABLE_SV
1506  *    $(SVH  x,     acosh(x) )
1507  *    $(SV  $(NAN), $(NAN) )
1508  *    $(SV  $(PLUSMN)0, $(PLUSMN)0)
1509  *    $(SV  -$(INFIN), -0)
1510  * )
1511  */
1512 real atanh(real x) @safe pure nothrow @nogc
1513 {
1514     // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) )
1515     return  0.5 * log1p( 2 * x / (1 - x) );
1516 }
1517 
1518 /// ditto
1519 double atanh(double x) @safe pure nothrow @nogc { return atanh(cast(real) x); }
1520 
1521 /// ditto
1522 float atanh(float x) @safe pure nothrow @nogc { return atanh(cast(real) x); }
1523 
1524 ///
1525 @safe @nogc nothrow unittest
1526 {
1527     assert(isIdentical(atanh(0.0), 0.0));
1528     assert(isIdentical(atanh(-0.0),-0.0));
1529     assert(isNaN(atanh(real.nan)));
1530     assert(isNaN(atanh(-real.infinity)));
1531     assert(atanh(0.0) == 0);
1532 }
1533 
1534 @safe unittest
1535 {
1536     assert(equalsDigit(atanh(tanh(0.5L)), 0.5, useDigits));
1537 }
1538 
1539 /*****************************************
1540  * Returns x rounded to a long value using the current rounding mode.
1541  * If the integer value of x is
1542  * greater than long.max, the result is
1543  * indeterminate.
1544  */
1545 long rndtol(real x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.rndtol(x); }
1546 //FIXME
1547 ///ditto
1548 long rndtol(double x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }
1549 //FIXME
1550 ///ditto
1551 long rndtol(float x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }
1552 
1553 ///
1554 @safe unittest
1555 {
1556     assert(rndtol(1.0) == 1L);
1557     assert(rndtol(1.2) == 1L);
1558     assert(rndtol(1.7) == 2L);
1559     assert(rndtol(1.0001) == 1L);
1560 }
1561 
1562 @safe unittest
1563 {
1564     long function(real) prndtol = &rndtol;
1565     assert(prndtol != null);
1566 }
1567 
1568 /**
1569 $(RED Deprecated. Please use $(LREF round) instead.)
1570 
1571 Returns `x` rounded to a `long` value using the `FE_TONEAREST` rounding mode.
1572 If the integer value of `x` is greater than `long.max`, the result is
1573 indeterminate.
1574 
1575 Only works with the Digital Mars C Runtime.
1576 
1577 Params:
1578     x = the number to round
1579 Returns:
1580     `x` rounded to an integer value
1581  */
1582 deprecated("rndtonl is to be removed by 2.089. Please use round instead")
1583 extern (C) real rndtonl(real x);
1584 
1585 ///
1586 deprecated @system unittest
1587 {
1588     version (CRuntime_DigitalMars)
1589     {
1590         assert(rndtonl(1.0) is -real.nan);
1591         assert(rndtonl(1.2) is -real.nan);
1592         assert(rndtonl(1.7) is -real.nan);
1593         assert(rndtonl(1.0001) is -real.nan);
1594     }
1595 }
1596 
1597 /***************************************
1598  * Compute square root of x.
1599  *
1600  *      $(TABLE_SV
1601  *      $(TR $(TH x)         $(TH sqrt(x))   $(TH invalid?))
1602  *      $(TR $(TD -0.0)      $(TD -0.0)      $(TD no))
1603  *      $(TR $(TD $(LT)0.0)  $(TD $(NAN))    $(TD yes))
1604  *      $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no))
1605  *      )
1606  */
1607 float sqrt(float x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }
1608 
1609 /// ditto
1610 double sqrt(double x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }
1611 
1612 /// ditto
1613 real sqrt(real x) @nogc @safe pure nothrow { pragma(inline, true); return core.math.sqrt(x); }
1614 
1615 ///
1616 @safe pure nothrow @nogc unittest
1617 {
1618     assert(sqrt(2.0).feqrel(1.4142) > 16);
1619     assert(sqrt(9.0).feqrel(3.0) > 16);
1620 
1621     assert(isNaN(sqrt(-1.0f)));
1622     assert(isNaN(sqrt(-1.0)));
1623     assert(isNaN(sqrt(-1.0L)));
1624 }
1625 
1626 @safe unittest
1627 {
1628     float function(float) psqrtf = &sqrt;
1629     assert(psqrtf != null);
1630     double function(double) psqrtd = &sqrt;
1631     assert(psqrtd != null);
1632     real function(real) psqrtr = &sqrt;
1633     assert(psqrtr != null);
1634 
1635     //ctfe
1636     enum ZX80 = sqrt(7.0f);
1637     enum ZX81 = sqrt(7.0);
1638     enum ZX82 = sqrt(7.0L);
1639 }
1640 
1641 /**
1642  * Calculates e$(SUPERSCRIPT x).
1643  *
1644  *  $(TABLE_SV
1645  *    $(TR $(TH x)             $(TH e$(SUPERSCRIPT x)) )
1646  *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN)) )
1647  *    $(TR $(TD -$(INFIN))     $(TD +0.0)      )
1648  *    $(TR $(TD $(NAN))        $(TD $(NAN))    )
1649  *  )
1650  */
1651 real exp(real x) @trusted pure nothrow @nogc // TODO: @safe
1652 {
1653     version (D_InlineAsm_X86)
1654     {
1655         //  e^^x = 2^^(LOG2E*x)
1656         // (This is valid because the overflow & underflow limits for exp
1657         // and exp2 are so similar).
1658         if (!__ctfe)
1659             return exp2Asm(LOG2E*x);
1660     }
1661     else version (D_InlineAsm_X86_64)
1662     {
1663         //  e^^x = 2^^(LOG2E*x)
1664         // (This is valid because the overflow & underflow limits for exp
1665         // and exp2 are so similar).
1666         if (!__ctfe)
1667             return exp2Asm(LOG2E*x);
1668     }
1669     return expImpl(x);
1670 }
1671 
1672 /// ditto
1673 double exp(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) exp(cast(real) x) : expImpl(x); }
1674 
1675 /// ditto
1676 float exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(cast(real) x) : expImpl(x); }
1677 
1678 ///
1679 @safe unittest
1680 {
1681     assert(exp(0.0) == 1.0);
1682     assert(exp(3.0).feqrel(E * E * E) > 16);
1683 }
1684 
1685 private T expImpl(T)(T x) @safe pure nothrow @nogc
1686 {
1687     alias F = floatTraits!T;
1688     static if (F.realFormat == RealFormat.ieeeSingle)
1689     {
1690         static immutable T[6] P = [
1691             5.0000001201E-1,
1692             1.6666665459E-1,
1693             4.1665795894E-2,
1694             8.3334519073E-3,
1695             1.3981999507E-3,
1696             1.9875691500E-4,
1697         ];
1698 
1699         enum T C1 = 0.693359375;
1700         enum T C2 = -2.12194440e-4;
1701 
1702         // Overflow and Underflow limits.
1703         enum T OF = 88.72283905206835;
1704         enum T UF = -103.278929903431851103; // ln(2^-149)
1705     }
1706     else static if (F.realFormat == RealFormat.ieeeDouble)
1707     {
1708         // Coefficients for exp(x)
1709         static immutable T[3] P = [
1710             9.99999999999999999910E-1L,
1711             3.02994407707441961300E-2L,
1712             1.26177193074810590878E-4L,
1713         ];
1714         static immutable T[4] Q = [
1715             2.00000000000000000009E0L,
1716             2.27265548208155028766E-1L,
1717             2.52448340349684104192E-3L,
1718             3.00198505138664455042E-6L,
1719         ];
1720 
1721         // C1 + C2 = LN2.
1722         enum T C1 = 6.93145751953125E-1;
1723         enum T C2 = 1.42860682030941723212E-6;
1724 
1725         // Overflow and Underflow limits.
1726         enum T OF =  7.09782712893383996732E2;  // ln((1-2^-53) * 2^1024)
1727         enum T UF = -7.451332191019412076235E2; // ln(2^-1075)
1728     }
1729     else static if (F.realFormat == RealFormat.ieeeExtended)
1730     {
1731         // Coefficients for exp(x)
1732         static immutable T[3] P = [
1733             9.9999999999999999991025E-1L,
1734             3.0299440770744196129956E-2L,
1735             1.2617719307481059087798E-4L,
1736         ];
1737         static immutable T[4] Q = [
1738             2.0000000000000000000897E0L,
1739             2.2726554820815502876593E-1L,
1740             2.5244834034968410419224E-3L,
1741             3.0019850513866445504159E-6L,
1742         ];
1743 
1744         // C1 + C2 = LN2.
1745         enum T C1 = 6.9314575195312500000000E-1L;
1746         enum T C2 = 1.4286068203094172321215E-6L;
1747 
1748         // Overflow and Underflow limits.
1749         enum T OF =  1.1356523406294143949492E4L;  // ln((1-2^-64) * 2^16384)
1750         enum T UF = -1.13994985314888605586758E4L; // ln(2^-16446)
1751     }
1752     else static if (F.realFormat == RealFormat.ieeeQuadruple)
1753     {
1754         // Coefficients for exp(x) - 1
1755         static immutable T[5] P = [
1756             9.999999999999999999999999999999999998502E-1L,
1757             3.508710990737834361215404761139478627390E-2L,
1758             2.708775201978218837374512615596512792224E-4L,
1759             6.141506007208645008909088812338454698548E-7L,
1760             3.279723985560247033712687707263393506266E-10L
1761         ];
1762         static immutable T[6] Q = [
1763             2.000000000000000000000000000000000000150E0,
1764             2.368408864814233538909747618894558968880E-1L,
1765             3.611828913847589925056132680618007270344E-3L,
1766             1.504792651814944826817779302637284053660E-5L,
1767             1.771372078166251484503904874657985291164E-8L,
1768             2.980756652081995192255342779918052538681E-12L
1769         ];
1770 
1771         // C1 + C2 = LN2.
1772         enum T C1 = 6.93145751953125E-1L;
1773         enum T C2 = 1.428606820309417232121458176568075500134E-6L;
1774 
1775         // Overflow and Underflow limits.
1776         enum T OF =  1.135583025911358400418251384584930671458833e4L;
1777         enum T UF = -1.143276959615573793352782661133116431383730e4L;
1778     }
1779     else
1780         static assert(0, "Not implemented for this architecture");
1781 
1782     // Special cases.
1783     if (isNaN(x))
1784         return x;
1785     if (x > OF)
1786         return real.infinity;
1787     if (x < UF)
1788         return 0.0;
1789 
1790     // Express: e^^x = e^^g * 2^^n
1791     //   = e^^g * e^^(n * LOG2E)
1792     //   = e^^(g + n * LOG2E)
1793     T xx = floor((cast(T) LOG2E) * x + cast(T) 0.5);
1794     const int n = cast(int) xx;
1795     x -= xx * C1;
1796     x -= xx * C2;
1797 
1798     static if (F.realFormat == RealFormat.ieeeSingle)
1799     {
1800         xx = x * x;
1801         x = poly(x, P) * xx + x + 1.0f;
1802     }
1803     else
1804     {
1805         // Rational approximation for exponential of the fractional part:
1806         //  e^^x = 1 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))
1807         xx = x * x;
1808         const T px = x * poly(xx, P);
1809         x = px / (poly(xx, Q) - px);
1810         x = (cast(T) 1.0) + (cast(T) 2.0) * x;
1811     }
1812 
1813     // Scale by power of 2.
1814     x = ldexp(x, n);
1815 
1816     return x;
1817 }
1818 
1819 @safe @nogc nothrow unittest
1820 {
1821     version (FloatingPointControlSupport)
1822     {
1823         FloatingPointControl ctrl;
1824         if (FloatingPointControl.hasExceptionTraps)
1825             ctrl.disableExceptions(FloatingPointControl.allExceptions);
1826         ctrl.rounding = FloatingPointControl.roundToNearest;
1827     }
1828 
1829     static void testExp(T)()
1830     {
1831         enum realFormat = floatTraits!T.realFormat;
1832         static if (realFormat == RealFormat.ieeeQuadruple)
1833         {
1834             static immutable T[2][] exptestpoints =
1835             [ //  x               exp(x)
1836                 [ 1.0L,           E                                        ],
1837                 [ 0.5L,           0x1.a61298e1e069bc972dfefab6df34p+0L     ],
1838                 [ 3.0L,           E*E*E                                    ],
1839                 [ 0x1.6p+13L,     0x1.6e509d45728655cdb4840542acb5p+16250L ], // near overflow
1840                 [ 0x1.7p+13L,     T.infinity                               ], // close overflow
1841                 [ 0x1p+80L,       T.infinity                               ], // far overflow
1842                 [ T.infinity,     T.infinity                               ],
1843                 [-0x1.18p+13L,    0x1.5e4bf54b4807034ea97fef0059a6p-12927L ], // near underflow
1844                 [-0x1.625p+13L,   0x1.a6bd68a39d11fec3a250cd97f524p-16358L ], // ditto
1845                 [-0x1.62dafp+13L, 0x0.cb629e9813b80ed4d639e875be6cp-16382L ], // near underflow - subnormal
1846                 [-0x1.6549p+13L,  0x0.0000000000000000000000000001p-16382L ], // ditto
1847                 [-0x1.655p+13L,   0                                        ], // close underflow
1848                 [-0x1p+30L,       0                                        ], // far underflow
1849             ];
1850         }
1851         else static if (realFormat == RealFormat.ieeeExtended)
1852         {
1853             static immutable T[2][] exptestpoints =
1854             [ //  x               exp(x)
1855                 [ 1.0L,           E                            ],
1856                 [ 0.5L,           0x1.a61298e1e069bc97p+0L     ],
1857                 [ 3.0L,           E*E*E                        ],
1858                 [ 0x1.1p+13L,     0x1.29aeffefc8ec645p+12557L  ], // near overflow
1859                 [ 0x1.7p+13L,     T.infinity                   ], // close overflow
1860                 [ 0x1p+80L,       T.infinity                   ], // far overflow
1861                 [ T.infinity,     T.infinity                   ],
1862                 [-0x1.18p+13L,    0x1.5e4bf54b4806db9p-12927L  ], // near underflow
1863                 [-0x1.625p+13L,   0x1.a6bd68a39d11f35cp-16358L ], // ditto
1864                 [-0x1.62dafp+13L, 0x1.96c53d30277021dp-16383L  ], // near underflow - subnormal
1865                 [-0x1.643p+13L,   0x1p-16444L                  ], // ditto
1866                 [-0x1.645p+13L,   0                            ], // close underflow
1867                 [-0x1p+30L,       0                            ], // far underflow
1868             ];
1869         }
1870         else static if (realFormat == RealFormat.ieeeDouble)
1871         {
1872             static immutable T[2][] exptestpoints =
1873             [ //  x,             exp(x)
1874                 [ 1.0L,          E                        ],
1875                 [ 0.5L,          0x1.a61298e1e069cp+0L    ],
1876                 [ 3.0L,          E*E*E                    ],
1877                 [ 0x1.6p+9L,     0x1.93bf4ec282efbp+1015L ], // near overflow
1878                 [ 0x1.7p+9L,     T.infinity               ], // close overflow
1879                 [ 0x1p+80L,      T.infinity               ], // far overflow
1880                 [ T.infinity,    T.infinity               ],
1881                 [-0x1.6p+9L,     0x1.44a3824e5285fp-1016L ], // near underflow
1882                 [-0x1.64p+9L,    0x0.06f84920bb2d4p-1022L ], // near underflow - subnormal
1883                 [-0x1.743p+9L,   0x0.0000000000001p-1022L ], // ditto
1884                 [-0x1.8p+9L,     0                        ], // close underflow
1885                 [-0x1p+30L,      0                        ], // far underflow
1886             ];
1887         }
1888         else static if (realFormat == RealFormat.ieeeSingle)
1889         {
1890             static immutable T[2][] exptestpoints =
1891             [ //  x,             exp(x)
1892                 [ 1.0L,          E                ],
1893                 [ 0.5L,          0x1.a61299p+0L   ],
1894                 [ 3.0L,          E*E*E            ],
1895                 [ 0x1.62p+6L,    0x1.99b988p+127L ], // near overflow
1896                 [ 0x1.7p+6L,     T.infinity       ], // close overflow
1897                 [ 0x1p+80L,      T.infinity       ], // far overflow
1898                 [ T.infinity,    T.infinity       ],
1899                 [-0x1.5cp+6L,    0x1.666d0ep-126L ], // near underflow
1900                 [-0x1.7p+6L,     0x0.026a42p-126L ], // near underflow - subnormal
1901                 [-0x1.9cp+6L,    0x0.000002p-126L ], // ditto
1902                 [-0x1.ap+6L,     0                ], // close underflow
1903                 [-0x1p+30L,      0                ], // far underflow
1904             ];
1905         }
1906         else
1907             static assert(0, "No exp() tests for real type!");
1908 
1909         const minEqualMantissaBits = T.mant_dig - 2;
1910         T x;
1911         version (IeeeFlagsSupport) IeeeFlags f;
1912         foreach (ref pair; exptestpoints)
1913         {
1914             version (IeeeFlagsSupport) resetIeeeFlags();
1915             x = exp(pair[0]);
1916             //printf("exp(%La) = %La, should be %La\n", cast(real) pair[0], cast(real) x, cast(real) pair[1]);
1917             assert(feqrel(x, pair[1]) >= minEqualMantissaBits);
1918         }
1919 
1920         // Ideally, exp(0) would not set the inexact flag.
1921         // Unfortunately, fldl2e sets it!
1922         // So it's not realistic to avoid setting it.
1923         assert(exp(cast(T) 0.0) == 1.0);
1924 
1925         // NaN propagation. Doesn't set flags, bcos was already NaN.
1926         version (IeeeFlagsSupport)
1927         {
1928             resetIeeeFlags();
1929             x = exp(T.nan);
1930             f = ieeeFlags;
1931             assert(isIdentical(abs(x), T.nan));
1932             assert(f.flags == 0);
1933 
1934             resetIeeeFlags();
1935             x = exp(-T.nan);
1936             f = ieeeFlags;
1937             assert(isIdentical(abs(x), T.nan));
1938             assert(f.flags == 0);
1939         }
1940         else
1941         {
1942             x = exp(T.nan);
1943             assert(isIdentical(abs(x), T.nan));
1944 
1945             x = exp(-T.nan);
1946             assert(isIdentical(abs(x), T.nan));
1947         }
1948 
1949         x = exp(NaN(0x123));
1950         assert(isIdentical(x, NaN(0x123)));
1951     }
1952 
1953     import std.meta : AliasSeq;
1954     foreach (T; AliasSeq!(real, double, float))
1955         testExp!T();
1956 
1957     // High resolution test (verified against GNU MPFR/Mathematica).
1958     assert(exp(0.5L) == 0x1.A612_98E1_E069_BC97_2DFE_FAB6_DF34p+0L);
1959 
1960     assert(equalsDigit(exp(3.0L), E * E * E, useDigits));
1961 }
1962 
1963 /**
1964  * Calculates the value of the natural logarithm base (e)
1965  * raised to the power of x, minus 1.
1966  *
1967  * For very small x, expm1(x) is more accurate
1968  * than exp(x)-1.
1969  *
1970  *  $(TABLE_SV
1971  *    $(TR $(TH x)             $(TH e$(SUPERSCRIPT x)-1)  )
1972  *    $(TR $(TD $(PLUSMN)0.0)  $(TD $(PLUSMN)0.0) )
1973  *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN))    )
1974  *    $(TR $(TD -$(INFIN))     $(TD -1.0)         )
1975  *    $(TR $(TD $(NAN))        $(TD $(NAN))       )
1976  *  )
1977  */
1978 real expm1(real x) @trusted pure nothrow @nogc // TODO: @safe
1979 {
1980     version (InlineAsm_X86_Any)
1981     {
1982         if (!__ctfe)
1983             return expm1Asm(x);
1984     }
1985     return expm1Impl(x);
1986 }
1987 
1988 /// ditto
1989 double expm1(double x) @safe pure nothrow @nogc
1990 {
1991     return __ctfe ? cast(double) expm1(cast(real) x) : expm1Impl(x);
1992 }
1993 
1994 /// ditto
1995 float expm1(float x) @safe pure nothrow @nogc
1996 {
1997     // no single-precision version in Cephes => use double precision
1998     return __ctfe ? cast(float) expm1(cast(real) x) : cast(float) expm1Impl(cast(double) x);
1999 }
2000 
2001 ///
2002 @safe unittest
2003 {
2004     assert(isIdentical(expm1(0.0), 0.0));
2005     assert(expm1(1.0).feqrel(1.71828) > 16);
2006     assert(expm1(2.0).feqrel(6.3890) > 16);
2007 }
2008 
2009 version (InlineAsm_X86_Any)
2010 private real expm1Asm(real x) @trusted pure nothrow @nogc
2011 {
2012     version (D_InlineAsm_X86)
2013     {
2014         enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4
2015         asm pure nothrow @nogc
2016         {
2017             /*  expm1() for x87 80-bit reals, IEEE754-2008 conformant.
2018              * Author: Don Clugston.
2019              *
2020              *    expm1(x) = 2^^(rndint(y))* 2^^(y-rndint(y)) - 1 where y = LN2*x.
2021              *    = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^^(rndint(y))
2022              *     and 2ym1 = (2^^(y-rndint(y))-1).
2023              *    If 2rndy  < 0.5*real.epsilon, result is -1.
2024              *    Implementation is otherwise the same as for exp2()
2025              */
2026             naked;
2027             fld real ptr [ESP+4] ; // x
2028             mov AX, [ESP+4+8]; // AX = exponent and sign
2029             sub ESP, 12+8; // Create scratch space on the stack
2030             // [ESP,ESP+2] = scratchint
2031             // [ESP+4..+6, +8..+10, +10] = scratchreal
2032             // set scratchreal mantissa = 1.0
2033             mov dword ptr [ESP+8], 0;
2034             mov dword ptr [ESP+8+4], 0x80000000;
2035             and AX, 0x7FFF; // drop sign bit
2036             cmp AX, 0x401D; // avoid InvalidException in fist
2037             jae L_extreme;
2038             fldl2e;
2039             fmulp ST(1), ST; // y = x*log2(e)
2040             fist dword ptr [ESP]; // scratchint = rndint(y)
2041             fisub dword ptr [ESP]; // y - rndint(y)
2042             // and now set scratchreal exponent
2043             mov EAX, [ESP];
2044             add EAX, 0x3fff;
2045             jle short L_largenegative;
2046             cmp EAX,0x8000;
2047             jge short L_largepositive;
2048             mov [ESP+8+8],AX;
2049             f2xm1; // 2ym1 = 2^^(y-rndint(y)) -1
2050             fld real ptr [ESP+8] ; // 2rndy = 2^^rndint(y)
2051             fmul ST(1), ST;  // ST=2rndy, ST(1)=2rndy*2ym1
2052             fld1;
2053             fsubp ST(1), ST; // ST = 2rndy-1, ST(1) = 2rndy * 2ym1 - 1
2054             faddp ST(1), ST; // ST = 2rndy * 2ym1 + 2rndy - 1
2055             add ESP,12+8;
2056             ret PARAMSIZE;
2057 
2058 L_extreme:  // Extreme exponent. X is very large positive, very
2059             // large negative, infinity, or NaN.
2060             fxam;
2061             fstsw AX;
2062             test AX, 0x0400; // NaN_or_zero, but we already know x != 0
2063             jz L_was_nan;  // if x is NaN, returns x
2064             test AX, 0x0200;
2065             jnz L_largenegative;
2066 L_largepositive:
2067             // Set scratchreal = real.max.
2068             // squaring it will create infinity, and set overflow flag.
2069             mov word  ptr [ESP+8+8], 0x7FFE;
2070             fstp ST(0);
2071             fld real ptr [ESP+8];  // load scratchreal
2072             fmul ST(0), ST;        // square it, to create havoc!
2073 L_was_nan:
2074             add ESP,12+8;
2075             ret PARAMSIZE;
2076 L_largenegative:
2077             fstp ST(0);
2078             fld1;
2079             fchs; // return -1. Underflow flag is not set.
2080             add ESP,12+8;
2081             ret PARAMSIZE;
2082         }
2083     }
2084     else version (D_InlineAsm_X86_64)
2085     {
2086         asm pure nothrow @nogc
2087         {
2088             naked;
2089         }
2090         version (Win64)
2091         {
2092             asm pure nothrow @nogc
2093             {
2094                 fld   real ptr [RCX];  // x
2095                 mov   AX,[RCX+8];      // AX = exponent and sign
2096             }
2097         }
2098         else
2099         {
2100             asm pure nothrow @nogc
2101             {
2102                 fld   real ptr [RSP+8];  // x
2103                 mov   AX,[RSP+8+8];      // AX = exponent and sign
2104             }
2105         }
2106         asm pure nothrow @nogc
2107         {
2108             /*  expm1() for x87 80-bit reals, IEEE754-2008 conformant.
2109              * Author: Don Clugston.
2110              *
2111              *    expm1(x) = 2^(rndint(y))* 2^(y-rndint(y)) - 1 where y = LN2*x.
2112              *    = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^(rndint(y))
2113              *     and 2ym1 = (2^(y-rndint(y))-1).
2114              *    If 2rndy  < 0.5*real.epsilon, result is -1.
2115              *    Implementation is otherwise the same as for exp2()
2116              */
2117             sub RSP, 24;       // Create scratch space on the stack
2118             // [RSP,RSP+2] = scratchint
2119             // [RSP+4..+6, +8..+10, +10] = scratchreal
2120             // set scratchreal mantissa = 1.0
2121             mov dword ptr [RSP+8], 0;
2122             mov dword ptr [RSP+8+4], 0x80000000;
2123             and AX, 0x7FFF; // drop sign bit
2124             cmp AX, 0x401D; // avoid InvalidException in fist
2125             jae L_extreme;
2126             fldl2e;
2127             fmul ; // y = x*log2(e)
2128             fist dword ptr [RSP]; // scratchint = rndint(y)
2129             fisub dword ptr [RSP]; // y - rndint(y)
2130             // and now set scratchreal exponent
2131             mov EAX, [RSP];
2132             add EAX, 0x3fff;
2133             jle short L_largenegative;
2134             cmp EAX,0x8000;
2135             jge short L_largepositive;
2136             mov [RSP+8+8],AX;
2137             f2xm1; // 2^(y-rndint(y)) -1
2138             fld real ptr [RSP+8] ; // 2^rndint(y)
2139             fmul ST(1), ST;
2140             fld1;
2141             fsubp ST(1), ST;
2142             fadd;
2143             add RSP,24;
2144             ret;
2145 
2146 L_extreme:  // Extreme exponent. X is very large positive, very
2147             // large negative, infinity, or NaN.
2148             fxam;
2149             fstsw AX;
2150             test AX, 0x0400; // NaN_or_zero, but we already know x != 0
2151             jz L_was_nan;  // if x is NaN, returns x
2152             test AX, 0x0200;
2153             jnz L_largenegative;
2154 L_largepositive:
2155             // Set scratchreal = real.max.
2156             // squaring it will create infinity, and set overflow flag.
2157             mov word  ptr [RSP+8+8], 0x7FFE;
2158             fstp ST(0);
2159             fld real ptr [RSP+8];  // load scratchreal
2160             fmul ST(0), ST;        // square it, to create havoc!
2161 L_was_nan:
2162             add RSP,24;
2163             ret;
2164 
2165 L_largenegative:
2166             fstp ST(0);
2167             fld1;
2168             fchs; // return -1. Underflow flag is not set.
2169             add RSP,24;
2170             ret;
2171         }
2172     }
2173     else
2174         static assert(0);
2175 }
2176 
2177 private T expm1Impl(T)(T x) @safe pure nothrow @nogc
2178 {
2179     // Coefficients for exp(x) - 1 and overflow/underflow limits.
2180     enum realFormat = floatTraits!T.realFormat;
2181     static if (realFormat == RealFormat.ieeeQuadruple)
2182     {
2183         static immutable T[8] P = [
2184             2.943520915569954073888921213330863757240E8L,
2185             -5.722847283900608941516165725053359168840E7L,
2186             8.944630806357575461578107295909719817253E6L,
2187             -7.212432713558031519943281748462837065308E5L,
2188             4.578962475841642634225390068461943438441E4L,
2189             -1.716772506388927649032068540558788106762E3L,
2190             4.401308817383362136048032038528753151144E1L,
2191             -4.888737542888633647784737721812546636240E-1L
2192         ];
2193 
2194         static immutable T[9] Q = [
2195             1.766112549341972444333352727998584753865E9L,
2196             -7.848989743695296475743081255027098295771E8L,
2197             1.615869009634292424463780387327037251069E8L,
2198             -2.019684072836541751428967854947019415698E7L,
2199             1.682912729190313538934190635536631941751E6L,
2200             -9.615511549171441430850103489315371768998E4L,
2201             3.697714952261803935521187272204485251835E3L,
2202             -8.802340681794263968892934703309274564037E1L,
2203             1.0
2204         ];
2205 
2206         enum T OF = 1.1356523406294143949491931077970764891253E4L;
2207         enum T UF = -1.143276959615573793352782661133116431383730e4L;
2208     }
2209     else static if (realFormat == RealFormat.ieeeExtended)
2210     {
2211         static immutable T[5] P = [
2212            -1.586135578666346600772998894928250240826E4L,
2213             2.642771505685952966904660652518429479531E3L,
2214            -3.423199068835684263987132888286791620673E2L,
2215             1.800826371455042224581246202420972737840E1L,
2216            -5.238523121205561042771939008061958820811E-1L,
2217         ];
2218         static immutable T[6] Q = [
2219            -9.516813471998079611319047060563358064497E4L,
2220             3.964866271411091674556850458227710004570E4L,
2221            -7.207678383830091850230366618190187434796E3L,
2222             7.206038318724600171970199625081491823079E2L,
2223            -4.002027679107076077238836622982900945173E1L,
2224             1.0
2225         ];
2226 
2227         enum T OF =  1.1356523406294143949492E4L;
2228         enum T UF = -4.5054566736396445112120088E1L;
2229     }
2230     else static if (realFormat == RealFormat.ieeeDouble)
2231     {
2232         static immutable T[3] P = [
2233             9.9999999999999999991025E-1,
2234             3.0299440770744196129956E-2,
2235             1.2617719307481059087798E-4,
2236         ];
2237         static immutable T[4] Q = [
2238             2.0000000000000000000897E0,
2239             2.2726554820815502876593E-1,
2240             2.5244834034968410419224E-3,
2241             3.0019850513866445504159E-6,
2242         ];
2243     }
2244     else
2245         static assert(0, "no coefficients for expm1()");
2246 
2247     static if (realFormat == RealFormat.ieeeDouble) // special case for double precision
2248     {
2249         if (x < -0.5 || x > 0.5)
2250             return exp(x) - 1.0;
2251         if (x == 0.0)
2252             return x;
2253 
2254         const T xx = x * x;
2255         x = x * poly(xx, P);
2256         x = x / (poly(xx, Q) - x);
2257         return x + x;
2258     }
2259     else
2260     {
2261         // C1 + C2 = LN2.
2262         enum T C1 = 6.9314575195312500000000E-1L;
2263         enum T C2 = 1.428606820309417232121458176568075500134E-6L;
2264 
2265         // Special cases.
2266         if (x > OF)
2267             return real.infinity;
2268         if (x == cast(T) 0.0)
2269             return x;
2270         if (x < UF)
2271             return -1.0;
2272 
2273         // Express x = LN2 (n + remainder), remainder not exceeding 1/2.
2274         int n = cast(int) floor((cast(T) 0.5) + x / cast(T) LN2);
2275         x -= n * C1;
2276         x -= n * C2;
2277 
2278         // Rational approximation:
2279         //  exp(x) - 1 = x + 0.5 x^^2 + x^^3 P(x) / Q(x)
2280         T px = x * poly(x, P);
2281         T qx = poly(x, Q);
2282         const T xx = x * x;
2283         qx = x + ((cast(T) 0.5) * xx + xx * px / qx);
2284 
2285         // We have qx = exp(remainder LN2) - 1, so:
2286         //  exp(x) - 1 = 2^^n (qx + 1) - 1 = 2^^n qx + 2^^n - 1.
2287         px = ldexp(cast(T) 1.0, n);
2288         x = px * qx + (px - cast(T) 1.0);
2289 
2290         return x;
2291     }
2292 }
2293 
2294 @safe @nogc nothrow unittest
2295 {
2296     static void testExpm1(T)()
2297     {
2298         // NaN
2299         assert(isNaN(expm1(cast(T) T.nan)));
2300 
2301         static immutable T[] xs = [ -2, -0.75, -0.3, 0.0, 0.1, 0.2, 0.5, 1.0 ];
2302         foreach (x; xs)
2303         {
2304             const T e = expm1(x);
2305             const T r = exp(x) - 1;
2306 
2307             //printf("expm1(%Lg) = %Lg, should approximately be %Lg\n", cast(real) x, cast(real) e, cast(real) r);
2308             assert(approxEqual(r, e));
2309         }
2310     }
2311 
2312     import std.meta : AliasSeq;
2313     foreach (T; AliasSeq!(real, double))
2314         testExpm1!T();
2315 }
2316 
2317 /**
2318  * Calculates 2$(SUPERSCRIPT x).
2319  *
2320  *  $(TABLE_SV
2321  *    $(TR $(TH x)             $(TH exp2(x))   )
2322  *    $(TR $(TD +$(INFIN))     $(TD +$(INFIN)) )
2323  *    $(TR $(TD -$(INFIN))     $(TD +0.0)      )
2324  *    $(TR $(TD $(NAN))        $(TD $(NAN))    )
2325  *  )
2326  */
2327 real exp2(real x) @nogc @trusted pure nothrow // TODO: @safe
2328 {
2329     version (InlineAsm_X86_Any)
2330     {
2331         if (!__ctfe)
2332             return exp2Asm(x);
2333     }
2334     return exp2Impl(x);
2335 }
2336 
2337 /// ditto
2338 double exp2(double x) @nogc @safe pure nothrow { return __ctfe ? cast(double) exp2(cast(real) x) : exp2Impl(x); }
2339 
2340 /// ditto
2341 float exp2(float x) @nogc @safe pure nothrow { return __ctfe ? cast(float) exp2(cast(real) x) : exp2Impl(x); }
2342 
2343 ///
2344 @safe unittest
2345 {
2346     assert(isIdentical(exp2(0.0), 1.0));
2347     assert(exp2(2.0).feqrel(4.0) > 16);
2348     assert(exp2(8.0).feqrel(256.0) > 16);
2349 }
2350 
2351 @safe unittest
2352 {
2353     version (CRuntime_Microsoft) {} else // aexp2/exp2f/exp2l not implemented
2354     {
2355         assert( core.stdc.math.exp2f(0.0f) == 1 );
2356         assert( core.stdc.math.exp2 (0.0)  == 1 );
2357         assert( core.stdc.math.exp2l(0.0L) == 1 );
2358     }
2359 }
2360 
2361 version (InlineAsm_X86_Any)
2362 private real exp2Asm(real x) @nogc @trusted pure nothrow
2363 {
2364     version (D_InlineAsm_X86)
2365     {
2366         enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4
2367 
2368         asm pure nothrow @nogc
2369         {
2370             /*  exp2() for x87 80-bit reals, IEEE754-2008 conformant.
2371              * Author: Don Clugston.
2372              *
2373              * exp2(x) = 2^^(rndint(x))* 2^^(y-rndint(x))
2374              * The trick for high performance is to avoid the fscale(28cycles on core2),
2375              * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.
2376              *
2377              * We can do frndint by using fist. BUT we can't use it for huge numbers,
2378              * because it will set the Invalid Operation flag if overflow or NaN occurs.
2379              * Fortunately, whenever this happens the result would be zero or infinity.
2380              *
2381              * We can perform fscale by directly poking into the exponent. BUT this doesn't
2382              * work for the (very rare) cases where the result is subnormal. So we fall back
2383              * to the slow method in that case.
2384              */
2385             naked;
2386             fld real ptr [ESP+4] ; // x
2387             mov AX, [ESP+4+8]; // AX = exponent and sign
2388             sub ESP, 12+8; // Create scratch space on the stack
2389             // [ESP,ESP+2] = scratchint
2390             // [ESP+4..+6, +8..+10, +10] = scratchreal
2391             // set scratchreal mantissa = 1.0
2392             mov dword ptr [ESP+8], 0;
2393             mov dword ptr [ESP+8+4], 0x80000000;
2394             and AX, 0x7FFF; // drop sign bit
2395             cmp AX, 0x401D; // avoid InvalidException in fist
2396             jae L_extreme;
2397             fist dword ptr [ESP]; // scratchint = rndint(x)
2398             fisub dword ptr [ESP]; // x - rndint(x)
2399             // and now set scratchreal exponent
2400             mov EAX, [ESP];
2401             add EAX, 0x3fff;
2402             jle short L_subnormal;
2403             cmp EAX,0x8000;
2404             jge short L_overflow;
2405             mov [ESP+8+8],AX;
2406 L_normal:
2407             f2xm1;
2408             fld1;
2409             faddp ST(1), ST; // 2^^(x-rndint(x))
2410             fld real ptr [ESP+8] ; // 2^^rndint(x)
2411             add ESP,12+8;
2412             fmulp ST(1), ST;
2413             ret PARAMSIZE;
2414 
2415 L_subnormal:
2416             // Result will be subnormal.
2417             // In this rare case, the simple poking method doesn't work.
2418             // The speed doesn't matter, so use the slow fscale method.
2419             fild dword ptr [ESP];  // scratchint
2420             fld1;
2421             fscale;
2422             fstp real ptr [ESP+8]; // scratchreal = 2^^scratchint
2423             fstp ST(0);         // drop scratchint
2424             jmp L_normal;
2425 
2426 L_extreme:  // Extreme exponent. X is very large positive, very
2427             // large negative, infinity, or NaN.
2428             fxam;
2429             fstsw AX;
2430             test AX, 0x0400; // NaN_or_zero, but we already know x != 0
2431             jz L_was_nan;  // if x is NaN, returns x
2432             // set scratchreal = real.min_normal
2433             // squaring it will return 0, setting underflow flag
2434             mov word  ptr [ESP+8+8], 1;
2435             test AX, 0x0200;
2436             jnz L_waslargenegative;
2437 L_overflow:
2438             // Set scratchreal = real.max.
2439             // squaring it will create infinity, and set overflow flag.
2440             mov word  ptr [ESP+8+8], 0x7FFE;
2441 L_waslargenegative:
2442             fstp ST(0);
2443             fld real ptr [ESP+8];  // load scratchreal
2444             fmul ST(0), ST;        // square it, to create havoc!
2445 L_was_nan:
2446             add ESP,12+8;
2447             ret PARAMSIZE;
2448         }
2449     }
2450     else version (D_InlineAsm_X86_64)
2451     {
2452         asm pure nothrow @nogc
2453         {
2454             naked;
2455         }
2456         version (Win64)
2457         {
2458             asm pure nothrow @nogc
2459             {
2460                 fld   real ptr [RCX];  // x
2461                 mov   AX,[RCX+8];      // AX = exponent and sign
2462             }
2463         }
2464         else
2465         {
2466             asm pure nothrow @nogc
2467             {
2468                 fld   real ptr [RSP+8];  // x
2469                 mov   AX,[RSP+8+8];      // AX = exponent and sign
2470             }
2471         }
2472         asm pure nothrow @nogc
2473         {
2474             /*  exp2() for x87 80-bit reals, IEEE754-2008 conformant.
2475              * Author: Don Clugston.
2476              *
2477              * exp2(x) = 2^(rndint(x))* 2^(y-rndint(x))
2478              * The trick for high performance is to avoid the fscale(28cycles on core2),
2479              * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.
2480              *
2481              * We can do frndint by using fist. BUT we can't use it for huge numbers,
2482              * because it will set the Invalid Operation flag is overflow or NaN occurs.
2483              * Fortunately, whenever this happens the result would be zero or infinity.
2484              *
2485              * We can perform fscale by directly poking into the exponent. BUT this doesn't
2486              * work for the (very rare) cases where the result is subnormal. So we fall back
2487              * to the slow method in that case.
2488              */
2489             sub RSP, 24; // Create scratch space on the stack
2490             // [RSP,RSP+2] = scratchint
2491             // [RSP+4..+6, +8..+10, +10] = scratchreal
2492             // set scratchreal mantissa = 1.0
2493             mov dword ptr [RSP+8], 0;
2494             mov dword ptr [RSP+8+4], 0x80000000;
2495             and AX, 0x7FFF; // drop sign bit
2496             cmp AX, 0x401D; // avoid InvalidException in fist
2497             jae L_extreme;
2498             fist dword ptr [RSP]; // scratchint = rndint(x)
2499             fisub dword ptr [RSP]; // x - rndint(x)
2500             // and now set scratchreal exponent
2501             mov EAX, [RSP];
2502             add EAX, 0x3fff;
2503             jle short L_subnormal;
2504             cmp EAX,0x8000;
2505             jge short L_overflow;
2506             mov [RSP+8+8],AX;
2507 L_normal:
2508             f2xm1;
2509             fld1;
2510             fadd; // 2^(x-rndint(x))
2511             fld real ptr [RSP+8] ; // 2^rndint(x)
2512             add RSP,24;
2513             fmulp ST(1), ST;
2514             ret;
2515 
2516 L_subnormal:
2517             // Result will be subnormal.
2518             // In this rare case, the simple poking method doesn't work.
2519             // The speed doesn't matter, so use the slow fscale method.
2520             fild dword ptr [RSP];  // scratchint
2521             fld1;
2522             fscale;
2523             fstp real ptr [RSP+8]; // scratchreal = 2^scratchint
2524             fstp ST(0);         // drop scratchint
2525             jmp L_normal;
2526 
2527 L_extreme:  // Extreme exponent. X is very large positive, very
2528             // large negative, infinity, or NaN.
2529             fxam;
2530             fstsw AX;
2531             test AX, 0x0400; // NaN_or_zero, but we already know x != 0
2532             jz L_was_nan;  // if x is NaN, returns x
2533             // set scratchreal = real.min
2534             // squaring it will return 0, setting underflow flag
2535             mov word  ptr [RSP+8+8], 1;
2536             test AX, 0x0200;
2537             jnz L_waslargenegative;
2538 L_overflow:
2539             // Set scratchreal = real.max.
2540             // squaring it will create infinity, and set overflow flag.
2541             mov word  ptr [RSP+8+8], 0x7FFE;
2542 L_waslargenegative:
2543             fstp ST(0);
2544             fld real ptr [RSP+8];  // load scratchreal
2545             fmul ST(0), ST;        // square it, to create havoc!
2546 L_was_nan:
2547             add RSP,24;
2548             ret;
2549         }
2550     }
2551     else
2552         static assert(0);
2553 }
2554 
2555 private T exp2Impl(T)(T x) @nogc @safe pure nothrow
2556 {
2557     // Coefficients for exp2(x)
2558     enum realFormat = floatTraits!T.realFormat;
2559     static if (realFormat == RealFormat.ieeeQuadruple)
2560     {
2561         static immutable T[5] P = [
2562             9.079594442980146270952372234833529694788E12L,
2563             1.530625323728429161131811299626419117557E11L,
2564             5.677513871931844661829755443994214173883E8L,
2565             6.185032670011643762127954396427045467506E5L,
2566             1.587171580015525194694938306936721666031E2L
2567         ];
2568 
2569         static immutable T[6] Q = [
2570             2.619817175234089411411070339065679229869E13L,
2571             1.490560994263653042761789432690793026977E12L,
2572             1.092141473886177435056423606755843616331E10L,
2573             2.186249607051644894762167991800811827835E7L,
2574             1.236602014442099053716561665053645270207E4L,
2575             1.0
2576         ];
2577     }
2578     else static if (realFormat == RealFormat.ieeeExtended)
2579     {
2580         static immutable T[3] P = [
2581             2.0803843631901852422887E6L,
2582             3.0286971917562792508623E4L,
2583             6.0614853552242266094567E1L,
2584         ];
2585         static immutable T[4] Q = [
2586             6.0027204078348487957118E6L,
2587             3.2772515434906797273099E5L,
2588             1.7492876999891839021063E3L,
2589             1.0000000000000000000000E0L,
2590         ];
2591     }
2592     else static if (realFormat == RealFormat.ieeeDouble)
2593     {
2594         static immutable T[3] P = [
2595             1.51390680115615096133E3L,
2596             2.02020656693165307700E1L,
2597             2.30933477057345225087E-2L,
2598         ];
2599         static immutable T[3] Q = [
2600             4.36821166879210612817E3L,
2601             2.33184211722314911771E2L,
2602             1.00000000000000000000E0L,
2603         ];
2604     }
2605     else static if (realFormat == RealFormat.ieeeSingle)
2606     {
2607         static immutable T[6] P = [
2608             6.931472028550421E-001L,
2609             2.402264791363012E-001L,
2610             5.550332471162809E-002L,
2611             9.618437357674640E-003L,
2612             1.339887440266574E-003L,
2613             1.535336188319500E-004L,
2614         ];
2615     }
2616     else
2617         static assert(0, "no coefficients for exp2()");
2618 
2619     // Overflow and Underflow limits.
2620     enum T OF = T.max_exp;
2621     enum T UF = T.min_exp - 1;
2622 
2623     // Special cases.
2624     if (isNaN(x))
2625         return x;
2626     if (x > OF)
2627         return real.infinity;
2628     if (x < UF)
2629         return 0.0;
2630 
2631     static if (realFormat == RealFormat.ieeeSingle) // special case for single precision
2632     {
2633         // The following is necessary because range reduction blows up.
2634         if (x == 0.0f)
2635             return 1.0f;
2636 
2637         // Separate into integer and fractional parts.
2638         const T i = floor(x);
2639         int n = cast(int) i;
2640         x -= i;
2641         if (x > 0.5f)
2642         {
2643             n += 1;
2644             x -= 1.0f;
2645         }
2646 
2647         // Rational approximation:
2648         //  exp2(x) = 1.0 + x P(x)
2649         x = 1.0f + x * poly(x, P);
2650     }
2651     else
2652     {
2653         // Separate into integer and fractional parts.
2654         const T i = floor(x + cast(T) 0.5);
2655         int n = cast(int) i;
2656         x -= i;
2657 
2658         // Rational approximation:
2659         //  exp2(x) = 1.0 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))
2660         const T xx = x * x;
2661         const T px = x * poly(xx, P);
2662         x = px / (poly(xx, Q) - px);
2663         x = (cast(T) 1.0) + (cast(T) 2.0) * x;
2664     }
2665 
2666     // Scale by power of 2.
2667     x = ldexp(x, n);
2668 
2669     return x;
2670 }
2671 
2672 @safe @nogc nothrow unittest
2673 {
2674     assert(feqrel(exp2(0.5L), SQRT2) >= real.mant_dig -1);
2675     assert(exp2(8.0L) == 256.0);
2676     assert(exp2(-9.0L)== 1.0L/512.0);
2677 
2678     static void testExp2(T)()
2679     {
2680         // NaN
2681         const T specialNaN = NaN(0x0123L);
2682         assert(isIdentical(exp2(specialNaN), specialNaN));
2683 
2684         // over-/underflow
2685         enum T OF = T.max_exp;
2686         enum T UF = T.min_exp - T.mant_dig;
2687         assert(isIdentical(exp2(OF + 1), cast(T) T.infinity));
2688         assert(isIdentical(exp2(UF - 1), cast(T) 0.0));
2689 
2690         static immutable T[2][] vals =
2691         [
2692             // x, exp2(x)
2693             [  0.0, 1.0 ],
2694             [ -0.0, 1.0 ],
2695             [  0.5, SQRT2 ],
2696             [  8.0, 256.0 ],
2697             [ -9.0, 1.0 / 512 ],
2698         ];
2699 
2700         foreach (ref val; vals)
2701         {
2702             const T x = val[0];
2703             const T r = val[1];
2704             const T e = exp2(x);
2705 
2706             //printf("exp2(%Lg) = %Lg, should be %Lg\n", cast(real) x, cast(real) e, cast(real) r);
2707             assert(approxEqual(r, e));
2708         }
2709     }
2710 
2711     import std.meta : AliasSeq;
2712     foreach (T; AliasSeq!(real, double, float))
2713         testExp2!T();
2714 }
2715 
2716 /*********************************************************************
2717  * Separate floating point value into significand and exponent.
2718  *
2719  * Returns:
2720  *      Calculate and return $(I x) and $(I exp) such that
2721  *      value =$(I x)*2$(SUPERSCRIPT exp) and
2722  *      .5 $(LT)= |$(I x)| $(LT) 1.0
2723  *
2724  *      $(I x) has same sign as value.
2725  *
2726  *      $(TABLE_SV
2727  *      $(TR $(TH value)           $(TH returns)         $(TH exp))
2728  *      $(TR $(TD $(PLUSMN)0.0)    $(TD $(PLUSMN)0.0)    $(TD 0))
2729  *      $(TR $(TD +$(INFIN))       $(TD +$(INFIN))       $(TD int.max))
2730  *      $(TR $(TD -$(INFIN))       $(TD -$(INFIN))       $(TD int.min))
2731  *      $(TR $(TD $(PLUSMN)$(NAN)) $(TD $(PLUSMN)$(NAN)) $(TD int.min))
2732  *      )
2733  */
2734 T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
2735 if (isFloatingPoint!T)
2736 {
2737     if (__ctfe)
2738     {
2739         // Handle special cases.
2740         if (value == 0) { exp = 0; return value; }
2741         if (value == T.infinity) { exp = int.max; return value; }
2742         if (value == -T.infinity || value != value) { exp = int.min; return value; }
2743         // Handle ordinary cases.
2744         // In CTFE there is no performance advantage for having separate
2745         // paths for different floating point types.
2746         T absValue = value < 0 ? -value : value;
2747         int expCount;
2748         static if (T.mant_dig > double.mant_dig)
2749         {
2750             for (; absValue >= 0x1.0p+1024L; absValue *= 0x1.0p-1024L)
2751                 expCount += 1024;
2752             for (; absValue < 0x1.0p-1021L; absValue *= 0x1.0p+1021L)
2753                 expCount -= 1021;
2754         }
2755         const double dval = cast(double) absValue;
2756         int dexp = cast(int) (((*cast(const long*) &dval) >>> 52) & 0x7FF) + double.min_exp - 2;
2757         dexp++;
2758         expCount += dexp;
2759         absValue *= 2.0 ^^ -dexp;
2760         // If the original value was subnormal or if it was a real
2761         // then absValue can still be outside the [0.5, 1.0) range.
2762         if (absValue < 0.5)
2763         {
2764             assert(T.mant_dig > double.mant_dig || isSubnormal(value));
2765             do
2766             {
2767                 absValue += absValue;
2768                 expCount--;
2769             } while (absValue < 0.5);
2770         }
2771         else
2772         {
2773             assert(absValue < 1 || T.mant_dig > double.mant_dig);
2774             for (; absValue >= 1; absValue *= T(0.5))
2775                 expCount++;
2776         }
2777         exp = expCount;
2778         return value < 0 ? -absValue : absValue;
2779     }
2780 
2781     Unqual!T vf = value;
2782     ushort* vu = cast(ushort*)&vf;
2783     static if (is(immutable T == immutable float))
2784         int* vi = cast(int*)&vf;
2785     else
2786         long* vl = cast(long*)&vf;
2787     int ex;
2788     alias F = floatTraits!T;
2789 
2790     ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
2791     static if (F.realFormat == RealFormat.ieeeExtended)
2792     {
2793         if (ex)
2794         {   // If exponent is non-zero
2795             if (ex == F.EXPMASK) // infinity or NaN
2796             {
2797                 if (*vl &  0x7FFF_FFFF_FFFF_FFFF)  // NaN
2798                 {
2799                     *vl |= 0xC000_0000_0000_0000;  // convert NaNS to NaNQ
2800                     exp = int.min;
2801                 }
2802                 else if (vu[F.EXPPOS_SHORT] & 0x8000)   // negative infinity
2803                     exp = int.min;
2804                 else   // positive infinity
2805                     exp = int.max;
2806 
2807             }
2808             else
2809             {
2810                 exp = ex - F.EXPBIAS;
2811                 vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE;
2812             }
2813         }
2814         else if (!*vl)
2815         {
2816             // vf is +-0.0
2817             exp = 0;
2818         }
2819         else
2820         {
2821             // subnormal
2822 
2823             vf *= F.RECIP_EPSILON;
2824             ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
2825             exp = ex - F.EXPBIAS - T.mant_dig + 1;
2826             vu[F.EXPPOS_SHORT] = ((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3FFE;
2827         }
2828         return vf;
2829     }
2830     else static if (F.realFormat == RealFormat.ieeeQuadruple)
2831     {
2832         if (ex)     // If exponent is non-zero
2833         {
2834             if (ex == F.EXPMASK)
2835             {
2836                 // infinity or NaN
2837                 if (vl[MANTISSA_LSB] |
2838                     (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF))  // NaN
2839                 {
2840                     // convert NaNS to NaNQ
2841                     vl[MANTISSA_MSB] |= 0x0000_8000_0000_0000;
2842                     exp = int.min;
2843                 }
2844                 else if (vu[F.EXPPOS_SHORT] & 0x8000)   // negative infinity
2845                     exp = int.min;
2846                 else   // positive infinity
2847                     exp = int.max;
2848             }
2849             else
2850             {
2851                 exp = ex - F.EXPBIAS;
2852                 vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]);
2853             }
2854         }
2855         else if ((vl[MANTISSA_LSB] |
2856             (vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0)
2857         {
2858             // vf is +-0.0
2859             exp = 0;
2860         }
2861         else
2862         {
2863             // subnormal
2864             vf *= F.RECIP_EPSILON;
2865             ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
2866             exp = ex - F.EXPBIAS - T.mant_dig + 1;
2867             vu[F.EXPPOS_SHORT] = F.EXPBIAS | (0x8000 & vu[F.EXPPOS_SHORT]);
2868         }
2869         return vf;
2870     }
2871     else static if (F.realFormat == RealFormat.ieeeDouble)
2872     {
2873         if (ex) // If exponent is non-zero
2874         {
2875             if (ex == F.EXPMASK)   // infinity or NaN
2876             {
2877                 if (*vl == 0x7FF0_0000_0000_0000)  // positive infinity
2878                 {
2879                     exp = int.max;
2880                 }
2881                 else if (*vl == 0xFFF0_0000_0000_0000) // negative infinity
2882                     exp = int.min;
2883                 else
2884                 { // NaN
2885                     *vl |= 0x0008_0000_0000_0000;  // convert NaNS to NaNQ
2886                     exp = int.min;
2887                 }
2888             }
2889             else
2890             {
2891                 exp = (ex - F.EXPBIAS) >> 4;
2892                 vu[F.EXPPOS_SHORT] = cast(ushort)((0x800F & vu[F.EXPPOS_SHORT]) | 0x3FE0);
2893             }
2894         }
2895         else if (!(*vl & 0x7FFF_FFFF_FFFF_FFFF))
2896         {
2897             // vf is +-0.0
2898             exp = 0;
2899         }
2900         else
2901         {
2902             // subnormal
2903             vf *= F.RECIP_EPSILON;
2904             ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
2905             exp = ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1;
2906             vu[F.EXPPOS_SHORT] =
2907                 cast(ushort)(((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3FE0);
2908         }
2909         return vf;
2910     }
2911     else static if (F.realFormat == RealFormat.ieeeSingle)
2912     {
2913         if (ex) // If exponent is non-zero
2914         {
2915             if (ex == F.EXPMASK)   // infinity or NaN
2916             {
2917                 if (*vi == 0x7F80_0000)  // positive infinity
2918                 {
2919                     exp = int.max;
2920                 }
2921                 else if (*vi == 0xFF80_0000) // negative infinity
2922                     exp = int.min;
2923                 else
2924                 { // NaN
2925                     *vi |= 0x0040_0000;  // convert NaNS to NaNQ
2926                     exp = int.min;
2927                 }
2928             }
2929             else
2930             {
2931                 exp = (ex - F.EXPBIAS) >> 7;
2932                 vu[F.EXPPOS_SHORT] = cast(ushort)((0x807F & vu[F.EXPPOS_SHORT]) | 0x3F00);
2933             }
2934         }
2935         else if (!(*vi & 0x7FFF_FFFF))
2936         {
2937             // vf is +-0.0
2938             exp = 0;
2939         }
2940         else
2941         {
2942             // subnormal
2943             vf *= F.RECIP_EPSILON;
2944             ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
2945             exp = ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1;
2946             vu[F.EXPPOS_SHORT] =
2947                 cast(ushort)(((-1 - F.EXPMASK) & vu[F.EXPPOS_SHORT]) | 0x3F00);
2948         }
2949         return vf;
2950     }
2951     else // static if (F.realFormat == RealFormat.ibmExtended)
2952     {
2953         assert(0, "frexp not implemented");
2954     }
2955 }
2956 
2957 ///
2958 @safe unittest
2959 {
2960     int exp;
2961     real mantissa = frexp(123.456L, exp);
2962 
2963     assert(approxEqual(mantissa * pow(2.0L, cast(real) exp), 123.456L));
2964 
2965     assert(frexp(-real.nan, exp) && exp == int.min);
2966     assert(frexp(real.nan, exp) && exp == int.min);
2967     assert(frexp(-real.infinity, exp) == -real.infinity && exp == int.min);
2968     assert(frexp(real.infinity, exp) == real.infinity && exp == int.max);
2969     assert(frexp(-0.0, exp) == -0.0 && exp == 0);
2970     assert(frexp(0.0, exp) == 0.0 && exp == 0);
2971 }
2972 
2973 @safe @nogc nothrow unittest
2974 {
2975     int exp;
2976     real mantissa = frexp(123.456L, exp);
2977 
2978     // check if values are equal to 19 decimal digits of precision
2979     assert(equalsDigit(mantissa * pow(2.0L, cast(real) exp), 123.456L, 19));
2980 }
2981 
2982 @safe unittest
2983 {
2984     import std.meta : AliasSeq;
2985     import std.typecons : tuple, Tuple;
2986 
2987     static foreach (T; AliasSeq!(real, double, float))
2988     {{
2989         Tuple!(T, T, int)[] vals =     // x,frexp,exp
2990             [
2991              tuple(T(0.0),  T( 0.0 ), 0),
2992              tuple(T(-0.0), T( -0.0), 0),
2993              tuple(T(1.0),  T( .5  ), 1),
2994              tuple(T(-1.0), T( -.5 ), 1),
2995              tuple(T(2.0),  T( .5  ), 2),
2996              tuple(T(float.min_normal/2.0f), T(.5), -126),
2997              tuple(T.infinity, T.infinity, int.max),
2998              tuple(-T.infinity, -T.infinity, int.min),
2999              tuple(T.nan, T.nan, int.min),
3000              tuple(-T.nan, -T.nan, int.min),
3001 
3002              // https://issues.dlang.org/show_bug.cgi?id=16026:
3003              tuple(3 * (T.min_normal * T.epsilon), T( .75), (T.min_exp - T.mant_dig) + 2)
3004              ];
3005 
3006         foreach (elem; vals)
3007         {
3008             T x = elem[0];
3009             T e = elem[1];
3010             int exp = elem[2];
3011             int eptr;
3012             T v = frexp(x, eptr);
3013             assert(isIdentical(e, v));
3014             assert(exp == eptr);
3015 
3016         }
3017 
3018         static if (floatTraits!(T).realFormat == RealFormat.ieeeExtended)
3019         {
3020             static T[3][] extendedvals = [ // x,frexp,exp
3021                 [0x1.a5f1c2eb3fe4efp+73L,    0x1.A5F1C2EB3FE4EFp-1L,     74],    // normal
3022                 [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],
3023                 [T.min_normal,      .5, -16381],
3024                 [T.min_normal/2.0L, .5, -16382]    // subnormal
3025             ];
3026             foreach (elem; extendedvals)
3027             {
3028                 T x = elem[0];
3029                 T e = elem[1];
3030                 int exp = cast(int) elem[2];
3031                 int eptr;
3032                 T v = frexp(x, eptr);
3033                 assert(isIdentical(e, v));
3034                 assert(exp == eptr);
3035 
3036             }
3037         }
3038     }}
3039 
3040     // CTFE
3041     alias CtfeFrexpResult= Tuple!(real, int);
3042     static CtfeFrexpResult ctfeFrexp(T)(const T value)
3043     {
3044         int exp;
3045         auto significand = frexp(value, exp);
3046         return CtfeFrexpResult(significand, exp);
3047     }
3048     static foreach (T; AliasSeq!(real, double, float))
3049     {{
3050         enum Tuple!(T, T, int)[] vals =     // x,frexp,exp
3051             [
3052              tuple(T(0.0),  T( 0.0 ), 0),
3053              tuple(T(-0.0), T( -0.0), 0),
3054              tuple(T(1.0),  T( .5  ), 1),
3055              tuple(T(-1.0), T( -.5 ), 1),
3056              tuple(T(2.0),  T( .5  ), 2),
3057              tuple(T(float.min_normal/2.0f), T(.5), -126),
3058              tuple(T.infinity, T.infinity, int.max),
3059              tuple(-T.infinity, -T.infinity, int.min),
3060              tuple(T.nan, T.nan, int.min),
3061              tuple(-T.nan, -T.nan, int.min),
3062 
3063              // https://issues.dlang.org/show_bug.cgi?id=16026:
3064              tuple(3 * (T.min_normal * T.epsilon), T( .75), (T.min_exp - T.mant_dig) + 2)
3065              ];
3066 
3067         static foreach (elem; vals)
3068         {
3069             static assert(ctfeFrexp(elem[0]) is CtfeFrexpResult(elem[1], elem[2]));
3070         }
3071 
3072         static if (floatTraits!(T).realFormat == RealFormat.ieeeExtended)
3073         {
3074             enum T[3][] extendedvals = [ // x,frexp,exp
3075                 [0x1.a5f1c2eb3fe4efp+73L,    0x1.A5F1C2EB3FE4EFp-1L,     74],    // normal
3076                 [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],
3077                 [T.min_normal,      .5, -16381],
3078                 [T.min_normal/2.0L, .5, -16382]    // subnormal
3079             ];
3080             static foreach (elem; extendedvals)
3081             {
3082                 static assert(ctfeFrexp(elem[0]) is CtfeFrexpResult(elem[1], cast(int) elem[2]));
3083             }
3084         }
3085     }}
3086 }
3087 
3088 @safe unittest
3089 {
3090     import std.meta : AliasSeq;
3091     void foo() {
3092         static foreach (T; AliasSeq!(real, double, float))
3093         {{
3094             int exp;
3095             const T a = 1;
3096             immutable T b = 2;
3097             auto c = frexp(a, exp);
3098             auto d = frexp(b, exp);
3099         }}
3100     }
3101 }
3102 
3103 /******************************************
3104  * Extracts the exponent of x as a signed integral value.
3105  *
3106  * If x is not a special value, the result is the same as
3107  * $(D cast(int) logb(x)).
3108  *
3109  *      $(TABLE_SV
3110  *      $(TR $(TH x)                $(TH ilogb(x))     $(TH Range error?))
3111  *      $(TR $(TD 0)                 $(TD FP_ILOGB0)   $(TD yes))
3112  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD int.max)     $(TD no))
3113  *      $(TR $(TD $(NAN))            $(TD FP_ILOGBNAN) $(TD no))
3114  *      )
3115  */
3116 int ilogb(T)(const T x) @trusted pure nothrow @nogc
3117 if (isFloatingPoint!T)
3118 {
3119     import core.bitop : bsr;
3120     alias F = floatTraits!T;
3121 
3122     union floatBits
3123     {
3124         T rv;
3125         ushort[T.sizeof/2] vu;
3126         uint[T.sizeof/4] vui;
3127         static if (T.sizeof >= 8)
3128             ulong[T.sizeof/8] vul;
3129     }
3130     floatBits y = void;
3131     y.rv = x;
3132 
3133     int ex = y.vu[F.EXPPOS_SHORT] & F.EXPMASK;
3134     static if (F.realFormat == RealFormat.ieeeExtended)
3135     {
3136         if (ex)
3137         {
3138             // If exponent is non-zero
3139             if (ex == F.EXPMASK) // infinity or NaN
3140             {
3141                 if (y.vul[0] &  0x7FFF_FFFF_FFFF_FFFF)  // NaN
3142                     return FP_ILOGBNAN;
3143                 else // +-infinity
3144                     return int.max;
3145             }
3146             else
3147             {
3148                 return ex - F.EXPBIAS - 1;
3149             }
3150         }
3151         else if (!y.vul[0])
3152         {
3153             // vf is +-0.0
3154             return FP_ILOGB0;
3155         }
3156         else
3157         {
3158             // subnormal
3159             return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(y.vul[0]);
3160         }
3161     }
3162     else static if (F.realFormat == RealFormat.ieeeQuadruple)
3163     {
3164         if (ex)    // If exponent is non-zero
3165         {
3166             if (ex == F.EXPMASK)
3167             {
3168                 // infinity or NaN
3169                 if (y.vul[MANTISSA_LSB] | ( y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF))  // NaN
3170                     return FP_ILOGBNAN;
3171                 else // +- infinity
3172                     return int.max;
3173             }
3174             else
3175             {
3176                 return ex - F.EXPBIAS - 1;
3177             }
3178         }
3179         else if ((y.vul[MANTISSA_LSB] | (y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0)
3180         {
3181             // vf is +-0.0
3182             return FP_ILOGB0;
3183         }
3184         else
3185         {
3186             // subnormal
3187             const ulong msb = y.vul[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF;
3188             const ulong lsb = y.vul[MANTISSA_LSB];
3189             if (msb)
3190                 return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(msb) + 64;
3191             else
3192                 return ex - F.EXPBIAS - T.mant_dig + 1 + bsr(lsb);
3193         }
3194     }
3195     else static if (F.realFormat == RealFormat.ieeeDouble)
3196     {
3197         if (ex) // If exponent is non-zero
3198         {
3199             if (ex == F.EXPMASK)   // infinity or NaN
3200             {
3201                 if ((y.vul[0] & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FF0_0000_0000_0000)  // +- infinity
3202                     return int.max;
3203                 else // NaN
3204                     return FP_ILOGBNAN;
3205             }
3206             else
3207             {
3208                 return ((ex - F.EXPBIAS) >> 4) - 1;
3209             }
3210         }
3211         else if (!(y.vul[0] & 0x7FFF_FFFF_FFFF_FFFF))
3212         {
3213             // vf is +-0.0
3214             return FP_ILOGB0;
3215         }
3216         else
3217         {
3218             // subnormal
3219             enum MANTISSAMASK_64 = ((cast(ulong) F.MANTISSAMASK_INT) << 32) | 0xFFFF_FFFF;
3220             return ((ex - F.EXPBIAS) >> 4) - T.mant_dig + 1 + bsr(y.vul[0] & MANTISSAMASK_64);
3221         }
3222     }
3223     else static if (F.realFormat == RealFormat.ieeeSingle)
3224     {
3225         if (ex) // If exponent is non-zero
3226         {
3227             if (ex == F.EXPMASK)   // infinity or NaN
3228             {
3229                 if ((y.vui[0] & 0x7FFF_FFFF) == 0x7F80_0000)  // +- infinity
3230                     return int.max;
3231                 else // NaN
3232                     return FP_ILOGBNAN;
3233             }
3234             else
3235             {
3236                 return ((ex - F.EXPBIAS) >> 7) - 1;
3237             }
3238         }
3239         else if (!(y.vui[0] & 0x7FFF_FFFF))
3240         {
3241             // vf is +-0.0
3242             return FP_ILOGB0;
3243         }
3244         else
3245         {
3246             // subnormal
3247             const uint mantissa = y.vui[0] & F.MANTISSAMASK_INT;
3248             return ((ex - F.EXPBIAS) >> 7) - T.mant_dig + 1 + bsr(mantissa);
3249         }
3250     }
3251     else // static if (F.realFormat == RealFormat.ibmExtended)
3252     {
3253         assert(0, "ilogb not implemented");
3254     }
3255 }
3256 /// ditto
3257 int ilogb(T)(const T x) @safe pure nothrow @nogc
3258 if (isIntegral!T && isUnsigned!T)
3259 {
3260     import core.bitop : bsr;
3261     if (x == 0)
3262         return FP_ILOGB0;
3263     else
3264     {
3265         static assert(T.sizeof <= ulong.sizeof, "integer size too large for the current ilogb implementation");
3266         return bsr(x);
3267     }
3268 }
3269 /// ditto
3270 int ilogb(T)(const T x) @safe pure nothrow @nogc
3271 if (isIntegral!T && isSigned!T)
3272 {
3273     import std.traits : Unsigned;
3274     // Note: abs(x) can not be used because the return type is not Unsigned and
3275     //       the return value would be wrong for x == int.min
3276     Unsigned!T absx =  x >= 0 ? x : -x;
3277     return ilogb(absx);
3278 }
3279 
3280 ///
3281 @safe pure unittest
3282 {
3283     assert(ilogb(1) == 0);
3284     assert(ilogb(3) == 1);
3285     assert(ilogb(3.0) == 1);
3286     assert(ilogb(100_000_000) == 26);
3287 
3288     assert(ilogb(0) == FP_ILOGB0);
3289     assert(ilogb(0.0) == FP_ILOGB0);
3290     assert(ilogb(double.nan) == FP_ILOGBNAN);
3291     assert(ilogb(double.infinity) == int.max);
3292 }
3293 
3294 /**
3295 Special return values of $(LREF ilogb).
3296  */
3297 alias FP_ILOGB0   = core.stdc.math.FP_ILOGB0;
3298 /// ditto
3299 alias FP_ILOGBNAN = core.stdc.math.FP_ILOGBNAN;
3300 
3301 ///
3302 @safe pure unittest
3303 {
3304     assert(ilogb(0) == FP_ILOGB0);
3305     assert(ilogb(0.0) == FP_ILOGB0);
3306     assert(ilogb(double.nan) == FP_ILOGBNAN);
3307 }
3308 
3309 @safe nothrow @nogc unittest
3310 {
3311     import std.meta : AliasSeq;
3312     import std.typecons : Tuple;
3313     static foreach (F; AliasSeq!(float, double, real))
3314     {{
3315         alias T = Tuple!(F, int);
3316         T[13] vals =   // x, ilogb(x)
3317         [
3318             T(  F.nan     , FP_ILOGBNAN ),
3319             T( -F.nan     , FP_ILOGBNAN ),
3320             T(  F.infinity, int.max     ),
3321             T( -F.infinity, int.max     ),
3322             T(  0.0       , FP_ILOGB0   ),
3323             T( -0.0       , FP_ILOGB0   ),
3324             T(  2.0       , 1           ),
3325             T(  2.0001    , 1           ),
3326             T(  1.9999    , 0           ),
3327             T(  0.5       , -1          ),
3328             T(  123.123   , 6           ),
3329             T( -123.123   , 6           ),
3330             T(  0.123     , -4          ),
3331         ];
3332 
3333         foreach (elem; vals)
3334         {
3335             assert(ilogb(elem[0]) == elem[1]);
3336         }
3337     }}
3338 
3339     // min_normal and subnormals
3340     assert(ilogb(-float.min_normal) == -126);
3341     assert(ilogb(nextUp(-float.min_normal)) == -127);
3342     assert(ilogb(nextUp(-float(0.0))) == -149);
3343     assert(ilogb(-double.min_normal) == -1022);
3344     assert(ilogb(nextUp(-double.min_normal)) == -1023);
3345     assert(ilogb(nextUp(-double(0.0))) == -1074);
3346     static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
3347     {
3348         assert(ilogb(-real.min_normal) == -16382);
3349         assert(ilogb(nextUp(-real.min_normal)) == -16383);
3350         assert(ilogb(nextUp(-real(0.0))) == -16445);
3351     }
3352     else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
3353     {
3354         assert(ilogb(-real.min_normal) == -1022);
3355         assert(ilogb(nextUp(-real.min_normal)) == -1023);
3356         assert(ilogb(nextUp(-real(0.0))) == -1074);
3357     }
3358 
3359     // test integer types
3360     assert(ilogb(0) == FP_ILOGB0);
3361     assert(ilogb(int.max) == 30);
3362     assert(ilogb(int.min) == 31);
3363     assert(ilogb(uint.max) == 31);
3364     assert(ilogb(long.max) == 62);
3365     assert(ilogb(long.min) == 63);
3366     assert(ilogb(ulong.max) == 63);
3367 }
3368 
3369 /*******************************************
3370  * Compute n * 2$(SUPERSCRIPT exp)
3371  * References: frexp
3372  */
3373 
3374 pragma(inline, true)
3375 real ldexp(real n, int exp)     @safe pure nothrow @nogc { return core.math.ldexp(n, exp); }
3376 ///ditto
3377 pragma(inline, true)
3378 double ldexp(double n, int exp) @safe pure nothrow @nogc { return core.math.ldexp(n, exp); }
3379 ///ditto
3380 pragma(inline, true)
3381 float ldexp(float n, int exp)   @safe pure nothrow @nogc { return core.math.ldexp(n, exp); }
3382 
3383 ///
3384 @nogc @safe pure nothrow unittest
3385 {
3386     import std.meta : AliasSeq;
3387     static foreach (T; AliasSeq!(float, double, real))
3388     {{
3389         T r;
3390 
3391         r = ldexp(3.0L, 3);
3392         assert(r == 24);
3393 
3394         r = ldexp(cast(T) 3.0, cast(int) 3);
3395         assert(r == 24);
3396 
3397         T n = 3.0;
3398         int exp = 3;
3399         r = ldexp(n, exp);
3400         assert(r == 24);
3401     }}
3402 }
3403 
3404 @safe pure nothrow @nogc unittest
3405 {
3406     static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
3407                floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)
3408     {
3409         assert(ldexp(1.0L, -16384) == 0x1p-16384L);
3410         assert(ldexp(1.0L, -16382) == 0x1p-16382L);
3411         int x;
3412         real n = frexp(0x1p-16384L, x);
3413         assert(n == 0.5L);
3414         assert(x==-16383);
3415         assert(ldexp(n, x)==0x1p-16384L);
3416     }
3417     else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
3418     {
3419         assert(ldexp(1.0L, -1024) == 0x1p-1024L);
3420         assert(ldexp(1.0L, -1022) == 0x1p-1022L);
3421         int x;
3422         real n = frexp(0x1p-1024L, x);
3423         assert(n == 0.5L);
3424         assert(x==-1023);
3425         assert(ldexp(n, x)==0x1p-1024L);
3426     }
3427     else static assert(false, "Floating point type real not supported");
3428 }
3429 
3430 /* workaround https://issues.dlang.org/show_bug.cgi?id=14718
3431    float parsing depends on platform strtold
3432 @safe pure nothrow @nogc unittest
3433 {
3434     assert(ldexp(1.0, -1024) == 0x1p-1024);
3435     assert(ldexp(1.0, -1022) == 0x1p-1022);
3436     int x;
3437     double n = frexp(0x1p-1024, x);
3438     assert(n == 0.5);
3439     assert(x==-1023);
3440     assert(ldexp(n, x)==0x1p-1024);
3441 }
3442 
3443 @safe pure nothrow @nogc unittest
3444 {
3445     assert(ldexp(1.0f, -128) == 0x1p-128f);
3446     assert(ldexp(1.0f, -126) == 0x1p-126f);
3447     int x;
3448     float n = frexp(0x1p-128f, x);
3449     assert(n == 0.5f);
3450     assert(x==-127);
3451     assert(ldexp(n, x)==0x1p-128f);
3452 }
3453 */
3454 
3455 @safe @nogc nothrow unittest
3456 {
3457     static real[3][] vals =    // value,exp,ldexp
3458     [
3459     [    0,    0,    0],
3460     [    1,    0,    1],
3461     [    -1,    0,    -1],
3462     [    1,    1,    2],
3463     [    123,    10,    125952],
3464     [    real.max,    int.max,    real.infinity],
3465     [    real.max,    -int.max,    0],
3466     [    real.min_normal,    -int.max,    0],
3467     ];
3468     int i;
3469 
3470     for (i = 0; i < vals.length; i++)
3471     {
3472         real x = vals[i][0];
3473         int exp = cast(int) vals[i][1];
3474         real z = vals[i][2];
3475         real l = ldexp(x, exp);
3476 
3477         assert(equalsDigit(z, l, 7));
3478     }
3479 
3480     real function(real, int) pldexp = &ldexp;
3481     assert(pldexp != null);
3482 }
3483 
3484 private
3485 {
3486     version (INLINE_YL2X) {} else
3487     {
3488         static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
3489         {
3490             // Coefficients for log(1 + x) = x - x**2/2 + x**3 P(x)/Q(x)
3491             static immutable real[13] logCoeffsP = [
3492                 1.313572404063446165910279910527789794488E4L,
3493                 7.771154681358524243729929227226708890930E4L,
3494                 2.014652742082537582487669938141683759923E5L,
3495                 3.007007295140399532324943111654767187848E5L,
3496                 2.854829159639697837788887080758954924001E5L,
3497                 1.797628303815655343403735250238293741397E5L,
3498                 7.594356839258970405033155585486712125861E4L,
3499                 2.128857716871515081352991964243375186031E4L,
3500                 3.824952356185897735160588078446136783779E3L,
3501                 4.114517881637811823002128927449878962058E2L,
3502                 2.321125933898420063925789532045674660756E1L,
3503                 4.998469661968096229986658302195402690910E-1L,
3504                 1.538612243596254322971797716843006400388E-6L
3505             ];
3506             static immutable real[13] logCoeffsQ = [
3507                 3.940717212190338497730839731583397586124E4L,
3508                 2.626900195321832660448791748036714883242E5L,
3509                 7.777690340007566932935753241556479363645E5L,
3510                 1.347518538384329112529391120390701166528E6L,
3511                 1.514882452993549494932585972882995548426E6L,
3512                 1.158019977462989115839826904108208787040E6L,
3513                 6.132189329546557743179177159925690841200E5L,
3514                 2.248234257620569139969141618556349415120E5L,
3515                 5.605842085972455027590989944010492125825E4L,
3516                 9.147150349299596453976674231612674085381E3L,
3517                 9.104928120962988414618126155557301584078E2L,
3518                 4.839208193348159620282142911143429644326E1L,
3519                 1.0
3520             ];
3521 
3522             // Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2)
3523             // where z = 2(x-1)/(x+1)
3524             static immutable real[6] logCoeffsR = [
3525                 -8.828896441624934385266096344596648080902E-1L,
3526                 8.057002716646055371965756206836056074715E1L,
3527                 -2.024301798136027039250415126250455056397E3L,
3528                 2.048819892795278657810231591630928516206E4L,
3529                 -8.977257995689735303686582344659576526998E4L,
3530                 1.418134209872192732479751274970992665513E5L
3531             ];
3532             static immutable real[6] logCoeffsS = [
3533                 1.701761051846631278975701529965589676574E6L
3534                 -1.332535117259762928288745111081235577029E6L,
3535                 4.001557694070773974936904547424676279307E5L,
3536                 -5.748542087379434595104154610899551484314E4L,
3537                 3.998526750980007367835804959888064681098E3L,
3538                 -1.186359407982897997337150403816839480438E2L,
3539                 1.0
3540             ];
3541         }
3542         else
3543         {
3544             // Coefficients for log(1 + x) = x - x**2/2 + x**3 P(x)/Q(x)
3545             static immutable real[7] logCoeffsP = [
3546                 2.0039553499201281259648E1L,
3547                 5.7112963590585538103336E1L,
3548                 6.0949667980987787057556E1L,
3549                 2.9911919328553073277375E1L,
3550                 6.5787325942061044846969E0L,
3551                 4.9854102823193375972212E-1L,
3552                 4.5270000862445199635215E-5L,
3553             ];
3554             static immutable real[7] logCoeffsQ = [
3555                 6.0118660497603843919306E1L,
3556                 2.1642788614495947685003E2L,
3557                 3.0909872225312059774938E2L,
3558                 2.2176239823732856465394E2L,
3559                 8.3047565967967209469434E1L,
3560                 1.5062909083469192043167E1L,
3561                 1.0000000000000000000000E0L,
3562             ];
3563 
3564             // Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2)
3565             // where z = 2(x-1)/(x+1)
3566             static immutable real[4] logCoeffsR = [
3567                -3.5717684488096787370998E1L,
3568                 1.0777257190312272158094E1L,
3569                -7.1990767473014147232598E-1L,
3570                 1.9757429581415468984296E-3L,
3571             ];
3572             static immutable real[4] logCoeffsS = [
3573                -4.2861221385716144629696E2L,
3574                 1.9361891836232102174846E2L,
3575                -2.6201045551331104417768E1L,
3576                 1.0000000000000000000000E0L,
3577             ];
3578         }
3579     }
3580 }
3581 
3582 /**************************************
3583  * Calculate the natural logarithm of x.
3584  *
3585  *    $(TABLE_SV
3586  *    $(TR $(TH x)            $(TH log(x))    $(TH divide by 0?) $(TH invalid?))
3587  *    $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no))
3588  *    $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes))
3589  *    $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))
3590  *    )
3591  */
3592 real log(real x) @safe pure nothrow @nogc
3593 {
3594     version (INLINE_YL2X)
3595         return core.math.yl2x(x, LN2);
3596     else
3597     {
3598         // C1 + C2 = LN2.
3599         enum real C1 = 6.93145751953125E-1L;
3600         enum real C2 = 1.428606820309417232121458176568075500134E-6L;
3601 
3602         // Special cases.
3603         if (isNaN(x))
3604             return x;
3605         if (isInfinity(x) && !signbit(x))
3606             return x;
3607         if (x == 0.0)
3608             return -real.infinity;
3609         if (x < 0.0)
3610             return real.nan;
3611 
3612         // Separate mantissa from exponent.
3613         // Note, frexp is used so that denormal numbers will be handled properly.
3614         real y, z;
3615         int exp;
3616 
3617         x = frexp(x, exp);
3618 
3619         // Logarithm using log(x) = z + z^^3 R(z) / S(z),
3620         // where z = 2(x - 1)/(x + 1)
3621         if ((exp > 2) || (exp < -2))
3622         {
3623             if (x < SQRT1_2)
3624             {   // 2(2x - 1)/(2x + 1)
3625                 exp -= 1;
3626                 z = x - 0.5;
3627                 y = 0.5 * z + 0.5;
3628             }
3629             else
3630             {   // 2(x - 1)/(x + 1)
3631                 z = x - 0.5;
3632                 z -= 0.5;
3633                 y = 0.5 * x  + 0.5;
3634             }
3635             x = z / y;
3636             z = x * x;
3637             z = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));
3638             z += exp * C2;
3639             z += x;
3640             z += exp * C1;
3641 
3642             return z;
3643         }
3644 
3645         // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
3646         if (x < SQRT1_2)
3647         {
3648             exp -= 1;
3649             x = 2.0 * x - 1.0;
3650         }
3651         else
3652         {
3653             x = x - 1.0;
3654         }
3655         z = x * x;
3656         y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));
3657         y += exp * C2;
3658         z = y - 0.5 * z;
3659 
3660         // Note, the sum of above terms does not exceed x/4,
3661         // so it contributes at most about 1/4 lsb to the error.
3662         z += x;
3663         z += exp * C1;
3664 
3665         return z;
3666     }
3667 }
3668 
3669 ///
3670 @safe pure nothrow @nogc unittest
3671 {
3672     assert(feqrel(log(E), 1) >= real.mant_dig - 1);
3673 }
3674 
3675 /**************************************
3676  * Calculate the base-10 logarithm of x.
3677  *
3678  *      $(TABLE_SV
3679  *      $(TR $(TH x)            $(TH log10(x))  $(TH divide by 0?) $(TH invalid?))
3680  *      $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no))
3681  *      $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes))
3682  *      $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no))
3683  *      )
3684  */
3685 real log10(real x) @safe pure nothrow @nogc
3686 {
3687     version (INLINE_YL2X)
3688         return core.math.yl2x(x, LOG2);
3689     else
3690     {
3691         // log10(2) split into two parts.
3692         enum real L102A =  0.3125L;
3693         enum real L102B = -1.14700043360188047862611052755069732318101185E-2L;
3694 
3695         // log10(e) split into two parts.
3696         enum real L10EA =  0.5L;
3697         enum real L10EB = -6.570551809674817234887108108339491770560299E-2L;
3698 
3699         // Special cases are the same as for log.
3700         if (isNaN(x))
3701             return x;
3702         if (isInfinity(x) && !signbit(x))
3703             return x;
3704         if (x == 0.0)
3705             return -real.infinity;
3706         if (x < 0.0)
3707             return real.nan;
3708 
3709         // Separate mantissa from exponent.
3710         // Note, frexp is used so that denormal numbers will be handled properly.
3711         real y, z;
3712         int exp;
3713 
3714         x = frexp(x, exp);
3715 
3716         // Logarithm using log(x) = z + z^^3 R(z) / S(z),
3717         // where z = 2(x - 1)/(x + 1)
3718         if ((exp > 2) || (exp < -2))
3719         {
3720             if (x < SQRT1_2)
3721             {   // 2(2x - 1)/(2x + 1)
3722                 exp -= 1;
3723                 z = x - 0.5;
3724                 y = 0.5 * z + 0.5;
3725             }
3726             else
3727             {   // 2(x - 1)/(x + 1)
3728                 z = x - 0.5;
3729                 z -= 0.5;
3730                 y = 0.5 * x  + 0.5;
3731             }
3732             x = z / y;
3733             z = x * x;
3734             y = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));
3735             goto Ldone;
3736         }
3737 
3738         // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
3739         if (x < SQRT1_2)
3740         {
3741             exp -= 1;
3742             x = 2.0 * x - 1.0;
3743         }
3744         else
3745             x = x - 1.0;
3746 
3747         z = x * x;
3748         y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));
3749         y = y - 0.5 * z;
3750 
3751         // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
3752         // This sequence of operations is critical and it may be horribly
3753         // defeated by some compiler optimizers.
3754     Ldone:
3755         z = y * L10EB;
3756         z += x * L10EB;
3757         z += exp * L102B;
3758         z += y * L10EA;
3759         z += x * L10EA;
3760         z += exp * L102A;
3761 
3762         return z;
3763     }
3764 }
3765 
3766 ///
3767 @safe pure nothrow @nogc unittest
3768 {
3769     assert(fabs(log10(1000) - 3) < .000001);
3770 }
3771 
3772 /**
3773  * Calculates the natural logarithm of 1 + x.
3774  *
3775  * For very small x, log1p(x) will be more accurate than
3776  * log(1 + x).
3777  *
3778  *  $(TABLE_SV
3779  *  $(TR $(TH x)            $(TH log1p(x))     $(TH divide by 0?) $(TH invalid?))
3780  *  $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no)           $(TD no))
3781  *  $(TR $(TD -1.0)         $(TD -$(INFIN))    $(TD yes)          $(TD no))
3782  *  $(TR $(TD $(LT)-1.0)    $(TD -$(NAN))      $(TD no)           $(TD yes))
3783  *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN))    $(TD no)           $(TD no))
3784  *  )
3785  */
3786 real log1p(real x) @safe pure nothrow @nogc
3787 {
3788     version (INLINE_YL2X)
3789     {
3790         // On x87, yl2xp1 is valid if and only if -0.5 <= lg(x) <= 0.5,
3791         //    ie if -0.29 <= x <= 0.414
3792         return (fabs(x) <= 0.25)  ? core.math.yl2xp1(x, LN2) : core.math.yl2x(x+1, LN2);
3793     }
3794     else
3795     {
3796         // Special cases.
3797         if (isNaN(x) || x == 0.0)
3798             return x;
3799         if (isInfinity(x) && !signbit(x))
3800             return x;
3801         if (x == -1.0)
3802             return -real.infinity;
3803         if (x < -1.0)
3804             return real.nan;
3805 
3806         return log(x + 1.0);
3807     }
3808 }
3809 
3810 ///
3811 @safe pure unittest
3812 {
3813     assert(isIdentical(log1p(0.0), 0.0));
3814     assert(log1p(1.0).feqrel(0.69314) > 16);
3815 
3816     assert(log1p(-1.0) == -real.infinity);
3817     assert(isNaN(log1p(-2.0)));
3818     assert(log1p(real.nan) is real.nan);
3819     assert(log1p(-real.nan) is -real.nan);
3820     assert(log1p(real.infinity) == real.infinity);
3821 }
3822 
3823 /***************************************
3824  * Calculates the base-2 logarithm of x:
3825  * $(SUB log, 2)x
3826  *
3827  *  $(TABLE_SV
3828  *  $(TR $(TH x)            $(TH log2(x))   $(TH divide by 0?) $(TH invalid?))
3829  *  $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes)          $(TD no) )
3830  *  $(TR $(TD $(LT)0.0)     $(TD $(NAN))    $(TD no)           $(TD yes) )
3831  *  $(TR $(TD +$(INFIN))    $(TD +$(INFIN)) $(TD no)           $(TD no) )
3832  *  )
3833  */
3834 real log2(real x) @safe pure nothrow @nogc
3835 {
3836     version (INLINE_YL2X)
3837         return core.math.yl2x(x, 1.0L);
3838     else
3839     {
3840         // Special cases are the same as for log.
3841         if (isNaN(x))
3842             return x;
3843         if (isInfinity(x) && !signbit(x))
3844             return x;
3845         if (x == 0.0)
3846             return -real.infinity;
3847         if (x < 0.0)
3848             return real.nan;
3849 
3850         // Separate mantissa from exponent.
3851         // Note, frexp is used so that denormal numbers will be handled properly.
3852         real y, z;
3853         int exp;
3854 
3855         x = frexp(x, exp);
3856 
3857         // Logarithm using log(x) = z + z^^3 R(z) / S(z),
3858         // where z = 2(x - 1)/(x + 1)
3859         if ((exp > 2) || (exp < -2))
3860         {
3861             if (x < SQRT1_2)
3862             {   // 2(2x - 1)/(2x + 1)
3863                 exp -= 1;
3864                 z = x - 0.5;
3865                 y = 0.5 * z + 0.5;
3866             }
3867             else
3868             {   // 2(x - 1)/(x + 1)
3869                 z = x - 0.5;
3870                 z -= 0.5;
3871                 y = 0.5 * x  + 0.5;
3872             }
3873             x = z / y;
3874             z = x * x;
3875             y = x * (z * poly(z, logCoeffsR) / poly(z, logCoeffsS));
3876             goto Ldone;
3877         }
3878 
3879         // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
3880         if (x < SQRT1_2)
3881         {
3882             exp -= 1;
3883             x = 2.0 * x - 1.0;
3884         }
3885         else
3886             x = x - 1.0;
3887 
3888         z = x * x;
3889         y = x * (z * poly(x, logCoeffsP) / poly(x, logCoeffsQ));
3890         y = y - 0.5 * z;
3891 
3892         // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
3893         // This sequence of operations is critical and it may be horribly
3894         // defeated by some compiler optimizers.
3895     Ldone:
3896         z = y * (LOG2E - 1.0);
3897         z += x * (LOG2E - 1.0);
3898         z += y;
3899         z += x;
3900         z += exp;
3901 
3902         return z;
3903     }
3904 }
3905 
3906 ///
3907 @safe unittest
3908 {
3909     assert(approxEqual(log2(1024.0L), 10));
3910 }
3911 
3912 @safe @nogc nothrow unittest
3913 {
3914     // check if values are equal to 19 decimal digits of precision
3915     assert(equalsDigit(log2(1024.0L), 10, 19));
3916 }
3917 
3918 /*****************************************
3919  * Extracts the exponent of x as a signed integral value.
3920  *
3921  * If x is subnormal, it is treated as if it were normalized.
3922  * For a positive, finite x:
3923  *
3924  * 1 $(LT)= $(I x) * FLT_RADIX$(SUPERSCRIPT -logb(x)) $(LT) FLT_RADIX
3925  *
3926  *      $(TABLE_SV
3927  *      $(TR $(TH x)                 $(TH logb(x))   $(TH divide by 0?) )
3928  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) $(TD no))
3929  *      $(TR $(TD $(PLUSMN)0.0)      $(TD -$(INFIN)) $(TD yes) )
3930  *      )
3931  */
3932 real logb(real x) @trusted nothrow @nogc
3933 {
3934     version (Win64_DMD_InlineAsm)
3935     {
3936         asm pure nothrow @nogc
3937         {
3938             naked                       ;
3939             fld     real ptr [RCX]      ;
3940             fxtract                     ;
3941             fstp    ST(0)               ;
3942             ret                         ;
3943         }
3944     }
3945     else version (MSVC_InlineAsm)
3946     {
3947         asm pure nothrow @nogc
3948         {
3949             fld     x                   ;
3950             fxtract                     ;
3951             fstp    ST(0)               ;
3952         }
3953     }
3954     else
3955         return core.stdc.math.logbl(x);
3956 }
3957 
3958 ///
3959 @safe @nogc nothrow unittest
3960 {
3961     assert(logb(1.0) == 0);
3962     assert(logb(100.0) == 6);
3963 
3964     assert(logb(0.0) == -real.infinity);
3965     assert(logb(real.infinity) == real.infinity);
3966     assert(logb(-real.infinity) == real.infinity);
3967 }
3968 
3969 /************************************
3970  * Calculates the remainder from the calculation x/y.
3971  * Returns:
3972  * The value of x - i * y, where i is the number of times that y can
3973  * be completely subtracted from x. The result has the same sign as x.
3974  *
3975  * $(TABLE_SV
3976  *  $(TR $(TH x)              $(TH y)             $(TH fmod(x, y))   $(TH invalid?))
3977  *  $(TR $(TD $(PLUSMN)0.0)   $(TD not 0.0)       $(TD $(PLUSMN)0.0) $(TD no))
3978  *  $(TR $(TD $(PLUSMNINF))   $(TD anything)      $(TD $(NAN))       $(TD yes))
3979  *  $(TR $(TD anything)       $(TD $(PLUSMN)0.0)  $(TD $(NAN))       $(TD yes))
3980  *  $(TR $(TD !=$(PLUSMNINF)) $(TD $(PLUSMNINF))  $(TD x)            $(TD no))
3981  * )
3982  */
3983 real fmod(real x, real y) @trusted nothrow @nogc
3984 {
3985     version (CRuntime_Microsoft)
3986     {
3987         return x % y;
3988     }
3989     else
3990         return core.stdc.math.fmodl(x, y);
3991 }
3992 
3993 ///
3994 @safe unittest
3995 {
3996     assert(isIdentical(fmod(0.0, 1.0), 0.0));
3997     assert(fmod(5.0, 3.0).feqrel(2.0) > 16);
3998     assert(isNaN(fmod(5.0, 0.0)));
3999 }
4000 
4001 /************************************
4002  * Breaks x into an integral part and a fractional part, each of which has
4003  * the same sign as x. The integral part is stored in i.
4004  * Returns:
4005  * The fractional part of x.
4006  *
4007  * $(TABLE_SV
4008  *  $(TR $(TH x)              $(TH i (on input))  $(TH modf(x, i))   $(TH i (on return)))
4009  *  $(TR $(TD $(PLUSMNINF))   $(TD anything)      $(TD $(PLUSMN)0.0) $(TD $(PLUSMNINF)))
4010  * )
4011  */
4012 real modf(real x, ref real i) @trusted nothrow @nogc
4013 {
4014     version (CRuntime_Microsoft)
4015     {
4016         i = trunc(x);
4017         return copysign(isInfinity(x) ? 0.0 : x - i, x);
4018     }
4019     else
4020         return core.stdc.math.modfl(x,&i);
4021 }
4022 
4023 ///
4024 @safe unittest
4025 {
4026     real frac;
4027     real intpart;
4028 
4029     frac = modf(3.14159, intpart);
4030     assert(intpart.feqrel(3.0) > 16);
4031     assert(frac.feqrel(0.14159) > 16);
4032 }
4033 
4034 /*************************************
4035  * Efficiently calculates x * 2$(SUPERSCRIPT n).
4036  *
4037  * scalbn handles underflow and overflow in
4038  * the same fashion as the basic arithmetic operators.
4039  *
4040  *      $(TABLE_SV
4041  *      $(TR $(TH x)                 $(TH scalb(x)))
4042  *      $(TR $(TD $(PLUSMNINF))      $(TD $(PLUSMNINF)) )
4043  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0) )
4044  *      )
4045  */
4046 real scalbn(real x, int n) @safe pure nothrow @nogc
4047 {
4048     if (__ctfe)
4049     {
4050         // Handle special cases.
4051         if (x == 0.0 || isInfinity(x))
4052             return x;
4053     }
4054     return core.math.ldexp(x, n);
4055 }
4056 
4057 ///
4058 @safe pure nothrow @nogc unittest
4059 {
4060     assert(scalbn(0x1.2345678abcdefp0, 999) == 0x1.2345678abcdefp999);
4061     assert(scalbn(-real.infinity, 5) == -real.infinity);
4062 }
4063 
4064 @safe pure nothrow @nogc unittest
4065 {
4066     // CTFE-able test
4067     static assert(scalbn(0x1.2345678abcdefp0, 999) == 0x1.2345678abcdefp999);
4068     static assert(scalbn(-real.infinity, 5) == -real.infinity);
4069     // Test with large exponent delta n where the result is in bounds but 2.0L ^^ n is not.
4070     enum initialExponent = real.min_exp + 2, resultExponent = real.max_exp - 2;
4071     enum int n = resultExponent - initialExponent;
4072     enum real x = 0x1.2345678abcdefp0 * (2.0L ^^ initialExponent);
4073     enum staticResult = scalbn(x, n);
4074     static assert(staticResult == 0x1.2345678abcdefp0 * (2.0L ^^ resultExponent));
4075     assert(scalbn(x, n) == staticResult);
4076 }
4077 
4078 /***************
4079  * Calculates the cube root of x.
4080  *
4081  *      $(TABLE_SV
4082  *      $(TR $(TH $(I x))            $(TH cbrt(x))           $(TH invalid?))
4083  *      $(TR $(TD $(PLUSMN)0.0)      $(TD $(PLUSMN)0.0)      $(TD no) )
4084  *      $(TR $(TD $(NAN))            $(TD $(NAN))            $(TD yes) )
4085  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no) )
4086  *      )
4087  */
4088 real cbrt(real x) @trusted nothrow @nogc
4089 {
4090     version (CRuntime_Microsoft)
4091     {
4092         version (INLINE_YL2X)
4093             return copysign(exp2(core.math.yl2x(fabs(x), 1.0L/3.0L)), x);
4094         else
4095             return core.stdc.math.cbrtl(x);
4096     }
4097     else
4098         return core.stdc.math.cbrtl(x);
4099 }
4100 
4101 ///
4102 @safe unittest
4103 {
4104     assert(cbrt(1.0).feqrel(1.0) > 16);
4105     assert(cbrt(27.0).feqrel(3.0) > 16);
4106     assert(cbrt(15.625).feqrel(2.5) > 16);
4107 }
4108 
4109 /*******************************
4110  * Returns |x|
4111  *
4112  *      $(TABLE_SV
4113  *      $(TR $(TH x)                 $(TH fabs(x)))
4114  *      $(TR $(TD $(PLUSMN)0.0)      $(TD +0.0) )
4115  *      $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )
4116  *      )
4117  */
4118 real fabs(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.fabs(x); }
4119 
4120 ///ditto
4121 pragma(inline, true)
4122 double fabs(double d) @trusted pure nothrow @nogc
4123 {
4124     ulong tmp = *cast(ulong*)&d & 0x7FFF_FFFF_FFFF_FFFF;
4125     return *cast(double*)&tmp;
4126 }
4127 
4128 ///ditto
4129 pragma(inline, true)
4130 float fabs(float f) @trusted pure nothrow @nogc
4131 {
4132     uint tmp = *cast(uint*)&f & 0x7FFF_FFFF;
4133     return *cast(float*)&tmp;
4134 }
4135 
4136 ///
4137 @safe unittest
4138 {
4139 
4140     assert(isIdentical(fabs(0.0f), 0.0f));
4141     assert(isIdentical(fabs(-0.0f), 0.0f));
4142     assert(fabs(-10.0f) == 10.0f);
4143 
4144     assert(isIdentical(fabs(0.0), 0.0));
4145     assert(isIdentical(fabs(-0.0), 0.0));
4146     assert(fabs(-10.0) == 10.0);
4147 
4148     assert(isIdentical(fabs(0.0L), 0.0L));
4149     assert(isIdentical(fabs(-0.0L), 0.0L));
4150     assert(fabs(-10.0L) == 10.0L);
4151 }
4152 
4153 @safe unittest
4154 {
4155     real function(real) pfabs = &fabs;
4156     assert(pfabs != null);
4157 }
4158 
4159 /***********************************************************************
4160  * Calculates the length of the
4161  * hypotenuse of a right-angled triangle with sides of length x and y.
4162  * The hypotenuse is the value of the square root of
4163  * the sums of the squares of x and y:
4164  *
4165  *      sqrt($(POWER x, 2) + $(POWER y, 2))
4166  *
4167  * Note that hypot(x, y), hypot(y, x) and
4168  * hypot(x, -y) are equivalent.
4169  *
4170  *  $(TABLE_SV
4171  *  $(TR $(TH x)            $(TH y)            $(TH hypot(x, y)) $(TH invalid?))
4172  *  $(TR $(TD x)            $(TD $(PLUSMN)0.0) $(TD |x|)         $(TD no))
4173  *  $(TR $(TD $(PLUSMNINF)) $(TD y)            $(TD +$(INFIN))   $(TD no))
4174  *  $(TR $(TD $(PLUSMNINF)) $(TD $(NAN))       $(TD +$(INFIN))   $(TD no))
4175  *  )
4176  */
4177 
4178 real hypot(real x, real y) @safe pure nothrow @nogc
4179 {
4180     // Scale x and y to avoid underflow and overflow.
4181     // If one is huge and the other tiny, return the larger.
4182     // If both are huge, avoid overflow by scaling by 1/sqrt(real.max/2).
4183     // If both are tiny, avoid underflow by scaling by sqrt(real.min_normal*real.epsilon).
4184 
4185     enum real SQRTMIN = 0.5 * sqrt(real.min_normal); // This is a power of 2.
4186     enum real SQRTMAX = 1.0L / SQRTMIN; // 2^^((max_exp)/2) = nextUp(sqrt(real.max))
4187 
4188     static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
4189 
4190     // Proves that sqrt(real.max) ~~  0.5/sqrt(real.min_normal)
4191     static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
4192 
4193     real u = fabs(x);
4194     real v = fabs(y);
4195     if (!(u >= v))  // check for NaN as well.
4196     {
4197         v = u;
4198         u = fabs(y);
4199         if (u == real.infinity) return u; // hypot(inf, nan) == inf
4200         if (v == real.infinity) return v; // hypot(nan, inf) == inf
4201     }
4202 
4203     // Now u >= v, or else one is NaN.
4204     if (v >= SQRTMAX*0.5)
4205     {
4206             // hypot(huge, huge) -- avoid overflow
4207         u *= SQRTMIN*0.5;
4208         v *= SQRTMIN*0.5;
4209         return sqrt(u*u + v*v) * SQRTMAX * 2.0;
4210     }
4211 
4212     if (u <= SQRTMIN)
4213     {
4214         // hypot (tiny, tiny) -- avoid underflow
4215         // This is only necessary to avoid setting the underflow
4216         // flag.
4217         u *= SQRTMAX / real.epsilon;
4218         v *= SQRTMAX / real.epsilon;
4219         return sqrt(u*u + v*v) * SQRTMIN * real.epsilon;
4220     }
4221 
4222     if (u * real.epsilon > v)
4223     {
4224         // hypot (huge, tiny) = huge
4225         return u;
4226     }
4227 
4228     // both are in the normal range
4229     return sqrt(u*u + v*v);
4230 }
4231 
4232 ///
4233 @safe unittest
4234 {
4235     assert(hypot(1.0, 1.0).feqrel(1.4142) > 16);
4236     assert(hypot(3.0, 4.0).feqrel(5.0) > 16);
4237     assert(hypot(real.infinity, 1.0) == real.infinity);
4238     assert(hypot(real.infinity, real.nan) == real.infinity);
4239 }
4240 
4241 @safe unittest
4242 {
4243     static real[3][] vals =     // x,y,hypot
4244         [
4245             [ 0.0,     0.0,   0.0],
4246             [ 0.0,    -0.0,   0.0],
4247             [ -0.0,   -0.0,   0.0],
4248             [ 3.0,     4.0,   5.0],
4249             [ -300,   -400,   500],
4250             [0.0,      7.0,   7.0],
4251             [9.0,   9*real.epsilon,   9.0],
4252             [88/(64*sqrt(real.min_normal)), 105/(64*sqrt(real.min_normal)), 137/(64*sqrt(real.min_normal))],
4253             [88/(128*sqrt(real.min_normal)), 105/(128*sqrt(real.min_normal)), 137/(128*sqrt(real.min_normal))],
4254             [3*real.min_normal*real.epsilon, 4*real.min_normal*real.epsilon, 5*real.min_normal*real.epsilon],
4255             [ real.min_normal, real.min_normal, sqrt(2.0L)*real.min_normal],
4256             [ real.max/sqrt(2.0L), real.max/sqrt(2.0L), real.max],
4257             [ real.infinity, real.nan, real.infinity],
4258             [ real.nan, real.infinity, real.infinity],
4259             [ real.nan, real.nan, real.nan],
4260             [ real.nan, real.max, real.nan],
4261             [ real.max, real.nan, real.nan],
4262         ];
4263         for (int i = 0; i < vals.length; i++)
4264         {
4265             real x = vals[i][0];
4266             real y = vals[i][1];
4267             real z = vals[i][2];
4268             real h = hypot(x, y);
4269             assert(isIdentical(z,h) || feqrel(z, h) >= real.mant_dig - 1);
4270         }
4271 }
4272 
4273 /**************************************
4274  * Returns the value of x rounded upward to the next integer
4275  * (toward positive infinity).
4276  */
4277 real ceil(real x) @trusted pure nothrow @nogc
4278 {
4279     version (Win64_DMD_InlineAsm)
4280     {
4281         asm pure nothrow @nogc
4282         {
4283             naked                       ;
4284             fld     real ptr [RCX]      ;
4285             fstcw   8[RSP]              ;
4286             mov     AL,9[RSP]           ;
4287             mov     DL,AL               ;
4288             and     AL,0xC3             ;
4289             or      AL,0x08             ; // round to +infinity
4290             mov     9[RSP],AL           ;
4291             fldcw   8[RSP]              ;
4292             frndint                     ;
4293             mov     9[RSP],DL           ;
4294             fldcw   8[RSP]              ;
4295             ret                         ;
4296         }
4297     }
4298     else version (MSVC_InlineAsm)
4299     {
4300         short cw;
4301         asm pure nothrow @nogc
4302         {
4303             fld     x                   ;
4304             fstcw   cw                  ;
4305             mov     AL,byte ptr cw+1    ;
4306             mov     DL,AL               ;
4307             and     AL,0xC3             ;
4308             or      AL,0x08             ; // round to +infinity
4309             mov     byte ptr cw+1,AL    ;
4310             fldcw   cw                  ;
4311             frndint                     ;
4312             mov     byte ptr cw+1,DL    ;
4313             fldcw   cw                  ;
4314         }
4315     }
4316     else
4317     {
4318         // Special cases.
4319         if (isNaN(x) || isInfinity(x))
4320             return x;
4321 
4322         real y = floorImpl(x);
4323         if (y < x)
4324             y += 1.0;
4325 
4326         return y;
4327     }
4328 }
4329 
4330 ///
4331 @safe pure nothrow @nogc unittest
4332 {
4333     assert(ceil(+123.456L) == +124);
4334     assert(ceil(-123.456L) == -123);
4335     assert(ceil(-1.234L) == -1);
4336     assert(ceil(-0.123L) == 0);
4337     assert(ceil(0.0L) == 0);
4338     assert(ceil(+0.123L) == 1);
4339     assert(ceil(+1.234L) == 2);
4340     assert(ceil(real.infinity) == real.infinity);
4341     assert(isNaN(ceil(real.nan)));
4342     assert(isNaN(ceil(real.init)));
4343 }
4344 
4345 /// ditto
4346 double ceil(double x) @trusted pure nothrow @nogc
4347 {
4348     // Special cases.
4349     if (isNaN(x) || isInfinity(x))
4350         return x;
4351 
4352     double y = floorImpl(x);
4353     if (y < x)
4354         y += 1.0;
4355 
4356     return y;
4357 }
4358 
4359 @safe pure nothrow @nogc unittest
4360 {
4361     assert(ceil(+123.456) == +124);
4362     assert(ceil(-123.456) == -123);
4363     assert(ceil(-1.234) == -1);
4364     assert(ceil(-0.123) == 0);
4365     assert(ceil(0.0) == 0);
4366     assert(ceil(+0.123) == 1);
4367     assert(ceil(+1.234) == 2);
4368     assert(ceil(double.infinity) == double.infinity);
4369     assert(isNaN(ceil(double.nan)));
4370     assert(isNaN(ceil(double.init)));
4371 }
4372 
4373 /// ditto
4374 float ceil(float x) @trusted pure nothrow @nogc
4375 {
4376     // Special cases.
4377     if (isNaN(x) || isInfinity(x))
4378         return x;
4379 
4380     float y = floorImpl(x);
4381     if (y < x)
4382         y += 1.0;
4383 
4384     return y;
4385 }
4386 
4387 @safe pure nothrow @nogc unittest
4388 {
4389     assert(ceil(+123.456f) == +124);
4390     assert(ceil(-123.456f) == -123);
4391     assert(ceil(-1.234f) == -1);
4392     assert(ceil(-0.123f) == 0);
4393     assert(ceil(0.0f) == 0);
4394     assert(ceil(+0.123f) == 1);
4395     assert(ceil(+1.234f) == 2);
4396     assert(ceil(float.infinity) == float.infinity);
4397     assert(isNaN(ceil(float.nan)));
4398     assert(isNaN(ceil(float.init)));
4399 }
4400 
4401 /**************************************
4402  * Returns the value of x rounded downward to the next integer
4403  * (toward negative infinity).
4404  */
4405 real floor(real x) @trusted pure nothrow @nogc
4406 {
4407     version (Win64_DMD_InlineAsm)
4408     {
4409         asm pure nothrow @nogc
4410         {
4411             naked                       ;
4412             fld     real ptr [RCX]      ;
4413             fstcw   8[RSP]              ;
4414             mov     AL,9[RSP]           ;
4415             mov     DL,AL               ;
4416             and     AL,0xC3             ;
4417             or      AL,0x04             ; // round to -infinity
4418             mov     9[RSP],AL           ;
4419             fldcw   8[RSP]              ;
4420             frndint                     ;
4421             mov     9[RSP],DL           ;
4422             fldcw   8[RSP]              ;
4423             ret                         ;
4424         }
4425     }
4426     else version (MSVC_InlineAsm)
4427     {
4428         short cw;
4429         asm pure nothrow @nogc
4430         {
4431             fld     x                   ;
4432             fstcw   cw                  ;
4433             mov     AL,byte ptr cw+1    ;
4434             mov     DL,AL               ;
4435             and     AL,0xC3             ;
4436             or      AL,0x04             ; // round to -infinity
4437             mov     byte ptr cw+1,AL    ;
4438             fldcw   cw                  ;
4439             frndint                     ;
4440             mov     byte ptr cw+1,DL    ;
4441             fldcw   cw                  ;
4442         }
4443     }
4444     else
4445     {
4446         // Special cases.
4447         if (isNaN(x) || isInfinity(x) || x == 0.0)
4448             return x;
4449 
4450         return floorImpl(x);
4451     }
4452 }
4453 
4454 ///
4455 @safe pure nothrow @nogc unittest
4456 {
4457     assert(floor(+123.456L) == +123);
4458     assert(floor(-123.456L) == -124);
4459     assert(floor(+123.0L) == +123);
4460     assert(floor(-124.0L) == -124);
4461     assert(floor(-1.234L) == -2);
4462     assert(floor(-0.123L) == -1);
4463     assert(floor(0.0L) == 0);
4464     assert(floor(+0.123L) == 0);
4465     assert(floor(+1.234L) == 1);
4466     assert(floor(real.infinity) == real.infinity);
4467     assert(isNaN(floor(real.nan)));
4468     assert(isNaN(floor(real.init)));
4469 }
4470 
4471 /// ditto
4472 double floor(double x) @trusted pure nothrow @nogc
4473 {
4474     // Special cases.
4475     if (isNaN(x) || isInfinity(x) || x == 0.0)
4476         return x;
4477 
4478     return floorImpl(x);
4479 }
4480 
4481 @safe pure nothrow @nogc unittest
4482 {
4483     assert(floor(+123.456) == +123);
4484     assert(floor(-123.456) == -124);
4485     assert(floor(+123.0) == +123);
4486     assert(floor(-124.0) == -124);
4487     assert(floor(-1.234) == -2);
4488     assert(floor(-0.123) == -1);
4489     assert(floor(0.0) == 0);
4490     assert(floor(+0.123) == 0);
4491     assert(floor(+1.234) == 1);
4492     assert(floor(double.infinity) == double.infinity);
4493     assert(isNaN(floor(double.nan)));
4494     assert(isNaN(floor(double.init)));
4495 }
4496 
4497 /// ditto
4498 float floor(float x) @trusted pure nothrow @nogc
4499 {
4500     // Special cases.
4501     if (isNaN(x) || isInfinity(x) || x == 0.0)
4502         return x;
4503 
4504     return floorImpl(x);
4505 }
4506 
4507 @safe pure nothrow @nogc unittest
4508 {
4509     assert(floor(+123.456f) == +123);
4510     assert(floor(-123.456f) == -124);
4511     assert(floor(+123.0f) == +123);
4512     assert(floor(-124.0f) == -124);
4513     assert(floor(-1.234f) == -2);
4514     assert(floor(-0.123f) == -1);
4515     assert(floor(0.0f) == 0);
4516     assert(floor(+0.123f) == 0);
4517     assert(floor(+1.234f) == 1);
4518     assert(floor(float.infinity) == float.infinity);
4519     assert(isNaN(floor(float.nan)));
4520     assert(isNaN(floor(float.init)));
4521 }
4522 
4523 /**
4524  * Round `val` to a multiple of `unit`. `rfunc` specifies the rounding
4525  * function to use; by default this is `rint`, which uses the current
4526  * rounding mode.
4527  */
4528 Unqual!F quantize(alias rfunc = rint, F)(const F val, const F unit)
4529 if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F)
4530 {
4531     typeof(return) ret = val;
4532     if (unit != 0)
4533     {
4534         const scaled = val / unit;
4535         if (!scaled.isInfinity)
4536             ret = rfunc(scaled) * unit;
4537     }
4538     return ret;
4539 }
4540 
4541 ///
4542 @safe pure nothrow @nogc unittest
4543 {
4544     assert(12345.6789L.quantize(0.01L) == 12345.68L);
4545     assert(12345.6789L.quantize!floor(0.01L) == 12345.67L);
4546     assert(12345.6789L.quantize(22.0L) == 12342.0L);
4547 }
4548 
4549 ///
4550 @safe pure nothrow @nogc unittest
4551 {
4552     assert(12345.6789L.quantize(0) == 12345.6789L);
4553     assert(12345.6789L.quantize(real.infinity).isNaN);
4554     assert(12345.6789L.quantize(real.nan).isNaN);
4555     assert(real.infinity.quantize(0.01L) == real.infinity);
4556     assert(real.infinity.quantize(real.nan).isNaN);
4557     assert(real.nan.quantize(0.01L).isNaN);
4558     assert(real.nan.quantize(real.infinity).isNaN);
4559     assert(real.nan.quantize(real.nan).isNaN);
4560 }
4561 
4562 /**
4563  * Round `val` to a multiple of `pow(base, exp)`. `rfunc` specifies the
4564  * rounding function to use; by default this is `rint`, which uses the
4565  * current rounding mode.
4566  */
4567 Unqual!F quantize(real base, alias rfunc = rint, F, E)(const F val, const E exp)
4568 if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E)
4569 {
4570     // TODO: Compile-time optimization for power-of-two bases?
4571     return quantize!rfunc(val, pow(cast(F) base, exp));
4572 }
4573 
4574 /// ditto
4575 Unqual!F quantize(real base, long exp = 1, alias rfunc = rint, F)(const F val)
4576 if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F)
4577 {
4578     enum unit = cast(F) pow(base, exp);
4579     return quantize!rfunc(val, unit);
4580 }
4581 
4582 ///
4583 @safe pure nothrow @nogc unittest
4584 {
4585     assert(12345.6789L.quantize!10(-2) == 12345.68L);
4586     assert(12345.6789L.quantize!(10, -2) == 12345.68L);
4587     assert(12345.6789L.quantize!(10, floor)(-2) == 12345.67L);
4588     assert(12345.6789L.quantize!(10, -2, floor) == 12345.67L);
4589 
4590     assert(12345.6789L.quantize!22(1) == 12342.0L);
4591     assert(12345.6789L.quantize!22 == 12342.0L);
4592 }
4593 
4594 @safe pure nothrow @nogc unittest
4595 {
4596     import std.meta : AliasSeq;
4597 
4598     static foreach (F; AliasSeq!(real, double, float))
4599     {{
4600         const maxL10 = cast(int) F.max.log10.floor;
4601         const maxR10 = pow(cast(F) 10, maxL10);
4602         assert((cast(F) 0.9L * maxR10).quantize!10(maxL10) ==  maxR10);
4603         assert((cast(F)-0.9L * maxR10).quantize!10(maxL10) == -maxR10);
4604 
4605         assert(F.max.quantize(F.min_normal) == F.max);
4606         assert((-F.max).quantize(F.min_normal) == -F.max);
4607         assert(F.min_normal.quantize(F.max) == 0);
4608         assert((-F.min_normal).quantize(F.max) == 0);
4609         assert(F.min_normal.quantize(F.min_normal) == F.min_normal);
4610         assert((-F.min_normal).quantize(F.min_normal) == -F.min_normal);
4611     }}
4612 }
4613 
4614 /******************************************
4615  * Rounds x to the nearest integer value, using the current rounding
4616  * mode.
4617  *
4618  * Unlike the rint functions, nearbyint does not raise the
4619  * FE_INEXACT exception.
4620  */
4621 real nearbyint(real x) @safe pure nothrow @nogc
4622 {
4623     return core.stdc.math.nearbyintl(x);
4624 }
4625 
4626 ///
4627 @safe pure unittest
4628 {
4629     assert(nearbyint(0.4) == 0);
4630     assert(nearbyint(0.5) == 0);
4631     assert(nearbyint(0.6) == 1);
4632     assert(nearbyint(100.0) == 100);
4633 
4634     assert(isNaN(nearbyint(real.nan)));
4635     assert(nearbyint(real.infinity) == real.infinity);
4636     assert(nearbyint(-real.infinity) == -real.infinity);
4637 }
4638 
4639 /**********************************
4640  * Rounds x to the nearest integer value, using the current rounding
4641  * mode.
4642  *
4643  * If the return value is not equal to x, the FE_INEXACT
4644  * exception is raised.
4645  *
4646  * $(LREF nearbyint) performs the same operation, but does
4647  * not set the FE_INEXACT exception.
4648  */
4649 real rint(real x) @safe pure nothrow @nogc { pragma(inline, true); return core.math.rint(x); }
4650 //FIXME
4651 ///ditto
4652 double rint(double x) @safe pure nothrow @nogc { return rint(cast(real) x); }
4653 //FIXME
4654 ///ditto
4655 float rint(float x) @safe pure nothrow @nogc { return rint(cast(real) x); }
4656 
4657 ///
4658 @safe unittest
4659 {
4660     version (IeeeFlagsSupport) resetIeeeFlags();
4661     assert(rint(0.4) == 0);
4662     version (IeeeFlagsSupport) assert(ieeeFlags.inexact);
4663 
4664     assert(rint(0.5) == 0);
4665     assert(rint(0.6) == 1);
4666     assert(rint(100.0) == 100);
4667 
4668     assert(isNaN(rint(real.nan)));
4669     assert(rint(real.infinity) == real.infinity);
4670     assert(rint(-real.infinity) == -real.infinity);
4671 }
4672 
4673 @safe unittest
4674 {
4675     real function(real) print = &rint;
4676     assert(print != null);
4677 }
4678 
4679 /***************************************
4680  * Rounds x to the nearest integer value, using the current rounding
4681  * mode.
4682  *
4683  * This is generally the fastest method to convert a floating-point number
4684  * to an integer. Note that the results from this function
4685  * depend on the rounding mode, if the fractional part of x is exactly 0.5.
4686  * If using the default rounding mode (ties round to even integers)
4687  * lrint(4.5) == 4, lrint(5.5)==6.
4688  */
4689 long lrint(real x) @trusted pure nothrow @nogc
4690 {
4691     version (InlineAsm_X86_Any)
4692     {
4693         version (Win64)
4694         {
4695             asm pure nothrow @nogc
4696             {
4697                 naked;
4698                 fld     real ptr [RCX];
4699                 fistp   qword ptr 8[RSP];
4700                 mov     RAX,8[RSP];
4701                 ret;
4702             }
4703         }
4704         else
4705         {
4706             long n;
4707             asm pure nothrow @nogc
4708             {
4709                 fld x;
4710                 fistp n;
4711             }
4712             return n;
4713         }
4714     }
4715     else
4716     {
4717         alias F = floatTraits!(real);
4718         static if (F.realFormat == RealFormat.ieeeDouble)
4719         {
4720             long result;
4721 
4722             // Rounding limit when casting from real(double) to ulong.
4723             enum real OF = 4.50359962737049600000E15L;
4724 
4725             uint* vi = cast(uint*)(&x);
4726 
4727             // Find the exponent and sign
4728             uint msb = vi[MANTISSA_MSB];
4729             uint lsb = vi[MANTISSA_LSB];
4730             int exp = ((msb >> 20) & 0x7ff) - 0x3ff;
4731             const int sign = msb >> 31;
4732             msb &= 0xfffff;
4733             msb |= 0x100000;
4734 
4735             if (exp < 63)
4736             {
4737                 if (exp >= 52)
4738                     result = (cast(long) msb << (exp - 20)) | (lsb << (exp - 52));
4739                 else
4740                 {
4741                     // Adjust x and check result.
4742                     const real j = sign ? -OF : OF;
4743                     x = (j + x) - j;
4744                     msb = vi[MANTISSA_MSB];
4745                     lsb = vi[MANTISSA_LSB];
4746                     exp = ((msb >> 20) & 0x7ff) - 0x3ff;
4747                     msb &= 0xfffff;
4748                     msb |= 0x100000;
4749 
4750                     if (exp < 0)
4751                         result = 0;
4752                     else if (exp < 20)
4753                         result = cast(long) msb >> (20 - exp);
4754                     else if (exp == 20)
4755                         result = cast(long) msb;
4756                     else
4757                         result = (cast(long) msb << (exp - 20)) | (lsb >> (52 - exp));
4758                 }
4759             }
4760             else
4761             {
4762                 // It is left implementation defined when the number is too large.
4763                 return cast(long) x;
4764             }
4765 
4766             return sign ? -result : result;
4767         }
4768         else static if (F.realFormat == RealFormat.ieeeExtended)
4769         {
4770             long result;
4771 
4772             // Rounding limit when casting from real(80-bit) to ulong.
4773             enum real OF = 9.22337203685477580800E18L;
4774 
4775             ushort* vu = cast(ushort*)(&x);
4776             uint* vi = cast(uint*)(&x);
4777 
4778             // Find the exponent and sign
4779             int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
4780             const int sign = (vu[F.EXPPOS_SHORT] >> 15) & 1;
4781 
4782             if (exp < 63)
4783             {
4784                 // Adjust x and check result.
4785                 const real j = sign ? -OF : OF;
4786                 x = (j + x) - j;
4787                 exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
4788 
4789                 version (LittleEndian)
4790                 {
4791                     if (exp < 0)
4792                         result = 0;
4793                     else if (exp <= 31)
4794                         result = vi[1] >> (31 - exp);
4795                     else
4796                         result = (cast(long) vi[1] << (exp - 31)) | (vi[0] >> (63 - exp));
4797                 }
4798                 else
4799                 {
4800                     if (exp < 0)
4801                         result = 0;
4802                     else if (exp <= 31)
4803                         result = vi[1] >> (31 - exp);
4804                     else
4805                         result = (cast(long) vi[1] << (exp - 31)) | (vi[2] >> (63 - exp));
4806                 }
4807             }
4808             else
4809             {
4810                 // It is left implementation defined when the number is too large
4811                 // to fit in a 64bit long.
4812                 return cast(long) x;
4813             }
4814 
4815             return sign ? -result : result;
4816         }
4817         else static if (F.realFormat == RealFormat.ieeeQuadruple)
4818         {
4819             const vu = cast(ushort*)(&x);
4820 
4821             // Find the exponent and sign
4822             const sign = (vu[F.EXPPOS_SHORT] >> 15) & 1;
4823             if ((vu[F.EXPPOS_SHORT] & F.EXPMASK) - (F.EXPBIAS + 1) > 63)
4824             {
4825                 // The result is left implementation defined when the number is
4826                 // too large to fit in a 64 bit long.
4827                 return cast(long) x;
4828             }
4829 
4830             // Force rounding of lower bits according to current rounding
4831             // mode by adding ±2^-112 and subtracting it again.
4832             enum OF = 5.19229685853482762853049632922009600E33L;
4833             const j = sign ? -OF : OF;
4834             x = (j + x) - j;
4835 
4836             const exp = (vu[F.EXPPOS_SHORT] & F.EXPMASK) - (F.EXPBIAS + 1);
4837             const implicitOne = 1UL << 48;
4838             auto vl = cast(ulong*)(&x);
4839             vl[MANTISSA_MSB] &= implicitOne - 1;
4840             vl[MANTISSA_MSB] |= implicitOne;
4841 
4842             long result;
4843 
4844             if (exp < 0)
4845                 result = 0;
4846             else if (exp <= 48)
4847                 result = vl[MANTISSA_MSB] >> (48 - exp);
4848             else
4849                 result = (vl[MANTISSA_MSB] << (exp - 48)) | (vl[MANTISSA_LSB] >> (112 - exp));
4850 
4851             return sign ? -result : result;
4852         }
4853         else
4854         {
4855             static assert(false, "real type not supported by lrint()");
4856         }
4857     }
4858 }
4859 
4860 ///
4861 @safe pure nothrow @nogc unittest
4862 {
4863     assert(lrint(4.5) == 4);
4864     assert(lrint(5.5) == 6);
4865     assert(lrint(-4.5) == -4);
4866     assert(lrint(-5.5) == -6);
4867 
4868     assert(lrint(int.max - 0.5) == 2147483646L);
4869     assert(lrint(int.max + 0.5) == 2147483648L);
4870     assert(lrint(int.min - 0.5) == -2147483648L);
4871     assert(lrint(int.min + 0.5) == -2147483648L);
4872 }
4873 
4874 static if (real.mant_dig >= long.sizeof * 8)
4875 {
4876     @safe pure nothrow @nogc unittest
4877     {
4878         assert(lrint(long.max - 1.5L) == long.max - 1);
4879         assert(lrint(long.max - 0.5L) == long.max - 1);
4880         assert(lrint(long.min + 0.5L) == long.min);
4881         assert(lrint(long.min + 1.5L) == long.min + 2);
4882     }
4883 }
4884 
4885 /*******************************************
4886  * Return the value of x rounded to the nearest integer.
4887  * If the fractional part of x is exactly 0.5, the return value is
4888  * rounded away from zero.
4889  *
4890  * Returns:
4891  *     A `real`.
4892  */
4893 auto round(real x) @trusted nothrow @nogc
4894 {
4895     version (CRuntime_Microsoft)
4896     {
4897         auto old = FloatingPointControl.getControlState();
4898         FloatingPointControl.setControlState(
4899             (old & (-1 - FloatingPointControl.roundingMask)) | FloatingPointControl.roundToZero
4900         );
4901         x = rint((x >= 0) ? x + 0.5 : x - 0.5);
4902         FloatingPointControl.setControlState(old);
4903         return x;
4904     }
4905     else
4906         return core.stdc.math.roundl(x);
4907 }
4908 
4909 ///
4910 @safe nothrow @nogc unittest
4911 {
4912     assert(round(4.5) == 5);
4913     assert(round(5.4) == 5);
4914     assert(round(-4.5) == -5);
4915     assert(round(-5.1) == -5);
4916 }
4917 
4918 // assure purity on Posix
4919 version (Posix)
4920 {
4921     @safe pure nothrow @nogc unittest
4922     {
4923         assert(round(4.5) == 5);
4924     }
4925 }
4926 
4927 /**********************************************
4928  * Return the value of x rounded to the nearest integer.
4929  *
4930  * If the fractional part of x is exactly 0.5, the return value is rounded
4931  * away from zero.
4932  *
4933  * $(BLUE This function is not implemented for Digital Mars C runtime.)
4934  */
4935 long lround(real x) @trusted nothrow @nogc
4936 {
4937     version (CRuntime_DigitalMars)
4938         assert(0, "lround not implemented");
4939     else
4940         return core.stdc.math.llroundl(x);
4941 }
4942 
4943 ///
4944 @safe nothrow @nogc unittest
4945 {
4946     version (CRuntime_DigitalMars) {}
4947     else
4948     {
4949         assert(lround(0.49) == 0);
4950         assert(lround(0.5) == 1);
4951         assert(lround(1.5) == 2);
4952     }
4953 }
4954 
4955 /**
4956  Returns the integer portion of x, dropping the fractional portion.
4957  This is also known as "chop" rounding.
4958  `pure` on all platforms.
4959  */
4960 real trunc(real x) @trusted nothrow @nogc pure
4961 {
4962     version (Win64_DMD_InlineAsm)
4963     {
4964         asm pure nothrow @nogc
4965         {
4966             naked                       ;
4967             fld     real ptr [RCX]      ;
4968             fstcw   8[RSP]              ;
4969             mov     AL,9[RSP]           ;
4970             mov     DL,AL               ;
4971             and     AL,0xC3             ;
4972             or      AL,0x0C             ; // round to 0
4973             mov     9[RSP],AL           ;
4974             fldcw   8[RSP]              ;
4975             frndint                     ;
4976             mov     9[RSP],DL           ;
4977             fldcw   8[RSP]              ;
4978             ret                         ;
4979         }
4980     }
4981     else version (MSVC_InlineAsm)
4982     {
4983         short cw;
4984         asm pure nothrow @nogc
4985         {
4986             fld     x                   ;
4987             fstcw   cw                  ;
4988             mov     AL,byte ptr cw+1    ;
4989             mov     DL,AL               ;
4990             and     AL,0xC3             ;
4991             or      AL,0x0C             ; // round to 0
4992             mov     byte ptr cw+1,AL    ;
4993             fldcw   cw                  ;
4994             frndint                     ;
4995             mov     byte ptr cw+1,DL    ;
4996             fldcw   cw                  ;
4997         }
4998     }
4999     else
5000         return core.stdc.math.truncl(x);
5001 }
5002 
5003 ///
5004 @safe pure unittest
5005 {
5006     assert(trunc(0.01) == 0);
5007     assert(trunc(0.49) == 0);
5008     assert(trunc(0.5) == 0);
5009     assert(trunc(1.5) == 1);
5010 }
5011 
5012 /****************************************************
5013  * Calculate the remainder x REM y, following IEC 60559.
5014  *
5015  * REM is the value of x - y * n, where n is the integer nearest the exact
5016  * value of x / y.
5017  * If |n - x / y| == 0.5, n is even.
5018  * If the result is zero, it has the same sign as x.
5019  * Otherwise, the sign of the result is the sign of x / y.
5020  * Precision mode has no effect on the remainder functions.
5021  *
5022  * remquo returns `n` in the parameter `n`.
5023  *
5024  * $(TABLE_SV
5025  *  $(TR $(TH x)               $(TH y)            $(TH remainder(x, y)) $(TH n)   $(TH invalid?))
5026  *  $(TR $(TD $(PLUSMN)0.0)    $(TD not 0.0)      $(TD $(PLUSMN)0.0)    $(TD 0.0) $(TD no))
5027  *  $(TR $(TD $(PLUSMNINF))    $(TD anything)     $(TD -$(NAN))         $(TD ?)   $(TD yes))
5028  *  $(TR $(TD anything)        $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)$(NAN)) $(TD ?)   $(TD yes))
5029  *  $(TR $(TD != $(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x)               $(TD ?)   $(TD no))
5030  * )
5031  */
5032 real remainder(real x, real y) @trusted nothrow @nogc
5033 {
5034     return core.stdc.math.remainderl(x, y);
5035 }
5036 
5037 /// ditto
5038 real remquo(real x, real y, out int n) @trusted nothrow @nogc  /// ditto
5039 {
5040     return core.stdc.math.remquol(x, y, &n);
5041 }
5042 
5043 ///
5044 @safe @nogc nothrow unittest
5045 {
5046     assert(remainder(5.1, 3.0).feqrel(-0.9) > 16);
5047     assert(remainder(-5.1, 3.0).feqrel(0.9) > 16);
5048     assert(remainder(0.0, 3.0) == 0.0);
5049 
5050     assert(isNaN(remainder(1.0, 0.0)));
5051     assert(isNaN(remainder(-1.0, 0.0)));
5052 }
5053 
5054 ///
5055 @safe @nogc nothrow unittest
5056 {
5057     int n;
5058 
5059     assert(remquo(5.1, 3.0, n).feqrel(-0.9) > 16 && n == 2);
5060     assert(remquo(-5.1, 3.0, n).feqrel(0.9) > 16 && n == -2);
5061     assert(remquo(0.0, 3.0, n) == 0.0 && n == 0);
5062 }
5063 
5064 
5065 version (IeeeFlagsSupport)
5066 {
5067 
5068 /** IEEE exception status flags ('sticky bits')
5069 
5070  These flags indicate that an exceptional floating-point condition has occurred.
5071  They indicate that a NaN or an infinity has been generated, that a result
5072  is inexact, or that a signalling NaN has been encountered. If floating-point
5073  exceptions are enabled (unmasked), a hardware exception will be generated
5074  instead of setting these flags.
5075  */
5076 struct IeeeFlags
5077 {
5078 nothrow @nogc:
5079 
5080 private:
5081     // The x87 FPU status register is 16 bits.
5082     // The Pentium SSE2 status register is 32 bits.
5083     // The ARM and PowerPC FPSCR is a 32-bit register.
5084     // The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting).
5085     // The RISC-V (32 & 64 bit) fcsr is 32-bit register.
5086     uint flags;
5087 
5088     version (CRuntime_Microsoft)
5089     {
5090         // Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).
5091         // Applies to both x87 status word (16 bits) and SSE2 status word(32 bits).
5092         enum : int
5093         {
5094             INEXACT_MASK   = 0x20,
5095             UNDERFLOW_MASK = 0x10,
5096             OVERFLOW_MASK  = 0x08,
5097             DIVBYZERO_MASK = 0x04,
5098             INVALID_MASK   = 0x01,
5099 
5100             EXCEPTIONS_MASK = 0b11_1111
5101         }
5102         // Don't bother about subnormals, they are not supported on most CPUs.
5103         //  SUBNORMAL_MASK = 0x02;
5104     }
5105     else
5106     {
5107         enum : int
5108         {
5109             INEXACT_MASK    = core.stdc.fenv.FE_INEXACT,
5110             UNDERFLOW_MASK  = core.stdc.fenv.FE_UNDERFLOW,
5111             OVERFLOW_MASK   = core.stdc.fenv.FE_OVERFLOW,
5112             DIVBYZERO_MASK  = core.stdc.fenv.FE_DIVBYZERO,
5113             INVALID_MASK    = core.stdc.fenv.FE_INVALID,
5114             EXCEPTIONS_MASK = core.stdc.fenv.FE_ALL_EXCEPT,
5115         }
5116     }
5117 
5118     static uint getIeeeFlags() @trusted pure
5119     {
5120         version (InlineAsm_X86_Any)
5121         {
5122             ushort sw;
5123             asm pure nothrow @nogc { fstsw sw; }
5124 
5125             // OR the result with the SSE2 status register (MXCSR).
5126             if (haveSSE)
5127             {
5128                 uint mxcsr;
5129                 asm pure nothrow @nogc { stmxcsr mxcsr; }
5130                 return (sw | mxcsr) & EXCEPTIONS_MASK;
5131             }
5132             else return sw & EXCEPTIONS_MASK;
5133         }
5134         else version (SPARC)
5135         {
5136            /*
5137                int retval;
5138                asm pure nothrow @nogc { st %fsr, retval; }
5139                return retval;
5140             */
5141            assert(0, "Not yet supported");
5142         }
5143         else version (ARM)
5144         {
5145             assert(false, "Not yet supported.");
5146         }
5147         else version (RISCV_Any)
5148         {
5149             mixin(`
5150             uint result = void;
5151             asm pure nothrow @nogc
5152             {
5153                 "frflags %0" : "=r" (result);
5154             }
5155             return result;
5156             `);
5157         }
5158         else
5159             assert(0, "Not yet supported");
5160     }
5161 
5162     static void resetIeeeFlags() @trusted
5163     {
5164         version (InlineAsm_X86_Any)
5165         {
5166             asm nothrow @nogc
5167             {
5168                 fnclex;
5169             }
5170 
5171             // Also clear exception flags in MXCSR, SSE's control register.
5172             if (haveSSE)
5173             {
5174                 uint mxcsr;
5175                 asm nothrow @nogc { stmxcsr mxcsr; }
5176                 mxcsr &= ~EXCEPTIONS_MASK;
5177                 asm nothrow @nogc { ldmxcsr mxcsr; }
5178             }
5179         }
5180         else version (RISCV_Any)
5181         {
5182             mixin(`
5183             uint newValues = 0x0;
5184             asm pure nothrow @nogc
5185             {
5186                 "fsflags %0" : : "r" (newValues);
5187             }
5188             `);
5189         }
5190         else
5191         {
5192             /* SPARC:
5193               int tmpval;
5194               asm pure nothrow @nogc { st %fsr, tmpval; }
5195               tmpval &=0xFFFF_FC00;
5196               asm pure nothrow @nogc { ld tmpval, %fsr; }
5197             */
5198            assert(0, "Not yet supported");
5199         }
5200     }
5201 
5202 public:
5203     /**
5204      * The result cannot be represented exactly, so rounding occurred.
5205      * Example: `x = sin(0.1);`
5206      */
5207     @property bool inexact() @safe const { return (flags & INEXACT_MASK) != 0; }
5208 
5209     /**
5210      * A zero was generated by underflow
5211      * Example: `x = real.min*real.epsilon/2;`
5212      */
5213     @property bool underflow() @safe const { return (flags & UNDERFLOW_MASK) != 0; }
5214 
5215     /**
5216      * An infinity was generated by overflow
5217      * Example: `x = real.max*2;`
5218      */
5219     @property bool overflow() @safe const { return (flags & OVERFLOW_MASK) != 0; }
5220 
5221     /**
5222      * An infinity was generated by division by zero
5223      * Example: `x = 3/0.0;`
5224      */
5225     @property bool divByZero() @safe const { return (flags & DIVBYZERO_MASK) != 0; }
5226 
5227     /**
5228      * A machine NaN was generated.
5229      * Example: `x = real.infinity * 0.0;`
5230      */
5231     @property bool invalid() @safe const { return (flags & INVALID_MASK) != 0; }
5232 }
5233 
5234 ///
5235 @safe unittest
5236 {
5237     static void func() {
5238         int a = 10 * 10;
5239     }
5240     pragma(inline, false) static void blockopt(ref real x) {}
5241     real a = 3.5;
5242     // Set all the flags to zero
5243     resetIeeeFlags();
5244     assert(!ieeeFlags.divByZero);
5245     blockopt(a); // avoid constant propagation by the optimizer
5246     // Perform a division by zero.
5247     a /= 0.0L;
5248     assert(a == real.infinity);
5249     assert(ieeeFlags.divByZero);
5250     blockopt(a); // avoid constant propagation by the optimizer
5251     // Create a NaN
5252     a *= 0.0L;
5253     assert(ieeeFlags.invalid);
5254     assert(isNaN(a));
5255 
5256     // Check that calling func() has no effect on the
5257     // status flags.
5258     IeeeFlags f = ieeeFlags;
5259     func();
5260     assert(ieeeFlags == f);
5261 }
5262 
5263 @safe unittest
5264 {
5265     import std.meta : AliasSeq;
5266 
5267     static struct Test
5268     {
5269         void delegate() @trusted action;
5270         bool function() @trusted ieeeCheck;
5271     }
5272 
5273     static foreach (T; AliasSeq!(float, double, real))
5274     {{
5275         T x; /* Needs to be here to trick -O. It would optimize away the
5276             calculations if x were local to the function literals. */
5277         auto tests = [
5278             Test(
5279                 () { x = 1; x += 0.1L; },
5280                 () => ieeeFlags.inexact
5281             ),
5282             Test(
5283                 () { x = T.min_normal; x /= T.max; },
5284                 () => ieeeFlags.underflow
5285             ),
5286             Test(
5287                 () { x = T.max; x += T.max; },
5288                 () => ieeeFlags.overflow
5289             ),
5290             Test(
5291                 () { x = 1; x /= 0; },
5292                 () => ieeeFlags.divByZero
5293             ),
5294             Test(
5295                 () { x = 0; x /= 0; },
5296                 () => ieeeFlags.invalid
5297             )
5298         ];
5299         foreach (test; tests)
5300         {
5301             resetIeeeFlags();
5302             assert(!test.ieeeCheck());
5303             test.action();
5304             assert(test.ieeeCheck());
5305         }
5306     }}
5307 }
5308 
5309 /// Set all of the floating-point status flags to false.
5310 void resetIeeeFlags() @trusted nothrow @nogc
5311 {
5312     IeeeFlags.resetIeeeFlags();
5313 }
5314 
5315 ///
5316 @safe unittest
5317 {
5318     pragma(inline, false) static void blockopt(ref real x) {}
5319     resetIeeeFlags();
5320     real a = 3.5;
5321     blockopt(a); // avoid constant propagation by the optimizer
5322     a /= 0.0L;
5323     blockopt(a); // avoid constant propagation by the optimizer
5324     assert(a == real.infinity);
5325     assert(ieeeFlags.divByZero);
5326 
5327     resetIeeeFlags();
5328     assert(!ieeeFlags.divByZero);
5329 }
5330 
5331 /// Returns: snapshot of the current state of the floating-point status flags
5332 @property IeeeFlags ieeeFlags() @trusted pure nothrow @nogc
5333 {
5334    return IeeeFlags(IeeeFlags.getIeeeFlags());
5335 }
5336 
5337 ///
5338 @safe nothrow unittest
5339 {
5340     pragma(inline, false) static void blockopt(ref real x) {}
5341     resetIeeeFlags();
5342     real a = 3.5;
5343     blockopt(a); // avoid constant propagation by the optimizer
5344 
5345     a /= 0.0L;
5346     assert(a == real.infinity);
5347     assert(ieeeFlags.divByZero);
5348     blockopt(a); // avoid constant propagation by the optimizer
5349 
5350     a *= 0.0L;
5351     assert(isNaN(a));
5352     assert(ieeeFlags.invalid);
5353 }
5354 
5355 } // IeeeFlagsSupport
5356 
5357 
5358 version (FloatingPointControlSupport)
5359 {
5360 
5361 /** Control the Floating point hardware
5362 
5363   Change the IEEE754 floating-point rounding mode and the floating-point
5364   hardware exceptions.
5365 
5366   By default, the rounding mode is roundToNearest and all hardware exceptions
5367   are disabled. For most applications, debugging is easier if the $(I division
5368   by zero), $(I overflow), and $(I invalid operation) exceptions are enabled.
5369   These three are combined into a $(I severeExceptions) value for convenience.
5370   Note in particular that if $(I invalidException) is enabled, a hardware trap
5371   will be generated whenever an uninitialized floating-point variable is used.
5372 
5373   All changes are temporary. The previous state is restored at the
5374   end of the scope.
5375 
5376 
5377 Example:
5378 ----
5379 {
5380     FloatingPointControl fpctrl;
5381 
5382     // Enable hardware exceptions for division by zero, overflow to infinity,
5383     // invalid operations, and uninitialized floating-point variables.
5384     fpctrl.enableExceptions(FloatingPointControl.severeExceptions);
5385 
5386     // This will generate a hardware exception, if x is a
5387     // default-initialized floating point variable:
5388     real x; // Add `= 0` or even `= real.nan` to not throw the exception.
5389     real y = x * 3.0;
5390 
5391     // The exception is only thrown for default-uninitialized NaN-s.
5392     // NaN-s with other payload are valid:
5393     real z = y * real.nan; // ok
5394 
5395     // The set hardware exceptions and rounding modes will be disabled when
5396     // leaving this scope.
5397 }
5398 ----
5399 
5400  */
5401 struct FloatingPointControl
5402 {
5403 nothrow @nogc:
5404 
5405     alias RoundingMode = uint; ///
5406 
5407     version (StdDdoc)
5408     {
5409         enum : RoundingMode
5410         {
5411             /** IEEE rounding modes.
5412              * The default mode is roundToNearest.
5413              *
5414              *  roundingMask = A mask of all rounding modes.
5415              */
5416             roundToNearest,
5417             roundDown, /// ditto
5418             roundUp, /// ditto
5419             roundToZero, /// ditto
5420             roundingMask, /// ditto
5421         }
5422     }
5423     else version (CRuntime_Microsoft)
5424     {
5425         // Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).
5426         enum : RoundingMode
5427         {
5428             roundToNearest = 0x0000,
5429             roundDown      = 0x0400,
5430             roundUp        = 0x0800,
5431             roundToZero    = 0x0C00,
5432             roundingMask   = roundToNearest | roundDown
5433                              | roundUp | roundToZero,
5434         }
5435     }
5436     else
5437     {
5438         enum : RoundingMode
5439         {
5440             roundToNearest = core.stdc.fenv.FE_TONEAREST,
5441             roundDown      = core.stdc.fenv.FE_DOWNWARD,
5442             roundUp        = core.stdc.fenv.FE_UPWARD,
5443             roundToZero    = core.stdc.fenv.FE_TOWARDZERO,
5444             roundingMask   = roundToNearest | roundDown
5445                              | roundUp | roundToZero,
5446         }
5447     }
5448 
5449     /***
5450      * Change the floating-point hardware rounding mode
5451      *
5452      * Changing the rounding mode in the middle of a function can interfere
5453      * with optimizations of floating point expressions, as the optimizer assumes
5454      * that the rounding mode does not change.
5455      * It is best to change the rounding mode only at the
5456      * beginning of the function, and keep it until the function returns.
5457      * It is also best to add the line:
5458      * ---
5459      * pragma(inline, false);
5460      * ---
5461      * as the first line of the function so it will not get inlined.
5462      * Params:
5463      *    newMode = the new rounding mode
5464      */
5465     @property void rounding(RoundingMode newMode) @trusted
5466     {
5467         initialize();
5468         setControlState((getControlState() & (-1 - roundingMask)) | (newMode & roundingMask));
5469     }
5470 
5471     /// Returns: the currently active rounding mode
5472     @property static RoundingMode rounding() @trusted pure
5473     {
5474         return cast(RoundingMode)(getControlState() & roundingMask);
5475     }
5476 
5477     alias ExceptionMask = uint; ///
5478 
5479     version (StdDdoc)
5480     {
5481         enum : ExceptionMask
5482         {
5483             /** IEEE hardware exceptions.
5484              *  By default, all exceptions are masked (disabled).
5485              *
5486              *  severeExceptions = The overflow, division by zero, and invalid
5487              *  exceptions.
5488              */
5489             subnormalException,
5490             inexactException, /// ditto
5491             underflowException, /// ditto
5492             overflowException, /// ditto
5493             divByZeroException, /// ditto
5494             invalidException, /// ditto
5495             severeExceptions, /// ditto
5496             allExceptions, /// ditto
5497         }
5498     }
5499     else version (ARM_Any)
5500     {
5501         enum : ExceptionMask
5502         {
5503             subnormalException    = 0x8000,
5504             inexactException      = 0x1000,
5505             underflowException    = 0x0800,
5506             overflowException     = 0x0400,
5507             divByZeroException    = 0x0200,
5508             invalidException      = 0x0100,
5509             severeExceptions   = overflowException | divByZeroException
5510                                  | invalidException,
5511             allExceptions      = severeExceptions | underflowException
5512                                  | inexactException | subnormalException,
5513         }
5514     }
5515     else version (PPC_Any)
5516     {
5517         enum : ExceptionMask
5518         {
5519             inexactException      = 0x0008,
5520             divByZeroException    = 0x0010,
5521             underflowException    = 0x0020,
5522             overflowException     = 0x0040,
5523             invalidException      = 0x0080,
5524             severeExceptions   = overflowException | divByZeroException
5525                                  | invalidException,
5526             allExceptions      = severeExceptions | underflowException
5527                                  | inexactException,
5528         }
5529     }
5530     else version (RISCV_Any)
5531     {
5532         enum : ExceptionMask
5533         {
5534             inexactException      = 0x01,
5535             divByZeroException    = 0x02,
5536             underflowException    = 0x04,
5537             overflowException     = 0x08,
5538             invalidException      = 0x10,
5539             severeExceptions   = overflowException | divByZeroException
5540                                  | invalidException,
5541             allExceptions      = severeExceptions | underflowException
5542                                  | inexactException,
5543         }
5544     }
5545     else version (HPPA)
5546     {
5547         enum : ExceptionMask
5548         {
5549             inexactException      = 0x01,
5550             underflowException    = 0x02,
5551             overflowException     = 0x04,
5552             divByZeroException    = 0x08,
5553             invalidException      = 0x10,
5554             severeExceptions   = overflowException | divByZeroException
5555                                  | invalidException,
5556             allExceptions      = severeExceptions | underflowException
5557                                  | inexactException,
5558         }
5559     }
5560     else version (MIPS_Any)
5561     {
5562         enum : ExceptionMask
5563         {
5564             inexactException      = 0x0080,
5565             divByZeroException    = 0x0400,
5566             overflowException     = 0x0200,
5567             underflowException    = 0x0100,
5568             invalidException      = 0x0800,
5569             severeExceptions   = overflowException | divByZeroException
5570                                  | invalidException,
5571             allExceptions      = severeExceptions | underflowException
5572                                  | inexactException,
5573         }
5574     }
5575     else version (SPARC_Any)
5576     {
5577         enum : ExceptionMask
5578         {
5579             inexactException      = 0x0800000,
5580             divByZeroException    = 0x1000000,
5581             overflowException     = 0x4000000,
5582             underflowException    = 0x2000000,
5583             invalidException      = 0x8000000,
5584             severeExceptions   = overflowException | divByZeroException
5585                                  | invalidException,
5586             allExceptions      = severeExceptions | underflowException
5587                                  | inexactException,
5588         }
5589     }
5590     else version (IBMZ_Any)
5591     {
5592         enum : ExceptionMask
5593         {
5594             inexactException      = 0x08000000,
5595             divByZeroException    = 0x40000000,
5596             overflowException     = 0x20000000,
5597             underflowException    = 0x10000000,
5598             invalidException      = 0x80000000,
5599             severeExceptions   = overflowException | divByZeroException
5600                                  | invalidException,
5601             allExceptions      = severeExceptions | underflowException
5602                                  | inexactException,
5603         }
5604     }
5605     else version (X86_Any)
5606     {
5607         enum : ExceptionMask
5608         {
5609             inexactException      = 0x20,
5610             underflowException    = 0x10,
5611             overflowException     = 0x08,
5612             divByZeroException    = 0x04,
5613             subnormalException    = 0x02,
5614             invalidException      = 0x01,
5615             severeExceptions   = overflowException | divByZeroException
5616                                  | invalidException,
5617             allExceptions      = severeExceptions | underflowException
5618                                  | inexactException | subnormalException,
5619         }
5620     }
5621     else
5622         static assert(false, "Not implemented for this architecture");
5623 
5624     version (ARM_Any)
5625     {
5626         static bool hasExceptionTraps_impl() @safe
5627         {
5628             auto oldState = getControlState();
5629             // If exceptions are not supported, we set the bit but read it back as zero
5630             // https://sourceware.org/ml/libc-ports/2012-06/msg00091.html
5631             setControlState(oldState | divByZeroException);
5632             immutable result = (getControlState() & allExceptions) != 0;
5633             setControlState(oldState);
5634             return result;
5635         }
5636     }
5637 
5638     /// Returns: true if the current FPU supports exception trapping
5639     @property static bool hasExceptionTraps() @safe pure
5640     {
5641         version (X86_Any)
5642             return true;
5643         else version (PPC_Any)
5644             return true;
5645         else version (MIPS_Any)
5646             return true;
5647         else version (ARM_Any)
5648         {
5649             // The hasExceptionTraps_impl function is basically pure,
5650             // as it restores all global state
5651             auto fptr = ( () @trusted => cast(bool function() @safe
5652                 pure nothrow @nogc)&hasExceptionTraps_impl)();
5653             return fptr();
5654         }
5655         else
5656             assert(0, "Not yet supported");
5657     }
5658 
5659     /// Enable (unmask) specific hardware exceptions. Multiple exceptions may be ORed together.
5660     void enableExceptions(ExceptionMask exceptions) @trusted
5661     {
5662         assert(hasExceptionTraps);
5663         initialize();
5664         version (X86_Any)
5665             setControlState(getControlState() & ~(exceptions & allExceptions));
5666         else
5667             setControlState(getControlState() | (exceptions & allExceptions));
5668     }
5669 
5670     /// Disable (mask) specific hardware exceptions. Multiple exceptions may be ORed together.
5671     void disableExceptions(ExceptionMask exceptions) @trusted
5672     {
5673         assert(hasExceptionTraps);
5674         initialize();
5675         version (X86_Any)
5676             setControlState(getControlState() | (exceptions & allExceptions));
5677         else
5678             setControlState(getControlState() & ~(exceptions & allExceptions));
5679     }
5680 
5681     /// Returns: the exceptions which are currently enabled (unmasked)
5682     @property static ExceptionMask enabledExceptions() @trusted pure
5683     {
5684         assert(hasExceptionTraps);
5685         version (X86_Any)
5686             return (getControlState() & allExceptions) ^ allExceptions;
5687         else
5688             return (getControlState() & allExceptions);
5689     }
5690 
5691     ///  Clear all pending exceptions, then restore the original exception state and rounding mode.
5692     ~this() @trusted
5693     {
5694         clearExceptions();
5695         if (initialized)
5696             setControlState(savedState);
5697     }
5698 
5699 private:
5700     ControlState savedState;
5701 
5702     bool initialized = false;
5703 
5704     version (ARM_Any)
5705     {
5706         alias ControlState = uint;
5707     }
5708     else version (HPPA)
5709     {
5710         alias ControlState = uint;
5711     }
5712     else version (PPC_Any)
5713     {
5714         alias ControlState = uint;
5715     }
5716     else version (RISCV_Any)
5717     {
5718         alias ControlState = uint;
5719     }
5720     else version (MIPS_Any)
5721     {
5722         alias ControlState = uint;
5723     }
5724     else version (SPARC_Any)
5725     {
5726         alias ControlState = ulong;
5727     }
5728     else version (IBMZ_Any)
5729     {
5730         alias ControlState = uint;
5731     }
5732     else version (X86_Any)
5733     {
5734         alias ControlState = ushort;
5735     }
5736     else
5737         static assert(false, "Not implemented for this architecture");
5738 
5739     void initialize() @safe
5740     {
5741         // BUG: This works around the absence of this() constructors.
5742         if (initialized) return;
5743         clearExceptions();
5744         savedState = getControlState();
5745         initialized = true;
5746     }
5747 
5748     // Clear all pending exceptions
5749     static void clearExceptions() @safe
5750     {
5751         version (IeeeFlagsSupport)
5752             resetIeeeFlags();
5753         else
5754             static assert(false, "Not implemented for this architecture");
5755     }
5756 
5757     // Read from the control register
5758     static ControlState getControlState() @trusted pure
5759     {
5760         version (D_InlineAsm_X86)
5761         {
5762             short cont;
5763             asm pure nothrow @nogc
5764             {
5765                 xor EAX, EAX;
5766                 fstcw cont;
5767             }
5768             return cont;
5769         }
5770         else
5771         version (D_InlineAsm_X86_64)
5772         {
5773             short cont;
5774             asm pure nothrow @nogc
5775             {
5776                 xor RAX, RAX;
5777                 fstcw cont;
5778             }
5779             return cont;
5780         }
5781         else version (RISCV_Any)
5782         {
5783             mixin(`
5784             ControlState cont;
5785             asm pure nothrow @nogc
5786             {
5787                 "frcsr %0" : "=r" (cont);
5788             }
5789             return cont;
5790             `);
5791         }
5792         else
5793             assert(0, "Not yet supported");
5794     }
5795 
5796     // Set the control register
5797     static void setControlState(ControlState newState) @trusted
5798     {
5799         version (InlineAsm_X86_Any)
5800         {
5801             asm nothrow @nogc
5802             {
5803                 fclex;
5804                 fldcw newState;
5805             }
5806 
5807             // Also update MXCSR, SSE's control register.
5808             if (haveSSE)
5809             {
5810                 uint mxcsr;
5811                 asm nothrow @nogc { stmxcsr mxcsr; }
5812 
5813                 /* In the FPU control register, rounding mode is in bits 10 and
5814                 11. In MXCSR it's in bits 13 and 14. */
5815                 mxcsr &= ~(roundingMask << 3);             // delete old rounding mode
5816                 mxcsr |= (newState & roundingMask) << 3;   // write new rounding mode
5817 
5818                 /* In the FPU control register, masks are bits 0 through 5.
5819                 In MXCSR they're 7 through 12. */
5820                 mxcsr &= ~(allExceptions << 7);            // delete old masks
5821                 mxcsr |= (newState & allExceptions) << 7;  // write new exception masks
5822 
5823                 asm nothrow @nogc { ldmxcsr mxcsr; }
5824             }
5825         }
5826         else version (RISCV_Any)
5827         {
5828             mixin(`
5829             asm pure nothrow @nogc
5830             {
5831                 "fscsr %0" : : "r" (newState);
5832             }
5833             `);
5834         }
5835         else
5836             assert(0, "Not yet supported");
5837     }
5838 }
5839 
5840 ///
5841 @safe unittest
5842 {
5843     FloatingPointControl fpctrl;
5844 
5845     fpctrl.rounding = FloatingPointControl.roundDown;
5846     assert(lrint(1.5) == 1.0);
5847 
5848     fpctrl.rounding = FloatingPointControl.roundUp;
5849     assert(lrint(1.4) == 2.0);
5850 
5851     fpctrl.rounding = FloatingPointControl.roundToNearest;
5852     assert(lrint(1.5) == 2.0);
5853 }
5854 
5855 @safe unittest
5856 {
5857     void ensureDefaults()
5858     {
5859         assert(FloatingPointControl.rounding
5860                == FloatingPointControl.roundToNearest);
5861         if (FloatingPointControl.hasExceptionTraps)
5862             assert(FloatingPointControl.enabledExceptions == 0);
5863     }
5864 
5865     {
5866         FloatingPointControl ctrl;
5867     }
5868     ensureDefaults();
5869 
5870     {
5871         FloatingPointControl ctrl;
5872         ctrl.rounding = FloatingPointControl.roundDown;
5873         assert(FloatingPointControl.rounding == FloatingPointControl.roundDown);
5874     }
5875     ensureDefaults();
5876 
5877     if (FloatingPointControl.hasExceptionTraps)
5878     {
5879         FloatingPointControl ctrl;
5880         ctrl.enableExceptions(FloatingPointControl.divByZeroException
5881                               | FloatingPointControl.overflowException);
5882         assert(ctrl.enabledExceptions ==
5883                (FloatingPointControl.divByZeroException
5884                 | FloatingPointControl.overflowException));
5885 
5886         ctrl.rounding = FloatingPointControl.roundUp;
5887         assert(FloatingPointControl.rounding == FloatingPointControl.roundUp);
5888     }
5889     ensureDefaults();
5890 }
5891 
5892 @safe unittest // rounding
5893 {
5894     import std.meta : AliasSeq;
5895 
5896     static foreach (T; AliasSeq!(float, double, real))
5897     {{
5898         /* Be careful with changing the rounding mode, it interferes
5899          * with common subexpressions. Changing rounding modes should
5900          * be done with separate functions that are not inlined.
5901          */
5902 
5903         {
5904             static T addRound(T)(uint rm)
5905             {
5906                 pragma(inline, false) static void blockopt(ref T x) {}
5907                 pragma(inline, false);
5908                 FloatingPointControl fpctrl;
5909                 fpctrl.rounding = rm;
5910                 T x = 1;
5911                 blockopt(x); // avoid constant propagation by the optimizer
5912                 x += 0.1L;
5913                 return x;
5914             }
5915 
5916             T u = addRound!(T)(FloatingPointControl.roundUp);
5917             T d = addRound!(T)(FloatingPointControl.roundDown);
5918             T z = addRound!(T)(FloatingPointControl.roundToZero);
5919 
5920             assert(u > d);
5921             assert(z == d);
5922         }
5923 
5924         {
5925             static T subRound(T)(uint rm)
5926             {
5927                 pragma(inline, false) static void blockopt(ref T x) {}
5928                 pragma(inline, false);
5929                 FloatingPointControl fpctrl;
5930                 fpctrl.rounding = rm;
5931                 T x = -1;
5932                 blockopt(x); // avoid constant propagation by the optimizer
5933                 x -= 0.1L;
5934                 return x;
5935             }
5936 
5937             T u = subRound!(T)(FloatingPointControl.roundUp);
5938             T d = subRound!(T)(FloatingPointControl.roundDown);
5939             T z = subRound!(T)(FloatingPointControl.roundToZero);
5940 
5941             assert(u > d);
5942             assert(z == u);
5943         }
5944     }}
5945 }
5946 
5947 } // FloatingPointControlSupport
5948 
5949 
5950 /*********************************
5951  * Determines if $(D_PARAM x) is NaN.
5952  * Params:
5953  *  x = a floating point number.
5954  * Returns:
5955  *  `true` if $(D_PARAM x) is Nan.
5956  */
5957 bool isNaN(X)(X x) @nogc @trusted pure nothrow
5958 if (isFloatingPoint!(X))
5959 {
5960     version (all)
5961     {
5962         return x != x;
5963     }
5964     else
5965     {
5966         /*
5967         Code kept for historical context. At least on Intel, the simple test
5968         x != x uses one dedicated instruction (ucomiss/ucomisd) that runs in one
5969         cycle. Code for 80- and 128-bits is larger but still smaller than the
5970         integrals-based solutions below. Future revisions may enable the code
5971         below conditionally depending on hardware.
5972         */
5973         alias F = floatTraits!(X);
5974         static if (F.realFormat == RealFormat.ieeeSingle)
5975         {
5976             const uint p = *cast(uint *)&x;
5977             // Sign bit (MSB) is irrelevant so mask it out.
5978             // Next 8 bits should be all set.
5979             // At least one bit among the least significant 23 bits should be set.
5980             return (p & 0x7FFF_FFFF) > 0x7F80_0000;
5981         }
5982         else static if (F.realFormat == RealFormat.ieeeDouble)
5983         {
5984             const ulong  p = *cast(ulong *)&x;
5985             // Sign bit (MSB) is irrelevant so mask it out.
5986             // Next 11 bits should be all set.
5987             // At least one bit among the least significant 52 bits should be set.
5988             return (p & 0x7FFF_FFFF_FFFF_FFFF) > 0x7FF0_0000_0000_0000;
5989         }
5990         else static if (F.realFormat == RealFormat.ieeeExtended)
5991         {
5992             const ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
5993             const ulong ps = *cast(ulong *)&x;
5994             return e == F.EXPMASK &&
5995                 ps & 0x7FFF_FFFF_FFFF_FFFF; // not infinity
5996         }
5997         else static if (F.realFormat == RealFormat.ieeeQuadruple)
5998         {
5999             const ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
6000             const ulong psLsb = (cast(ulong *)&x)[MANTISSA_LSB];
6001             const ulong psMsb = (cast(ulong *)&x)[MANTISSA_MSB];
6002             return e == F.EXPMASK &&
6003                 (psLsb | (psMsb& 0x0000_FFFF_FFFF_FFFF)) != 0;
6004         }
6005         else
6006         {
6007             return x != x;
6008         }
6009     }
6010 }
6011 
6012 ///
6013 @safe pure nothrow @nogc unittest
6014 {
6015     assert( isNaN(float.init));
6016     assert( isNaN(-double.init));
6017     assert( isNaN(real.nan));
6018     assert( isNaN(-real.nan));
6019     assert(!isNaN(cast(float) 53.6));
6020     assert(!isNaN(cast(real)-53.6));
6021 }
6022 
6023 @safe pure nothrow @nogc unittest
6024 {
6025     import std.meta : AliasSeq;
6026 
6027     static foreach (T; AliasSeq!(float, double, real))
6028     {{
6029         // CTFE-able tests
6030         assert(isNaN(T.init));
6031         assert(isNaN(-T.init));
6032         assert(isNaN(T.nan));
6033         assert(isNaN(-T.nan));
6034         assert(!isNaN(T.infinity));
6035         assert(!isNaN(-T.infinity));
6036         assert(!isNaN(cast(T) 53.6));
6037         assert(!isNaN(cast(T)-53.6));
6038 
6039         // Runtime tests
6040         shared T f;
6041         f = T.init;
6042         assert(isNaN(f));
6043         assert(isNaN(-f));
6044         f = T.nan;
6045         assert(isNaN(f));
6046         assert(isNaN(-f));
6047         f = T.infinity;
6048         assert(!isNaN(f));
6049         assert(!isNaN(-f));
6050         f = cast(T) 53.6;
6051         assert(!isNaN(f));
6052         assert(!isNaN(-f));
6053     }}
6054 }
6055 
6056 /*********************************
6057  * Determines if $(D_PARAM x) is finite.
6058  * Params:
6059  *  x = a floating point number.
6060  * Returns:
6061  *  `true` if $(D_PARAM x) is finite.
6062  */
6063 bool isFinite(X)(X x) @trusted pure nothrow @nogc
6064 {
6065     static if (__traits(isFloating, X))
6066         if (__ctfe)
6067             return x == x && x != X.infinity && x != -X.infinity;
6068     alias F = floatTraits!(X);
6069     ushort* pe = cast(ushort *)&x;
6070     return (pe[F.EXPPOS_SHORT] & F.EXPMASK) != F.EXPMASK;
6071 }
6072 
6073 ///
6074 @safe pure nothrow @nogc unittest
6075 {
6076     assert( isFinite(1.23f));
6077     assert( isFinite(float.max));
6078     assert( isFinite(float.min_normal));
6079     assert(!isFinite(float.nan));
6080     assert(!isFinite(float.infinity));
6081 }
6082 
6083 @safe pure nothrow @nogc unittest
6084 {
6085     assert(isFinite(1.23));
6086     assert(isFinite(double.max));
6087     assert(isFinite(double.min_normal));
6088     assert(!isFinite(double.nan));
6089     assert(!isFinite(double.infinity));
6090 
6091     assert(isFinite(1.23L));
6092     assert(isFinite(real.max));
6093     assert(isFinite(real.min_normal));
6094     assert(!isFinite(real.nan));
6095     assert(!isFinite(real.infinity));
6096 
6097     //CTFE
6098     static assert(isFinite(1.23));
6099     static assert(isFinite(double.max));
6100     static assert(isFinite(double.min_normal));
6101     static assert(!isFinite(double.nan));
6102     static assert(!isFinite(double.infinity));
6103 
6104     static assert(isFinite(1.23L));
6105     static assert(isFinite(real.max));
6106     static assert(isFinite(real.min_normal));
6107     static assert(!isFinite(real.nan));
6108     static assert(!isFinite(real.infinity));
6109 }
6110 
6111 
6112 /*********************************
6113  * Determines if $(D_PARAM x) is normalized.
6114  *
6115  * A normalized number must not be zero, subnormal, infinite nor $(NAN).
6116  *
6117  * Params:
6118  *  x = a floating point number.
6119  * Returns:
6120  *  `true` if $(D_PARAM x) is normalized.
6121  */
6122 
6123 /* Need one for each format because subnormal floats might
6124  * be converted to normal reals.
6125  */
6126 bool isNormal(X)(X x) @trusted pure nothrow @nogc
6127 {
6128     static if (__traits(isFloating, X))
6129         if (__ctfe)
6130             return (x <= -X.min_normal && x != -X.infinity) || (x >= X.min_normal && x != X.infinity);
6131     alias F = floatTraits!(X);
6132     ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
6133     return (e != F.EXPMASK && e != 0);
6134 }
6135 
6136 ///
6137 @safe pure nothrow @nogc unittest
6138 {
6139     float f = 3;
6140     double d = 500;
6141     real e = 10e+48;
6142 
6143     assert(isNormal(f));
6144     assert(isNormal(d));
6145     assert(isNormal(e));
6146     f = d = e = 0;
6147     assert(!isNormal(f));
6148     assert(!isNormal(d));
6149     assert(!isNormal(e));
6150     assert(!isNormal(real.infinity));
6151     assert(isNormal(-real.max));
6152     assert(!isNormal(real.min_normal/4));
6153 
6154 }
6155 
6156 @safe pure nothrow @nogc unittest
6157 {
6158     // CTFE
6159     enum float f = 3;
6160     enum double d = 500;
6161     enum real e = 10e+48;
6162 
6163     static assert(isNormal(f));
6164     static assert(isNormal(d));
6165     static assert(isNormal(e));
6166 
6167     static assert(!isNormal(0.0f));
6168     static assert(!isNormal(0.0));
6169     static assert(!isNormal(0.0L));
6170     static assert(!isNormal(real.infinity));
6171     static assert(isNormal(-real.max));
6172     static assert(!isNormal(real.min_normal/4));
6173 }
6174 
6175 /*********************************
6176  * Determines if $(D_PARAM x) is subnormal.
6177  *
6178  * Subnormals (also known as "denormal number"), have a 0 exponent
6179  * and a 0 most significant mantissa bit.
6180  *
6181  * Params:
6182  *  x = a floating point number.
6183  * Returns:
6184  *  `true` if $(D_PARAM x) is a denormal number.
6185  */
6186 bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
6187 {
6188     static if (__traits(isFloating, X))
6189         if (__ctfe)
6190             return -X.min_normal < x && x < X.min_normal;
6191     /*
6192         Need one for each format because subnormal floats might
6193         be converted to normal reals.
6194     */
6195     alias F = floatTraits!(X);
6196     static if (F.realFormat == RealFormat.ieeeSingle)
6197     {
6198         uint *p = cast(uint *)&x;
6199         return (*p & F.EXPMASK_INT) == 0 && *p & F.MANTISSAMASK_INT;
6200     }
6201     else static if (F.realFormat == RealFormat.ieeeDouble)
6202     {
6203         uint *p = cast(uint *)&x;
6204         return (p[MANTISSA_MSB] & F.EXPMASK_INT) == 0
6205             && (p[MANTISSA_LSB] || p[MANTISSA_MSB] & F.MANTISSAMASK_INT);
6206     }
6207     else static if (F.realFormat == RealFormat.ieeeQuadruple)
6208     {
6209         ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
6210         long*   ps = cast(long *)&x;
6211         return (e == 0 &&
6212           ((ps[MANTISSA_LSB]|(ps[MANTISSA_MSB]& 0x0000_FFFF_FFFF_FFFF)) != 0));
6213     }
6214     else static if (F.realFormat == RealFormat.ieeeExtended)
6215     {
6216         ushort* pe = cast(ushort *)&x;
6217         long*   ps = cast(long *)&x;
6218 
6219         return (pe[F.EXPPOS_SHORT] & F.EXPMASK) == 0 && *ps > 0;
6220     }
6221     else
6222     {
6223         static assert(false, "Not implemented for this architecture");
6224     }
6225 }
6226 
6227 ///
6228 @safe pure nothrow @nogc unittest
6229 {
6230     import std.meta : AliasSeq;
6231 
6232     static foreach (T; AliasSeq!(float, double, real))
6233     {{
6234         T f;
6235         for (f = 1.0; !isSubnormal(f); f /= 2)
6236             assert(f != 0);
6237     }}
6238 }
6239 
6240 @safe pure nothrow @nogc unittest
6241 {
6242     static bool subnormalTest(T)()
6243     {
6244         T f;
6245         for (f = 1.0; !isSubnormal(f); f /= 2)
6246             if (f == 0)
6247                 return false;
6248         return true;
6249     }
6250     static assert(subnormalTest!float());
6251     static assert(subnormalTest!double());
6252     static assert(subnormalTest!real());
6253 }
6254 
6255 /*********************************
6256  * Determines if $(D_PARAM x) is $(PLUSMN)$(INFIN).
6257  * Params:
6258  *  x = a floating point number.
6259  * Returns:
6260  *  `true` if $(D_PARAM x) is $(PLUSMN)$(INFIN).
6261  */
6262 bool isInfinity(X)(X x) @nogc @trusted pure nothrow
6263 if (isFloatingPoint!(X))
6264 {
6265     alias F = floatTraits!(X);
6266     static if (F.realFormat == RealFormat.ieeeSingle)
6267     {
6268         return ((*cast(uint *)&x) & 0x7FFF_FFFF) == 0x7F80_0000;
6269     }
6270     else static if (F.realFormat == RealFormat.ieeeDouble)
6271     {
6272         return ((*cast(ulong *)&x) & 0x7FFF_FFFF_FFFF_FFFF)
6273             == 0x7FF0_0000_0000_0000;
6274     }
6275     else static if (F.realFormat == RealFormat.ieeeExtended)
6276     {
6277         const ushort e = cast(ushort)(F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT]);
6278         const ulong ps = *cast(ulong *)&x;
6279 
6280         // On Motorola 68K, infinity can have hidden bit = 1 or 0. On x86, it is always 1.
6281         return e == F.EXPMASK && (ps & 0x7FFF_FFFF_FFFF_FFFF) == 0;
6282     }
6283     else static if (F.realFormat == RealFormat.ieeeQuadruple)
6284     {
6285         const long psLsb = (cast(long *)&x)[MANTISSA_LSB];
6286         const long psMsb = (cast(long *)&x)[MANTISSA_MSB];
6287         return (psLsb == 0)
6288             && (psMsb & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_0000_0000_0000;
6289     }
6290     else
6291     {
6292         return (x < -X.max) || (X.max < x);
6293     }
6294 }
6295 
6296 ///
6297 @nogc @safe pure nothrow unittest
6298 {
6299     assert(!isInfinity(float.init));
6300     assert(!isInfinity(-float.init));
6301     assert(!isInfinity(float.nan));
6302     assert(!isInfinity(-float.nan));
6303     assert(isInfinity(float.infinity));
6304     assert(isInfinity(-float.infinity));
6305     assert(isInfinity(-1.0f / 0.0f));
6306 }
6307 
6308 @safe pure nothrow @nogc unittest
6309 {
6310     // CTFE-able tests
6311     assert(!isInfinity(double.init));
6312     assert(!isInfinity(-double.init));
6313     assert(!isInfinity(double.nan));
6314     assert(!isInfinity(-double.nan));
6315     assert(isInfinity(double.infinity));
6316     assert(isInfinity(-double.infinity));
6317     assert(isInfinity(-1.0 / 0.0));
6318 
6319     assert(!isInfinity(real.init));
6320     assert(!isInfinity(-real.init));
6321     assert(!isInfinity(real.nan));
6322     assert(!isInfinity(-real.nan));
6323     assert(isInfinity(real.infinity));
6324     assert(isInfinity(-real.infinity));
6325     assert(isInfinity(-1.0L / 0.0L));
6326 
6327     // Runtime tests
6328     shared float f;
6329     f = float.init;
6330     assert(!isInfinity(f));
6331     assert(!isInfinity(-f));
6332     f = float.nan;
6333     assert(!isInfinity(f));
6334     assert(!isInfinity(-f));
6335     f = float.infinity;
6336     assert(isInfinity(f));
6337     assert(isInfinity(-f));
6338     f = (-1.0f / 0.0f);
6339     assert(isInfinity(f));
6340 
6341     shared double d;
6342     d = double.init;
6343     assert(!isInfinity(d));
6344     assert(!isInfinity(-d));
6345     d = double.nan;
6346     assert(!isInfinity(d));
6347     assert(!isInfinity(-d));
6348     d = double.infinity;
6349     assert(isInfinity(d));
6350     assert(isInfinity(-d));
6351     d = (-1.0 / 0.0);
6352     assert(isInfinity(d));
6353 
6354     shared real e;
6355     e = real.init;
6356     assert(!isInfinity(e));
6357     assert(!isInfinity(-e));
6358     e = real.nan;
6359     assert(!isInfinity(e));
6360     assert(!isInfinity(-e));
6361     e = real.infinity;
6362     assert(isInfinity(e));
6363     assert(isInfinity(-e));
6364     e = (-1.0L / 0.0L);
6365     assert(isInfinity(e));
6366 }
6367 
6368 @nogc @safe pure nothrow unittest
6369 {
6370     import std.meta : AliasSeq;
6371     static bool foo(T)(inout T x) { return isInfinity(x); }
6372     foreach (T; AliasSeq!(float, double, real))
6373     {
6374         assert(!foo(T(3.14f)));
6375         assert(foo(T.infinity));
6376     }
6377 }
6378 
6379 /*********************************
6380  * Is the binary representation of x identical to y?
6381  */
6382 bool isIdentical(real x, real y) @trusted pure nothrow @nogc
6383 {
6384     // We're doing a bitwise comparison so the endianness is irrelevant.
6385     long*   pxs = cast(long *)&x;
6386     long*   pys = cast(long *)&y;
6387     alias F = floatTraits!(real);
6388     static if (F.realFormat == RealFormat.ieeeDouble)
6389     {
6390         return pxs[0] == pys[0];
6391     }
6392     else static if (F.realFormat == RealFormat.ieeeQuadruple)
6393     {
6394         return pxs[0] == pys[0] && pxs[1] == pys[1];
6395     }
6396     else static if (F.realFormat == RealFormat.ieeeExtended)
6397     {
6398         ushort* pxe = cast(ushort *)&x;
6399         ushort* pye = cast(ushort *)&y;
6400         return pxe[4] == pye[4] && pxs[0] == pys[0];
6401     }
6402     else
6403     {
6404         assert(0, "isIdentical not implemented");
6405     }
6406 }
6407 
6408 ///
6409 @safe @nogc pure nothrow unittest
6410 {
6411     assert( isIdentical(0.0, 0.0));
6412     assert( isIdentical(1.0, 1.0));
6413     assert( isIdentical(real.infinity, real.infinity));
6414     assert( isIdentical(-real.infinity, -real.infinity));
6415 
6416     assert(!isIdentical(0.0, -0.0));
6417     assert(!isIdentical(real.nan, -real.nan));
6418     assert(!isIdentical(real.infinity, -real.infinity));
6419 }
6420 
6421 /*********************************
6422  * Return 1 if sign bit of e is set, 0 if not.
6423  */
6424 int signbit(X)(X x) @nogc @trusted pure nothrow
6425 {
6426     if (__ctfe)
6427     {
6428         double dval = cast(double) x; // Precision can increase or decrease but sign won't change (even NaN).
6429         return 0 > *cast(long*) &dval;
6430     }
6431 
6432     alias F = floatTraits!(X);
6433     return ((cast(ubyte *)&x)[F.SIGNPOS_BYTE] & 0x80) != 0;
6434 }
6435 
6436 ///
6437 @nogc @safe pure nothrow unittest
6438 {
6439     assert(!signbit(float.nan));
6440     assert(signbit(-float.nan));
6441     assert(!signbit(168.1234f));
6442     assert(signbit(-168.1234f));
6443     assert(!signbit(0.0f));
6444     assert(signbit(-0.0f));
6445     assert(signbit(-float.max));
6446     assert(!signbit(float.max));
6447 
6448     assert(!signbit(double.nan));
6449     assert(signbit(-double.nan));
6450     assert(!signbit(168.1234));
6451     assert(signbit(-168.1234));
6452     assert(!signbit(0.0));
6453     assert(signbit(-0.0));
6454     assert(signbit(-double.max));
6455     assert(!signbit(double.max));
6456 
6457     assert(!signbit(real.nan));
6458     assert(signbit(-real.nan));
6459     assert(!signbit(168.1234L));
6460     assert(signbit(-168.1234L));
6461     assert(!signbit(0.0L));
6462     assert(signbit(-0.0L));
6463     assert(signbit(-real.max));
6464     assert(!signbit(real.max));
6465 }
6466 
6467 @nogc @safe pure nothrow unittest
6468 {
6469     // CTFE
6470     static assert(!signbit(float.nan));
6471     static assert(signbit(-float.nan));
6472     static assert(!signbit(168.1234f));
6473     static assert(signbit(-168.1234f));
6474     static assert(!signbit(0.0f));
6475     static assert(signbit(-0.0f));
6476     static assert(signbit(-float.max));
6477     static assert(!signbit(float.max));
6478 
6479     static assert(!signbit(double.nan));
6480     static assert(signbit(-double.nan));
6481     static assert(!signbit(168.1234));
6482     static assert(signbit(-168.1234));
6483     static assert(!signbit(0.0));
6484     static assert(signbit(-0.0));
6485     static assert(signbit(-double.max));
6486     static assert(!signbit(double.max));
6487 
6488     static assert(!signbit(real.nan));
6489     static assert(signbit(-real.nan));
6490     static assert(!signbit(168.1234L));
6491     static assert(signbit(-168.1234L));
6492     static assert(!signbit(0.0L));
6493     static assert(signbit(-0.0L));
6494     static assert(signbit(-real.max));
6495     static assert(!signbit(real.max));
6496 }
6497 
6498 /**
6499 Params:
6500     to = the numeric value to use
6501     from = the sign value to use
6502 Returns:
6503     a value composed of to with from's sign bit.
6504  */
6505 R copysign(R, X)(R to, X from) @trusted pure nothrow @nogc
6506 if (isFloatingPoint!(R) && isFloatingPoint!(X))
6507 {
6508     if (__ctfe)
6509     {
6510         return signbit(to) == signbit(from) ? to : -to;
6511     }
6512     ubyte* pto   = cast(ubyte *)&to;
6513     const ubyte* pfrom = cast(ubyte *)&from;
6514 
6515     alias T = floatTraits!(R);
6516     alias F = floatTraits!(X);
6517     pto[T.SIGNPOS_BYTE] &= 0x7F;
6518     pto[T.SIGNPOS_BYTE] |= pfrom[F.SIGNPOS_BYTE] & 0x80;
6519     return to;
6520 }
6521 
6522 /// ditto
6523 R copysign(R, X)(X to, R from) @trusted pure nothrow @nogc
6524 if (isIntegral!(X) && isFloatingPoint!(R))
6525 {
6526     return copysign(cast(R) to, from);
6527 }
6528 
6529 ///
6530 @safe pure nothrow @nogc unittest
6531 {
6532     assert(copysign(1.0, 1.0) == 1.0);
6533     assert(copysign(1.0, -0.0) == -1.0);
6534     assert(copysign(1UL, -1.0) == -1.0);
6535     assert(copysign(-1.0, -1.0) == -1.0);
6536 
6537     assert(copysign(real.infinity, -1.0) == -real.infinity);
6538     assert(copysign(real.nan, 1.0) is real.nan);
6539     assert(copysign(-real.nan, 1.0) is real.nan);
6540     assert(copysign(real.nan, -1.0) is -real.nan);
6541 }
6542 
6543 @safe pure nothrow @nogc unittest
6544 {
6545     import std.meta : AliasSeq;
6546 
6547     static foreach (X; AliasSeq!(float, double, real, int, long))
6548     {
6549         static foreach (Y; AliasSeq!(float, double, real))
6550         {{
6551             X x = 21;
6552             Y y = 23.8;
6553             Y e = void;
6554 
6555             e = copysign(x, y);
6556             assert(e == 21.0);
6557 
6558             e = copysign(-x, y);
6559             assert(e == 21.0);
6560 
6561             e = copysign(x, -y);
6562             assert(e == -21.0);
6563 
6564             e = copysign(-x, -y);
6565             assert(e == -21.0);
6566 
6567             static if (isFloatingPoint!X)
6568             {
6569                 e = copysign(X.nan, y);
6570                 assert(isNaN(e) && !signbit(e));
6571 
6572                 e = copysign(X.nan, -y);
6573                 assert(isNaN(e) && signbit(e));
6574             }
6575         }}
6576     }
6577     // CTFE
6578     static foreach (X; AliasSeq!(float, double, real, int, long))
6579     {
6580         static foreach (Y; AliasSeq!(float, double, real))
6581         {{
6582             enum X x = 21;
6583             enum Y y = 23.8;
6584 
6585             assert(21.0 == copysign(x, y));
6586             assert(21.0 == copysign(-x, y));
6587             assert(-21.0 == copysign(x, -y));
6588             assert(-21.0 == copysign(-x, -y));
6589 
6590             static if (isFloatingPoint!X)
6591             {
6592                 static assert(isNaN(copysign(X.nan, y)) && !signbit(copysign(X.nan, y)));
6593                 assert(isNaN(copysign(X.nan, -y)) && signbit(copysign(X.nan, -y)));
6594             }
6595         }}
6596     }
6597 }
6598 
6599 /*********************************
6600 Returns `-1` if $(D x < 0), `x` if $(D x == 0), `1` if
6601 $(D x > 0), and $(NAN) if x==$(NAN).
6602  */
6603 F sgn(F)(F x) @safe pure nothrow @nogc
6604 if (isFloatingPoint!F || isIntegral!F)
6605 {
6606     // @@@TODO@@@: make this faster
6607     return x > 0 ? 1 : x < 0 ? -1 : x;
6608 }
6609 
6610 ///
6611 @safe pure nothrow @nogc unittest
6612 {
6613     assert(sgn(168.1234) == 1);
6614     assert(sgn(-168.1234) == -1);
6615     assert(sgn(0.0) == 0);
6616     assert(sgn(-0.0) == 0);
6617 }
6618 
6619 // Functions for NaN payloads
6620 /*
6621  * A 'payload' can be stored in the significand of a $(NAN). One bit is required
6622  * to distinguish between a quiet and a signalling $(NAN). This leaves 22 bits
6623  * of payload for a float; 51 bits for a double; 62 bits for an 80-bit real;
6624  * and 111 bits for a 128-bit quad.
6625 */
6626 /**
6627  * Create a quiet $(NAN), storing an integer inside the payload.
6628  *
6629  * For floats, the largest possible payload is 0x3F_FFFF.
6630  * For doubles, it is 0x3_FFFF_FFFF_FFFF.
6631  * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
6632  */
6633 real NaN(ulong payload) @trusted pure nothrow @nogc
6634 {
6635     alias F = floatTraits!(real);
6636     static if (F.realFormat == RealFormat.ieeeExtended)
6637     {
6638         // real80 (in x86 real format, the implied bit is actually
6639         // not implied but a real bit which is stored in the real)
6640         ulong v = 3; // implied bit = 1, quiet bit = 1
6641     }
6642     else
6643     {
6644         ulong v = 1; // no implied bit. quiet bit = 1
6645     }
6646 
6647     ulong a = payload;
6648 
6649     // 22 Float bits
6650     ulong w = a & 0x3F_FFFF;
6651     a -= w;
6652 
6653     v <<=22;
6654     v |= w;
6655     a >>=22;
6656 
6657     // 29 Double bits
6658     v <<=29;
6659     w = a & 0xFFF_FFFF;
6660     v |= w;
6661     a -= w;
6662     a >>=29;
6663 
6664     static if (F.realFormat == RealFormat.ieeeDouble)
6665     {
6666         v |= 0x7FF0_0000_0000_0000;
6667         real x;
6668         * cast(ulong *)(&x) = v;
6669         return x;
6670     }
6671     else
6672     {
6673         v <<=11;
6674         a &= 0x7FF;
6675         v |= a;
6676         real x = real.nan;
6677 
6678         // Extended real bits
6679         static if (F.realFormat == RealFormat.ieeeQuadruple)
6680         {
6681             v <<= 1; // there's no implicit bit
6682 
6683             version (LittleEndian)
6684             {
6685                 *cast(ulong*)(6+cast(ubyte*)(&x)) = v;
6686             }
6687             else
6688             {
6689                 *cast(ulong*)(2+cast(ubyte*)(&x)) = v;
6690             }
6691         }
6692         else
6693         {
6694             *cast(ulong *)(&x) = v;
6695         }
6696         return x;
6697     }
6698 }
6699 
6700 ///
6701 @safe @nogc pure nothrow unittest
6702 {
6703     real a = NaN(1_000_000);
6704     assert(isNaN(a));
6705     assert(getNaNPayload(a) == 1_000_000);
6706 }
6707 
6708 @system pure nothrow @nogc unittest // not @safe because taking address of local.
6709 {
6710     static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
6711     {
6712         auto x = NaN(1);
6713         auto xl = *cast(ulong*)&x;
6714         assert(xl & 0x8_0000_0000_0000UL); //non-signaling bit, bit 52
6715         assert((xl & 0x7FF0_0000_0000_0000UL) == 0x7FF0_0000_0000_0000UL); //all exp bits set
6716     }
6717 }
6718 
6719 /**
6720  * Extract an integral payload from a $(NAN).
6721  *
6722  * Returns:
6723  * the integer payload as a ulong.
6724  *
6725  * For floats, the largest possible payload is 0x3F_FFFF.
6726  * For doubles, it is 0x3_FFFF_FFFF_FFFF.
6727  * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
6728  */
6729 ulong getNaNPayload(real x) @trusted pure nothrow @nogc
6730 {
6731     //  assert(isNaN(x));
6732     alias F = floatTraits!(real);
6733     static if (F.realFormat == RealFormat.ieeeDouble)
6734     {
6735         ulong m = *cast(ulong *)(&x);
6736         // Make it look like an 80-bit significand.
6737         // Skip exponent, and quiet bit
6738         m &= 0x0007_FFFF_FFFF_FFFF;
6739         m <<= 11;
6740     }
6741     else static if (F.realFormat == RealFormat.ieeeQuadruple)
6742     {
6743         version (LittleEndian)
6744         {
6745             ulong m = *cast(ulong*)(6+cast(ubyte*)(&x));
6746         }
6747         else
6748         {
6749             ulong m = *cast(ulong*)(2+cast(ubyte*)(&x));
6750         }
6751 
6752         m >>= 1; // there's no implicit bit
6753     }
6754     else
6755     {
6756         ulong m = *cast(ulong *)(&x);
6757     }
6758 
6759     // ignore implicit bit and quiet bit
6760 
6761     const ulong f = m & 0x3FFF_FF00_0000_0000L;
6762 
6763     ulong w = f >>> 40;
6764             w |= (m & 0x00FF_FFFF_F800L) << (22 - 11);
6765             w |= (m & 0x7FF) << 51;
6766             return w;
6767 }
6768 
6769 ///
6770 @safe @nogc pure nothrow unittest
6771 {
6772     real a = NaN(1_000_000);
6773     assert(isNaN(a));
6774     assert(getNaNPayload(a) == 1_000_000);
6775 }
6776 
6777 debug(UnitTest)
6778 {
6779     @safe pure nothrow @nogc unittest
6780     {
6781         real nan4 = NaN(0x789_ABCD_EF12_3456);
6782         static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended
6783                 || floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)
6784         {
6785             assert(getNaNPayload(nan4) == 0x789_ABCD_EF12_3456);
6786         }
6787         else
6788         {
6789             assert(getNaNPayload(nan4) == 0x1_ABCD_EF12_3456);
6790         }
6791         double nan5 = nan4;
6792         assert(getNaNPayload(nan5) == 0x1_ABCD_EF12_3456);
6793         float nan6 = nan4;
6794         assert(getNaNPayload(nan6) == 0x12_3456);
6795         nan4 = NaN(0xFABCD);
6796         assert(getNaNPayload(nan4) == 0xFABCD);
6797         nan6 = nan4;
6798         assert(getNaNPayload(nan6) == 0xFABCD);
6799         nan5 = NaN(0x100_0000_0000_3456);
6800         assert(getNaNPayload(nan5) == 0x0000_0000_3456);
6801     }
6802 }
6803 
6804 /**
6805  * Calculate the next largest floating point value after x.
6806  *
6807  * Return the least number greater than x that is representable as a real;
6808  * thus, it gives the next point on the IEEE number line.
6809  *
6810  *  $(TABLE_SV
6811  *    $(SVH x,            nextUp(x)   )
6812  *    $(SV  -$(INFIN),    -real.max   )
6813  *    $(SV  $(PLUSMN)0.0, real.min_normal*real.epsilon )
6814  *    $(SV  real.max,     $(INFIN) )
6815  *    $(SV  $(INFIN),     $(INFIN) )
6816  *    $(SV  $(NAN),       $(NAN)   )
6817  * )
6818  */
6819 real nextUp(real x) @trusted pure nothrow @nogc
6820 {
6821     alias F = floatTraits!(real);
6822     static if (F.realFormat == RealFormat.ieeeDouble)
6823     {
6824         return nextUp(cast(double) x);
6825     }
6826     else static if (F.realFormat == RealFormat.ieeeQuadruple)
6827     {
6828         ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
6829         if (e == F.EXPMASK)
6830         {
6831             // NaN or Infinity
6832             if (x == -real.infinity) return -real.max;
6833             return x; // +Inf and NaN are unchanged.
6834         }
6835 
6836         auto ps = cast(ulong *)&x;
6837         if (ps[MANTISSA_MSB] & 0x8000_0000_0000_0000)
6838         {
6839             // Negative number
6840             if (ps[MANTISSA_LSB] == 0 && ps[MANTISSA_MSB] == 0x8000_0000_0000_0000)
6841             {
6842                 // it was negative zero, change to smallest subnormal
6843                 ps[MANTISSA_LSB] = 1;
6844                 ps[MANTISSA_MSB] = 0;
6845                 return x;
6846             }
6847             if (ps[MANTISSA_LSB] == 0) --ps[MANTISSA_MSB];
6848             --ps[MANTISSA_LSB];
6849         }
6850         else
6851         {
6852             // Positive number
6853             ++ps[MANTISSA_LSB];
6854             if (ps[MANTISSA_LSB] == 0) ++ps[MANTISSA_MSB];
6855         }
6856         return x;
6857     }
6858     else static if (F.realFormat == RealFormat.ieeeExtended)
6859     {
6860         // For 80-bit reals, the "implied bit" is a nuisance...
6861         ushort *pe = cast(ushort *)&x;
6862         ulong  *ps = cast(ulong  *)&x;
6863 
6864         if ((pe[F.EXPPOS_SHORT] & F.EXPMASK) == F.EXPMASK)
6865         {
6866             // First, deal with NANs and infinity
6867             if (x == -real.infinity) return -real.max;
6868             return x; // +Inf and NaN are unchanged.
6869         }
6870         if (pe[F.EXPPOS_SHORT] & 0x8000)
6871         {
6872             // Negative number -- need to decrease the significand
6873             --*ps;
6874             // Need to mask with 0x7FFF... so subnormals are treated correctly.
6875             if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_FFFF_FFFF_FFFF)
6876             {
6877                 if (pe[F.EXPPOS_SHORT] == 0x8000)   // it was negative zero
6878                 {
6879                     *ps = 1;
6880                     pe[F.EXPPOS_SHORT] = 0; // smallest subnormal.
6881                     return x;
6882                 }
6883 
6884                 --pe[F.EXPPOS_SHORT];
6885 
6886                 if (pe[F.EXPPOS_SHORT] == 0x8000)
6887                     return x; // it's become a subnormal, implied bit stays low.
6888 
6889                 *ps = 0xFFFF_FFFF_FFFF_FFFF; // set the implied bit
6890                 return x;
6891             }
6892             return x;
6893         }
6894         else
6895         {
6896             // Positive number -- need to increase the significand.
6897             // Works automatically for positive zero.
6898             ++*ps;
6899             if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0)
6900             {
6901                 // change in exponent
6902                 ++pe[F.EXPPOS_SHORT];
6903                 *ps = 0x8000_0000_0000_0000; // set the high bit
6904             }
6905         }
6906         return x;
6907     }
6908     else // static if (F.realFormat == RealFormat.ibmExtended)
6909     {
6910         assert(0, "nextUp not implemented");
6911     }
6912 }
6913 
6914 /** ditto */
6915 double nextUp(double x) @trusted pure nothrow @nogc
6916 {
6917     ulong s = *cast(ulong *)&x;
6918 
6919     if ((s & 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000)
6920     {
6921         // First, deal with NANs and infinity
6922         if (x == -x.infinity) return -x.max;
6923         return x; // +INF and NAN are unchanged.
6924     }
6925     if (s & 0x8000_0000_0000_0000)    // Negative number
6926     {
6927         if (s == 0x8000_0000_0000_0000) // it was negative zero
6928         {
6929             s = 0x0000_0000_0000_0001; // change to smallest subnormal
6930             return *cast(double*) &s;
6931         }
6932         --s;
6933     }
6934     else
6935     {   // Positive number
6936         ++s;
6937     }
6938     return *cast(double*) &s;
6939 }
6940 
6941 /** ditto */
6942 float nextUp(float x) @trusted pure nothrow @nogc
6943 {
6944     uint s = *cast(uint *)&x;
6945 
6946     if ((s & 0x7F80_0000) == 0x7F80_0000)
6947     {
6948         // First, deal with NANs and infinity
6949         if (x == -x.infinity) return -x.max;
6950 
6951         return x; // +INF and NAN are unchanged.
6952     }
6953     if (s & 0x8000_0000)   // Negative number
6954     {
6955         if (s == 0x8000_0000) // it was negative zero
6956         {
6957             s = 0x0000_0001; // change to smallest subnormal
6958             return *cast(float*) &s;
6959         }
6960 
6961         --s;
6962     }
6963     else
6964     {
6965         // Positive number
6966         ++s;
6967     }
6968     return *cast(float*) &s;
6969 }
6970 
6971 ///
6972 @safe @nogc pure nothrow unittest
6973 {
6974     assert(nextUp(1.0 - 1.0e-6).feqrel(0.999999) > 16);
6975     assert(nextUp(1.0 - real.epsilon).feqrel(1.0) > 16);
6976 }
6977 
6978 /**
6979  * Calculate the next smallest floating point value before x.
6980  *
6981  * Return the greatest number less than x that is representable as a real;
6982  * thus, it gives the previous point on the IEEE number line.
6983  *
6984  *  $(TABLE_SV
6985  *    $(SVH x,            nextDown(x)   )
6986  *    $(SV  $(INFIN),     real.max  )
6987  *    $(SV  $(PLUSMN)0.0, -real.min_normal*real.epsilon )
6988  *    $(SV  -real.max,    -$(INFIN) )
6989  *    $(SV  -$(INFIN),    -$(INFIN) )
6990  *    $(SV  $(NAN),       $(NAN)    )
6991  * )
6992  */
6993 real nextDown(real x) @safe pure nothrow @nogc
6994 {
6995     return -nextUp(-x);
6996 }
6997 
6998 /** ditto */
6999 double nextDown(double x) @safe pure nothrow @nogc
7000 {
7001     return -nextUp(-x);
7002 }
7003 
7004 /** ditto */
7005 float nextDown(float x) @safe pure nothrow @nogc
7006 {
7007     return -nextUp(-x);
7008 }
7009 
7010 ///
7011 @safe pure nothrow @nogc unittest
7012 {
7013     assert( nextDown(1.0 + real.epsilon) == 1.0);
7014 }
7015 
7016 @safe pure nothrow @nogc unittest
7017 {
7018     static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
7019     {
7020 
7021         // Tests for 80-bit reals
7022         assert(isIdentical(nextUp(NaN(0xABC)), NaN(0xABC)));
7023         // negative numbers
7024         assert( nextUp(-real.infinity) == -real.max );
7025         assert( nextUp(-1.0L-real.epsilon) == -1.0 );
7026         assert( nextUp(-2.0L) == -2.0 + real.epsilon);
7027         // subnormals and zero
7028         assert( nextUp(-real.min_normal) == -real.min_normal*(1-real.epsilon) );
7029         assert( nextUp(-real.min_normal*(1-real.epsilon)) == -real.min_normal*(1-2*real.epsilon) );
7030         assert( isIdentical(-0.0L, nextUp(-real.min_normal*real.epsilon)) );
7031         assert( nextUp(-0.0L) == real.min_normal*real.epsilon );
7032         assert( nextUp(0.0L) == real.min_normal*real.epsilon );
7033         assert( nextUp(real.min_normal*(1-real.epsilon)) == real.min_normal );
7034         assert( nextUp(real.min_normal) == real.min_normal*(1+real.epsilon) );
7035         // positive numbers
7036         assert( nextUp(1.0L) == 1.0 + real.epsilon );
7037         assert( nextUp(2.0L-real.epsilon) == 2.0 );
7038         assert( nextUp(real.max) == real.infinity );
7039         assert( nextUp(real.infinity)==real.infinity );
7040     }
7041 
7042     double n = NaN(0xABC);
7043     assert(isIdentical(nextUp(n), n));
7044     // negative numbers
7045     assert( nextUp(-double.infinity) == -double.max );
7046     assert( nextUp(-1-double.epsilon) == -1.0 );
7047     assert( nextUp(-2.0) == -2.0 + double.epsilon);
7048     // subnormals and zero
7049 
7050     assert( nextUp(-double.min_normal) == -double.min_normal*(1-double.epsilon) );
7051     assert( nextUp(-double.min_normal*(1-double.epsilon)) == -double.min_normal*(1-2*double.epsilon) );
7052     assert( isIdentical(-0.0, nextUp(-double.min_normal*double.epsilon)) );
7053     assert( nextUp(0.0) == double.min_normal*double.epsilon );
7054     assert( nextUp(-0.0) == double.min_normal*double.epsilon );
7055     assert( nextUp(double.min_normal*(1-double.epsilon)) == double.min_normal );
7056     assert( nextUp(double.min_normal) == double.min_normal*(1+double.epsilon) );
7057     // positive numbers
7058     assert( nextUp(1.0) == 1.0 + double.epsilon );
7059     assert( nextUp(2.0-double.epsilon) == 2.0 );
7060     assert( nextUp(double.max) == double.infinity );
7061 
7062     float fn = NaN(0xABC);
7063     assert(isIdentical(nextUp(fn), fn));
7064     float f = -float.min_normal*(1-float.epsilon);
7065     float f1 = -float.min_normal;
7066     assert( nextUp(f1) ==  f);
7067     f = 1.0f+float.epsilon;
7068     f1 = 1.0f;
7069     assert( nextUp(f1) == f );
7070     f1 = -0.0f;
7071     assert( nextUp(f1) == float.min_normal*float.epsilon);
7072     assert( nextUp(float.infinity)==float.infinity );
7073 
7074     assert(nextDown(1.0L+real.epsilon)==1.0);
7075     assert(nextDown(1.0+double.epsilon)==1.0);
7076     f = 1.0f+float.epsilon;
7077     assert(nextDown(f)==1.0);
7078     assert(nextafter(1.0+real.epsilon, -real.infinity)==1.0);
7079 
7080     // CTFE
7081 
7082     //enum double n = NaN(0xABC); // FIXME: Cannot set NaN payload in CTFE.
7083     //static assert(isIdentical(nextUp(n), n)); // FIXME: https://issues.dlang.org/show_bug.cgi?id=20197
7084     static assert(nextUp(double.nan) is double.nan);
7085     // negative numbers
7086     static assert( nextUp(-double.infinity) == -double.max );
7087     static assert( nextUp(-1-double.epsilon) == -1.0 );
7088     static assert( nextUp(-2.0) == -2.0 + double.epsilon);
7089     // subnormals and zero
7090 
7091     static assert( nextUp(-double.min_normal) == -double.min_normal*(1-double.epsilon) );
7092     static assert( nextUp(-double.min_normal*(1-double.epsilon)) == -double.min_normal*(1-2*double.epsilon) );
7093     static assert( -0.0 is nextUp(-double.min_normal*double.epsilon) );
7094     static assert( nextUp(0.0) == double.min_normal*double.epsilon );
7095     static assert( nextUp(-0.0) == double.min_normal*double.epsilon );
7096     static assert( nextUp(double.min_normal*(1-double.epsilon)) == double.min_normal );
7097     static assert( nextUp(double.min_normal) == double.min_normal*(1+double.epsilon) );
7098     // positive numbers
7099     static assert( nextUp(1.0) == 1.0 + double.epsilon );
7100     static assert( nextUp(2.0-double.epsilon) == 2.0 );
7101     static assert( nextUp(double.max) == double.infinity );
7102 
7103     //enum float fn = NaN(0xABC); // FIXME: Cannot set NaN payload in CTFE.
7104     //static assert(isIdentical(nextUp(fn), fn)); // FIXME: https://issues.dlang.org/show_bug.cgi?id=20197
7105     static assert(nextUp(float.nan) is float.nan);
7106     static assert(nextUp(-float.min_normal) == -float.min_normal*(1-float.epsilon));
7107     static assert(nextUp(1.0f) == 1.0f+float.epsilon);
7108     static assert(nextUp(-0.0f) == float.min_normal*float.epsilon);
7109     static assert(nextUp(float.infinity)==float.infinity);
7110     //static assert(nextDown(1.0L+real.epsilon)==1.0);
7111     static assert(nextDown(1.0+double.epsilon)==1.0);
7112     static assert(nextDown(1.0f+float.epsilon)==1.0);
7113     //static assert(nextafter(1.0+real.epsilon, -real.infinity)==1.0);
7114 }
7115 
7116 
7117 
7118 /******************************************
7119  * Calculates the next representable value after x in the direction of y.
7120  *
7121  * If y > x, the result will be the next largest floating-point value;
7122  * if y < x, the result will be the next smallest value.
7123  * If x == y, the result is y.
7124  * If x or y is a NaN, the result is a NaN.
7125  *
7126  * Remarks:
7127  * This function is not generally very useful; it's almost always better to use
7128  * the faster functions nextUp() or nextDown() instead.
7129  *
7130  * The FE_INEXACT and FE_OVERFLOW exceptions will be raised if x is finite and
7131  * the function result is infinite. The FE_INEXACT and FE_UNDERFLOW
7132  * exceptions will be raised if the function value is subnormal, and x is
7133  * not equal to y.
7134  */
7135 T nextafter(T)(const T x, const T y) @safe pure nothrow @nogc
7136 {
7137     if (x == y || isNaN(y))
7138     {
7139         return y;
7140     }
7141 
7142     if (isNaN(x))
7143     {
7144         return x;
7145     }
7146 
7147     return ((y>x) ? nextUp(x) :  nextDown(x));
7148 }
7149 
7150 ///
7151 @safe pure nothrow @nogc unittest
7152 {
7153     float a = 1;
7154     assert(is(typeof(nextafter(a, a)) == float));
7155     assert(nextafter(a, a.infinity) > a);
7156     assert(isNaN(nextafter(a, a.nan)));
7157     assert(isNaN(nextafter(a.nan, a)));
7158 
7159     double b = 2;
7160     assert(is(typeof(nextafter(b, b)) == double));
7161     assert(nextafter(b, b.infinity) > b);
7162     assert(isNaN(nextafter(b, b.nan)));
7163     assert(isNaN(nextafter(b.nan, b)));
7164 
7165     real c = 3;
7166     assert(is(typeof(nextafter(c, c)) == real));
7167     assert(nextafter(c, c.infinity) > c);
7168     assert(isNaN(nextafter(c, c.nan)));
7169     assert(isNaN(nextafter(c.nan, c)));
7170 }
7171 
7172 @safe pure nothrow @nogc unittest
7173 {
7174     // CTFE
7175     enum float a = 1;
7176     static assert(is(typeof(nextafter(a, a)) == float));
7177     static assert(nextafter(a, a.infinity) > a);
7178     static assert(isNaN(nextafter(a, a.nan)));
7179     static assert(isNaN(nextafter(a.nan, a)));
7180 
7181     enum double b = 2;
7182     static assert(is(typeof(nextafter(b, b)) == double));
7183     static assert(nextafter(b, b.infinity) > b);
7184     static assert(isNaN(nextafter(b, b.nan)));
7185     static assert(isNaN(nextafter(b.nan, b)));
7186 
7187     enum real c = 3;
7188     static assert(is(typeof(nextafter(c, c)) == real));
7189     //static assert(nextafter(c, c.infinity) > c);
7190 
7191     enum real negZero = nextafter(+0.0L, -0.0L); // specially CTFEable
7192     static assert(negZero == -0.0L);
7193     static assert(signbit(negZero));
7194 
7195     static assert(nextafter(c, c) == c); // ditto
7196     static assert(isNaN(nextafter(c, c.nan))); // ditto
7197     static assert(isNaN(nextafter(c.nan, c))); // ditto
7198 }
7199 
7200 //real nexttoward(real x, real y) { return core.stdc.math.nexttowardl(x, y); }
7201 
7202 /**
7203  * Returns the positive difference between x and y.
7204  *
7205  * Equivalent to `fmax(x-y, 0)`.
7206  *
7207  * Returns:
7208  *      $(TABLE_SV
7209  *      $(TR $(TH x, y)       $(TH fdim(x, y)))
7210  *      $(TR $(TD x $(GT) y)  $(TD x - y))
7211  *      $(TR $(TD x $(LT)= y) $(TD +0.0))
7212  *      )
7213  */
7214 real fdim(real x, real y) @safe pure nothrow @nogc
7215 {
7216     return (x < y) ? +0.0 : x - y;
7217 }
7218 
7219 ///
7220 @safe pure nothrow @nogc unittest
7221 {
7222     assert(fdim(2.0, 0.0) == 2.0);
7223     assert(fdim(-2.0, 0.0) == 0.0);
7224     assert(fdim(real.infinity, 2.0) == real.infinity);
7225     assert(isNaN(fdim(real.nan, 2.0)));
7226     assert(isNaN(fdim(2.0, real.nan)));
7227     assert(isNaN(fdim(real.nan, real.nan)));
7228 }
7229 
7230 /**
7231  * Returns the larger of x and y.
7232  *
7233  * If one of the arguments is a NaN, the other is returned.
7234  */
7235 real fmax(real x, real y) @safe pure nothrow @nogc
7236 {
7237     return (y > x || isNaN(x)) ? y : x;
7238 }
7239 
7240 ///
7241 @safe pure nothrow @nogc unittest
7242 {
7243     assert(fmax(0.0, 2.0) == 2.0);
7244     assert(fmax(-2.0, 0.0) == 0.0);
7245     assert(fmax(real.infinity, 2.0) == real.infinity);
7246     assert(fmax(real.nan, 2.0) == 2.0);
7247     assert(fmax(2.0, real.nan) == 2.0);
7248 }
7249 
7250 /**
7251  * Returns the smaller of x and y.
7252  *
7253  * If one of the arguments is a NaN, the other is returned.
7254  */
7255 real fmin(real x, real y) @safe pure nothrow @nogc
7256 {
7257     return (y < x || isNaN(x)) ? y : x;
7258 }
7259 
7260 ///
7261 @safe pure nothrow @nogc unittest
7262 {
7263     assert(fmin(0.0, 2.0) == 0.0);
7264     assert(fmin(-2.0, 0.0) == -2.0);
7265     assert(fmin(real.infinity, 2.0) == 2.0);
7266     assert(fmin(real.nan, 2.0) == 2.0);
7267     assert(fmin(2.0, real.nan) == 2.0);
7268 }
7269 
7270 /**************************************
7271  * Returns (x * y) + z, rounding only once according to the
7272  * current rounding mode.
7273  *
7274  * BUGS: Not currently implemented - rounds twice.
7275  */
7276 real fma(real x, real y, real z) @safe pure nothrow @nogc { return (x * y) + z; }
7277 
7278 ///
7279 @safe pure nothrow @nogc unittest
7280 {
7281     assert(fma(0.0, 2.0, 2.0) == 2.0);
7282     assert(fma(2.0, 2.0, 2.0) == 6.0);
7283     assert(fma(real.infinity, 2.0, 2.0) == real.infinity);
7284     assert(fma(real.nan, 2.0, 2.0) is real.nan);
7285     assert(fma(2.0, 2.0, real.nan) is real.nan);
7286 }
7287 
7288 /**
7289  * Compute the value of x $(SUPERSCRIPT n), where n is an integer
7290  */
7291 Unqual!F pow(F, G)(F x, G n) @nogc @trusted pure nothrow
7292 if (isFloatingPoint!(F) && isIntegral!(G))
7293 {
7294     import std.traits : Unsigned, isSigned;
7295     real p = 1.0, v = void;
7296     Unsigned!(Unqual!G) m = n;
7297 
7298     static if (G.sizeof < 4 && !isSigned!G)
7299     {
7300         import std.conv : to;
7301         const int n2 = n.to!int;
7302     }
7303     else alias n2 = n;
7304 
7305     if (n < 0)
7306     {
7307         switch (n2)
7308         {
7309         case -1:
7310             return 1 / x;
7311         case -2:
7312             return 1 / (x * x);
7313         default:
7314         }
7315 
7316         m = cast(typeof(m))(0 - n);
7317         v = p / x;
7318     }
7319     else
7320     {
7321         switch (n)
7322         {
7323         case 0:
7324             return 1.0;
7325         case 1:
7326             return x;
7327         case 2:
7328             return x * x;
7329         default:
7330         }
7331 
7332         v = x;
7333     }
7334 
7335     while (1)
7336     {
7337         if (m & 1)
7338             p *= v;
7339         m >>= 1;
7340         if (!m)
7341             break;
7342         v *= v;
7343     }
7344     return p;
7345 }
7346 
7347 ///
7348 @safe pure nothrow @nogc unittest
7349 {
7350     assert(pow(2.0, 5) == 32.0);
7351     assert(pow(1.5, 9).feqrel(38.4433) > 16);
7352     assert(pow(real.nan, 2) is real.nan);
7353     assert(pow(real.infinity, 2) == real.infinity);
7354 }
7355 
7356 @safe pure nothrow @nogc unittest
7357 {
7358     // Make sure it instantiates and works properly on immutable values and
7359     // with various integer and float types.
7360     immutable real x = 46;
7361     immutable float xf = x;
7362     immutable double xd = x;
7363     immutable uint one = 1;
7364     immutable ushort two = 2;
7365     immutable ubyte three = 3;
7366     immutable ulong eight = 8;
7367 
7368     immutable int neg1 = -1;
7369     immutable short neg2 = -2;
7370     immutable byte neg3 = -3;
7371     immutable long neg8 = -8;
7372 
7373 
7374     assert(pow(x,0) == 1.0);
7375     assert(pow(xd,one) == x);
7376     assert(pow(xf,two) == x * x);
7377     assert(pow(x,three) == x * x * x);
7378     assert(pow(x,eight) == (x * x) * (x * x) * (x * x) * (x * x));
7379 
7380     assert(pow(x, neg1) == 1 / x);
7381 
7382     assert(approxEqual(pow(xd, neg2), cast(double) (1 / (x * x)), 1e-25, 0.0));
7383     assert(approxEqual(pow(xf, neg8), cast(float) (1 / ((x * x) * (x * x) * (x * x) * (x * x))), 1e-15, 0.0));
7384 
7385     assert(feqrel(pow(x, neg3),  1 / (x * x * x)) >= real.mant_dig - 1);
7386 }
7387 
7388 @safe @nogc nothrow unittest
7389 {
7390     assert(equalsDigit(pow(2.0L, 10.0L), 1024, 19));
7391 }
7392 
7393 /**
7394  * Compute the power of two integral numbers.
7395  *
7396  * Params:
7397  *     x = base
7398  *     n = exponent
7399  *
7400  * Returns:
7401  *     x raised to the power of n. If n is negative the result is 1 / pow(x, -n),
7402  *     which is calculated as integer division with remainder. This may result in
7403  *     a division by zero error.
7404  *
7405  *     If both x and n are 0, the result is 1.
7406  *
7407  * Throws:
7408  *     If x is 0 and n is negative, the result is the same as the result of a
7409  *     division by zero.
7410  */
7411 typeof(Unqual!(F).init * Unqual!(G).init) pow(F, G)(F x, G n) @nogc @trusted pure nothrow
7412 if (isIntegral!(F) && isIntegral!(G))
7413 {
7414     typeof(return) p, v = void;
7415     Unqual!G m = n;
7416 
7417     static if (isSigned!(F))
7418     {
7419         if (x == -1) return cast(typeof(return)) (m & 1 ? -1 : 1);
7420     }
7421     static if (isSigned!(G))
7422     {
7423         if (x == 0 && m <= -1) return x / 0;
7424     }
7425     if (x == 1) return 1;
7426     static if (isSigned!(G))
7427     {
7428         if (m < 0) return 0;
7429     }
7430 
7431     switch (m)
7432     {
7433     case 0:
7434         p = 1;
7435         break;
7436 
7437     case 1:
7438         p = x;
7439         break;
7440 
7441     case 2:
7442         p = x * x;
7443         break;
7444 
7445     default:
7446         v = x;
7447         p = 1;
7448         while (1)
7449         {
7450             if (m & 1)
7451                 p *= v;
7452             m >>= 1;
7453             if (!m)
7454                 break;
7455             v *= v;
7456         }
7457         break;
7458     }
7459     return p;
7460 }
7461 
7462 ///
7463 @safe pure nothrow @nogc unittest
7464 {
7465     assert(pow(2, 3) == 8);
7466     assert(pow(3, 2) == 9);
7467 
7468     assert(pow(2, 10) == 1_024);
7469     assert(pow(2, 20) == 1_048_576);
7470     assert(pow(2, 30) == 1_073_741_824);
7471 
7472     assert(pow(0, 0) == 1);
7473 
7474     assert(pow(1, -5) == 1);
7475     assert(pow(1, -6) == 1);
7476     assert(pow(-1, -5) == -1);
7477     assert(pow(-1, -6) == 1);
7478 
7479     assert(pow(-2, 5) == -32);
7480     assert(pow(-2, -5) == 0);
7481     assert(pow(cast(double) -2, -5) == -0.03125);
7482 }
7483 
7484 @safe pure nothrow @nogc unittest
7485 {
7486     immutable int one = 1;
7487     immutable byte two = 2;
7488     immutable ubyte three = 3;
7489     immutable short four = 4;
7490     immutable long ten = 10;
7491 
7492     assert(pow(two, three) == 8);
7493     assert(pow(two, ten) == 1024);
7494     assert(pow(one, ten) == 1);
7495     assert(pow(ten, four) == 10_000);
7496     assert(pow(four, 10) == 1_048_576);
7497     assert(pow(three, four) == 81);
7498 }
7499 
7500 // https://issues.dlang.org/show_bug.cgi?id=7006
7501 @safe pure nothrow @nogc unittest
7502 {
7503     assert(pow(5, -1) == 0);
7504     assert(pow(-5, -1) == 0);
7505     assert(pow(5, -2) == 0);
7506     assert(pow(-5, -2) == 0);
7507     assert(pow(-1, int.min) == 1);
7508     assert(pow(-2, int.min) == 0);
7509 
7510     assert(pow(4294967290UL,2) == 18446744022169944100UL);
7511     assert(pow(0,uint.max) == 0);
7512 }
7513 
7514 /**Computes integer to floating point powers.*/
7515 real pow(I, F)(I x, F y) @nogc @trusted pure nothrow
7516 if (isIntegral!I && isFloatingPoint!F)
7517 {
7518     return pow(cast(real) x, cast(Unqual!F) y);
7519 }
7520 
7521 ///
7522 @safe pure nothrow @nogc unittest
7523 {
7524     assert(pow(2, 5.0) == 32.0);
7525     assert(pow(7, 3.0) == 343.0);
7526     assert(pow(2, real.nan) is real.nan);
7527     assert(pow(2, real.infinity) == real.infinity);
7528 }
7529 
7530 /**
7531  * Calculates x$(SUPERSCRIPT y).
7532  *
7533  * $(TABLE_SV
7534  * $(TR $(TH x) $(TH y) $(TH pow(x, y))
7535  *      $(TH div 0) $(TH invalid?))
7536  * $(TR $(TD anything)      $(TD $(PLUSMN)0.0)                $(TD 1.0)
7537  *      $(TD no)        $(TD no) )
7538  * $(TR $(TD |x| $(GT) 1)    $(TD +$(INFIN))                  $(TD +$(INFIN))
7539  *      $(TD no)        $(TD no) )
7540  * $(TR $(TD |x| $(LT) 1)    $(TD +$(INFIN))                  $(TD +0.0)
7541  *      $(TD no)        $(TD no) )
7542  * $(TR $(TD |x| $(GT) 1)    $(TD -$(INFIN))                  $(TD +0.0)
7543  *      $(TD no)        $(TD no) )
7544  * $(TR $(TD |x| $(LT) 1)    $(TD -$(INFIN))                  $(TD +$(INFIN))
7545  *      $(TD no)        $(TD no) )
7546  * $(TR $(TD +$(INFIN))      $(TD $(GT) 0.0)                  $(TD +$(INFIN))
7547  *      $(TD no)        $(TD no) )
7548  * $(TR $(TD +$(INFIN))      $(TD $(LT) 0.0)                  $(TD +0.0)
7549  *      $(TD no)        $(TD no) )
7550  * $(TR $(TD -$(INFIN))      $(TD odd integer $(GT) 0.0)      $(TD -$(INFIN))
7551  *      $(TD no)        $(TD no) )
7552  * $(TR $(TD -$(INFIN))      $(TD $(GT) 0.0, not odd integer) $(TD +$(INFIN))
7553  *      $(TD no)        $(TD no))
7554  * $(TR $(TD -$(INFIN))      $(TD odd integer $(LT) 0.0)      $(TD -0.0)
7555  *      $(TD no)        $(TD no) )
7556  * $(TR $(TD -$(INFIN))      $(TD $(LT) 0.0, not odd integer) $(TD +0.0)
7557  *      $(TD no)        $(TD no) )
7558  * $(TR $(TD $(PLUSMN)1.0)   $(TD $(PLUSMN)$(INFIN))          $(TD -$(NAN))
7559  *      $(TD no)        $(TD yes) )
7560  * $(TR $(TD $(LT) 0.0)      $(TD finite, nonintegral)        $(TD $(NAN))
7561  *      $(TD no)        $(TD yes))
7562  * $(TR $(TD $(PLUSMN)0.0)   $(TD odd integer $(LT) 0.0)      $(TD $(PLUSMNINF))
7563  *      $(TD yes)       $(TD no) )
7564  * $(TR $(TD $(PLUSMN)0.0)   $(TD $(LT) 0.0, not odd integer) $(TD +$(INFIN))
7565  *      $(TD yes)       $(TD no))
7566  * $(TR $(TD $(PLUSMN)0.0)   $(TD odd integer $(GT) 0.0)      $(TD $(PLUSMN)0.0)
7567  *      $(TD no)        $(TD no) )
7568  * $(TR $(TD $(PLUSMN)0.0)   $(TD $(GT) 0.0, not odd integer) $(TD +0.0)
7569  *      $(TD no)        $(TD no) )
7570  * )
7571  */
7572 Unqual!(Largest!(F, G)) pow(F, G)(F x, G y) @nogc @trusted pure nothrow
7573 if (isFloatingPoint!(F) && isFloatingPoint!(G))
7574 {
7575     alias Float = typeof(return);
7576 
7577     static real impl(real x, real y) @nogc pure nothrow
7578     {
7579         // Special cases.
7580         if (isNaN(y))
7581             return y;
7582         if (isNaN(x) && y != 0.0)
7583             return x;
7584 
7585         // Even if x is NaN.
7586         if (y == 0.0)
7587             return 1.0;
7588         if (y == 1.0)
7589             return x;
7590 
7591         if (isInfinity(y))
7592         {
7593             if (fabs(x) > 1)
7594             {
7595                 if (signbit(y))
7596                     return +0.0;
7597                 else
7598                     return F.infinity;
7599             }
7600             else if (fabs(x) == 1)
7601             {
7602                 return y * 0; // generate NaN.
7603             }
7604             else // < 1
7605             {
7606                 if (signbit(y))
7607                     return F.infinity;
7608                 else
7609                     return +0.0;
7610             }
7611         }
7612         if (isInfinity(x))
7613         {
7614             if (signbit(x))
7615             {
7616                 long i = cast(long) y;
7617                 if (y > 0.0)
7618                 {
7619                     if (i == y && i & 1)
7620                         return -F.infinity;
7621                     else
7622                         return F.infinity;
7623                 }
7624                 else if (y < 0.0)
7625                 {
7626                     if (i == y && i & 1)
7627                         return -0.0;
7628                     else
7629                         return +0.0;
7630                 }
7631             }
7632             else
7633             {
7634                 if (y > 0.0)
7635                     return F.infinity;
7636                 else if (y < 0.0)
7637                     return +0.0;
7638             }
7639         }
7640 
7641         if (x == 0.0)
7642         {
7643             if (signbit(x))
7644             {
7645                 long i = cast(long) y;
7646                 if (y > 0.0)
7647                 {
7648                     if (i == y && i & 1)
7649                         return -0.0;
7650                     else
7651                         return +0.0;
7652                 }
7653                 else if (y < 0.0)
7654                 {
7655                     if (i == y && i & 1)
7656                         return -F.infinity;
7657                     else
7658                         return F.infinity;
7659                 }
7660             }
7661             else
7662             {
7663                 if (y > 0.0)
7664                     return +0.0;
7665                 else if (y < 0.0)
7666                     return F.infinity;
7667             }
7668         }
7669         if (x == 1.0)
7670             return 1.0;
7671 
7672         if (y >= F.max)
7673         {
7674             if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))
7675                 return 0.0;
7676             if (x > 1.0 || x < -1.0)
7677                 return F.infinity;
7678         }
7679         if (y <= -F.max)
7680         {
7681             if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))
7682                 return F.infinity;
7683             if (x > 1.0 || x < -1.0)
7684                 return 0.0;
7685         }
7686 
7687         if (x >= F.max)
7688         {
7689             if (y > 0.0)
7690                 return F.infinity;
7691             else
7692                 return 0.0;
7693         }
7694         if (x <= -F.max)
7695         {
7696             long i = cast(long) y;
7697             if (y > 0.0)
7698             {
7699                 if (i == y && i & 1)
7700                     return -F.infinity;
7701                 else
7702                     return F.infinity;
7703             }
7704             else if (y < 0.0)
7705             {
7706                 if (i == y && i & 1)
7707                     return -0.0;
7708                 else
7709                     return +0.0;
7710             }
7711         }
7712 
7713         // Integer power of x.
7714         long iy = cast(long) y;
7715         if (iy == y && fabs(y) < 32_768.0)
7716             return pow(x, iy);
7717 
7718         real sign = 1.0;
7719         if (x < 0)
7720         {
7721             // Result is real only if y is an integer
7722             // Check for a non-zero fractional part
7723             enum maxOdd = pow(2.0L, real.mant_dig) - 1.0L;
7724             static if (maxOdd > ulong.max)
7725             {
7726                 // Generic method, for any FP type
7727                 if (floor(y) != y)
7728                     return sqrt(x); // Complex result -- create a NaN
7729 
7730                 const hy = 0.5 * y;
7731                 if (floor(hy) != hy)
7732                     sign = -1.0;
7733             }
7734             else
7735             {
7736                 // Much faster, if ulong has enough precision
7737                 const absY = fabs(y);
7738                 if (absY <= maxOdd)
7739                 {
7740                     const uy = cast(ulong) absY;
7741                     if (uy != absY)
7742                         return sqrt(x); // Complex result -- create a NaN
7743 
7744                     if (uy & 1)
7745                         sign = -1.0;
7746                 }
7747             }
7748             x = -x;
7749         }
7750         version (INLINE_YL2X)
7751         {
7752             // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )
7753             // TODO: This is not accurate in practice. A fast and accurate
7754             // (though complicated) method is described in:
7755             // "An efficient rounding boundary test for pow(x, y)
7756             // in double precision", C.Q. Lauter and V. Lefèvre, INRIA (2007).
7757             return sign * exp2( core.math.yl2x(x, y) );
7758         }
7759         else
7760         {
7761             // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )
7762             // TODO: This is not accurate in practice. A fast and accurate
7763             // (though complicated) method is described in:
7764             // "An efficient rounding boundary test for pow(x, y)
7765             // in double precision", C.Q. Lauter and V. Lefèvre, INRIA (2007).
7766             Float w = exp2(y * log2(x));
7767             return sign * w;
7768         }
7769     }
7770     return impl(x, y);
7771 }
7772 
7773 ///
7774 @safe pure nothrow @nogc unittest
7775 {
7776     assert(pow(1.0, 2.0) == 1.0);
7777     assert(pow(0.0, 0.0) == 1.0);
7778     assert(pow(1.5, 10.0).feqrel(57.665) > 16);
7779 
7780     // special values
7781     assert(pow(1.5, real.infinity) == real.infinity);
7782     assert(pow(0.5, real.infinity) == 0.0);
7783     assert(pow(1.5, -real.infinity) == 0.0);
7784     assert(pow(0.5, -real.infinity) == real.infinity);
7785     assert(pow(real.infinity, 1.0) == real.infinity);
7786     assert(pow(real.infinity, -1.0) == 0.0);
7787     assert(pow(-real.infinity, 1.0) == -real.infinity);
7788     assert(pow(-real.infinity, 2.0) == real.infinity);
7789     assert(pow(-real.infinity, -1.0) == -0.0);
7790     assert(pow(-real.infinity, -2.0) == 0.0);
7791     assert(pow(1.0, real.infinity) is -real.nan);
7792     assert(pow(0.0, -1.0) == real.infinity);
7793     assert(pow(real.nan, 0.0) == 1.0);
7794 }
7795 
7796 @safe pure nothrow @nogc unittest
7797 {
7798     // Test all the special values.  These unittests can be run on Windows
7799     // by temporarily changing the version (linux) to version (all).
7800     immutable float zero = 0;
7801     immutable real one = 1;
7802     immutable double two = 2;
7803     immutable float three = 3;
7804     immutable float fnan = float.nan;
7805     immutable double dnan = double.nan;
7806     immutable real rnan = real.nan;
7807     immutable dinf = double.infinity;
7808     immutable rninf = -real.infinity;
7809 
7810     assert(pow(fnan, zero) == 1);
7811     assert(pow(dnan, zero) == 1);
7812     assert(pow(rnan, zero) == 1);
7813 
7814     assert(pow(two, dinf) == double.infinity);
7815     assert(isIdentical(pow(0.2f, dinf), +0.0));
7816     assert(pow(0.99999999L, rninf) == real.infinity);
7817     assert(isIdentical(pow(1.000000001, rninf), +0.0));
7818     assert(pow(dinf, 0.001) == dinf);
7819     assert(isIdentical(pow(dinf, -0.001), +0.0));
7820     assert(pow(rninf, 3.0L) == rninf);
7821     assert(pow(rninf, 2.0L) == real.infinity);
7822     assert(isIdentical(pow(rninf, -3.0), -0.0));
7823     assert(isIdentical(pow(rninf, -2.0), +0.0));
7824 
7825     // @@@BUG@@@ somewhere
7826     version (OSX) {} else assert(isNaN(pow(one, dinf)));
7827     version (OSX) {} else assert(isNaN(pow(-one, dinf)));
7828     assert(isNaN(pow(-0.2, PI)));
7829     // boundary cases. Note that epsilon == 2^^-n for some n,
7830     // so 1/epsilon == 2^^n is always even.
7831     assert(pow(-1.0L, 1/real.epsilon - 1.0L) == -1.0L);
7832     assert(pow(-1.0L, 1/real.epsilon) == 1.0L);
7833     assert(isNaN(pow(-1.0L, 1/real.epsilon-0.5L)));
7834     assert(isNaN(pow(-1.0L, -1/real.epsilon+0.5L)));
7835 
7836     assert(pow(0.0, -3.0) == double.infinity);
7837     assert(pow(-0.0, -3.0) == -double.infinity);
7838     assert(pow(0.0, -PI) == double.infinity);
7839     assert(pow(-0.0, -PI) == double.infinity);
7840     assert(isIdentical(pow(0.0, 5.0), 0.0));
7841     assert(isIdentical(pow(-0.0, 5.0), -0.0));
7842     assert(isIdentical(pow(0.0, 6.0), 0.0));
7843     assert(isIdentical(pow(-0.0, 6.0), 0.0));
7844 
7845     // https://issues.dlang.org/show_bug.cgi?id=14786 fixed
7846     immutable real maxOdd = pow(2.0L, real.mant_dig) - 1.0L;
7847     assert(pow(-1.0L,  maxOdd) == -1.0L);
7848     assert(pow(-1.0L, -maxOdd) == -1.0L);
7849     assert(pow(-1.0L, maxOdd + 1.0L) == 1.0L);
7850     assert(pow(-1.0L, -maxOdd + 1.0L) == 1.0L);
7851     assert(pow(-1.0L, maxOdd - 1.0L) == 1.0L);
7852     assert(pow(-1.0L, -maxOdd - 1.0L) == 1.0L);
7853 
7854     // Now, actual numbers.
7855     assert(approxEqual(pow(two, three), 8.0));
7856     assert(approxEqual(pow(two, -2.5), 0.1767767));
7857 
7858     // Test integer to float power.
7859     immutable uint twoI = 2;
7860     assert(approxEqual(pow(twoI, three), 8.0));
7861 }
7862 
7863 /** Computes the value of a positive integer `x`, raised to the power `n`, modulo `m`.
7864  *
7865  *  Params:
7866  *      x = base
7867  *      n = exponent
7868  *      m = modulus
7869  *
7870  *  Returns:
7871  *      `x` to the power `n`, modulo `m`.
7872  *      The return type is the largest of `x`'s and `m`'s type.
7873  *
7874  * The function requires that all values have unsigned types.
7875  */
7876 Unqual!(Largest!(F, H)) powmod(F, G, H)(F x, G n, H m)
7877 if (isUnsigned!F && isUnsigned!G && isUnsigned!H)
7878 {
7879     import std.meta : AliasSeq;
7880 
7881     alias T = Unqual!(Largest!(F, H));
7882     static if (T.sizeof <= 4)
7883     {
7884         alias DoubleT = AliasSeq!(void, ushort, uint, void, ulong)[T.sizeof];
7885     }
7886 
7887     static T mulmod(T a, T b, T c)
7888     {
7889         static if (T.sizeof == 8)
7890         {
7891             static T addmod(T a, T b, T c)
7892             {
7893                 b = c - b;
7894                 if (a >= b)
7895                     return a - b;
7896                 else
7897                     return c - b + a;
7898             }
7899 
7900             T result = 0, tmp;
7901 
7902             b %= c;
7903             while (a > 0)
7904             {
7905                 if (a & 1)
7906                     result = addmod(result, b, c);
7907 
7908                 a >>= 1;
7909                 b = addmod(b, b, c);
7910             }
7911 
7912             return result;
7913         }
7914         else
7915         {
7916             DoubleT result = cast(DoubleT) (cast(DoubleT) a * cast(DoubleT) b);
7917             return result % c;
7918         }
7919     }
7920 
7921     T base = x, result = 1, modulus = m;
7922     Unqual!G exponent = n;
7923 
7924     while (exponent > 0)
7925     {
7926         if (exponent & 1)
7927             result = mulmod(result, base, modulus);
7928 
7929         base = mulmod(base, base, modulus);
7930         exponent >>= 1;
7931     }
7932 
7933     return result;
7934 }
7935 
7936 ///
7937 @safe pure nothrow @nogc unittest
7938 {
7939     assert(powmod(1U, 10U, 3U) == 1);
7940     assert(powmod(3U, 2U, 6U) == 3);
7941     assert(powmod(5U, 5U, 15U) == 5);
7942     assert(powmod(2U, 3U, 5U) == 3);
7943     assert(powmod(2U, 4U, 5U) == 1);
7944     assert(powmod(2U, 5U, 5U) == 2);
7945 }
7946 
7947 @safe pure nothrow @nogc unittest
7948 {
7949     ulong a = 18446744073709551615u, b = 20u, c = 18446744073709551610u;
7950     assert(powmod(a, b, c) == 95367431640625u);
7951     a = 100; b = 7919; c = 18446744073709551557u;
7952     assert(powmod(a, b, c) == 18223853583554725198u);
7953     a = 117; b = 7919; c = 18446744073709551557u;
7954     assert(powmod(a, b, c) == 11493139548346411394u);
7955     a = 134; b = 7919; c = 18446744073709551557u;
7956     assert(powmod(a, b, c) == 10979163786734356774u);
7957     a = 151; b = 7919; c = 18446744073709551557u;
7958     assert(powmod(a, b, c) == 7023018419737782840u);
7959     a = 168; b = 7919; c = 18446744073709551557u;
7960     assert(powmod(a, b, c) == 58082701842386811u);
7961     a = 185; b = 7919; c = 18446744073709551557u;
7962     assert(powmod(a, b, c) == 17423478386299876798u);
7963     a = 202; b = 7919; c = 18446744073709551557u;
7964     assert(powmod(a, b, c) == 5522733478579799075u);
7965     a = 219; b = 7919; c = 18446744073709551557u;
7966     assert(powmod(a, b, c) == 15230218982491623487u);
7967     a = 236; b = 7919; c = 18446744073709551557u;
7968     assert(powmod(a, b, c) == 5198328724976436000u);
7969 
7970     a = 0; b = 7919; c = 18446744073709551557u;
7971     assert(powmod(a, b, c) == 0);
7972     a = 123; b = 0; c = 18446744073709551557u;
7973     assert(powmod(a, b, c) == 1);
7974 
7975     immutable ulong a1 = 253, b1 = 7919, c1 = 18446744073709551557u;
7976     assert(powmod(a1, b1, c1) == 3883707345459248860u);
7977 
7978     uint x = 100 ,y = 7919, z = 1844674407u;
7979     assert(powmod(x, y, z) == 1613100340u);
7980     x = 134; y = 7919; z = 1844674407u;
7981     assert(powmod(x, y, z) == 734956622u);
7982     x = 151; y = 7919; z = 1844674407u;
7983     assert(powmod(x, y, z) == 1738696945u);
7984     x = 168; y = 7919; z = 1844674407u;
7985     assert(powmod(x, y, z) == 1247580927u);
7986     x = 185; y = 7919; z = 1844674407u;
7987     assert(powmod(x, y, z) == 1293855176u);
7988     x = 202; y = 7919; z = 1844674407u;
7989     assert(powmod(x, y, z) == 1566963682u);
7990     x = 219; y = 7919; z = 1844674407u;
7991     assert(powmod(x, y, z) == 181227807u);
7992     x = 236; y = 7919; z = 1844674407u;
7993     assert(powmod(x, y, z) == 217988321u);
7994     x = 253; y = 7919; z = 1844674407u;
7995     assert(powmod(x, y, z) == 1588843243u);
7996 
7997     x = 0; y = 7919; z = 184467u;
7998     assert(powmod(x, y, z) == 0);
7999     x = 123; y = 0; z = 1844674u;
8000     assert(powmod(x, y, z) == 1);
8001 
8002     immutable ubyte x1 = 117;
8003     immutable uint y1 = 7919;
8004     immutable uint z1 = 1844674407u;
8005     auto res = powmod(x1, y1, z1);
8006     assert(is(typeof(res) == uint));
8007     assert(res == 9479781u);
8008 
8009     immutable ushort x2 = 123;
8010     immutable uint y2 = 203;
8011     immutable ubyte z2 = 113;
8012     auto res2 = powmod(x2, y2, z2);
8013     assert(is(typeof(res2) == ushort));
8014     assert(res2 == 42u);
8015 }
8016 
8017 /**************************************
8018  * To what precision is x equal to y?
8019  *
8020  * Returns: the number of mantissa bits which are equal in x and y.
8021  * eg, 0x1.F8p+60 and 0x1.F1p+60 are equal to 5 bits of precision.
8022  *
8023  *      $(TABLE_SV
8024  *      $(TR $(TH x)      $(TH y)          $(TH feqrel(x, y)))
8025  *      $(TR $(TD x)      $(TD x)          $(TD real.mant_dig))
8026  *      $(TR $(TD x)      $(TD $(GT)= 2*x) $(TD 0))
8027  *      $(TR $(TD x)      $(TD $(LT)= x/2) $(TD 0))
8028  *      $(TR $(TD $(NAN)) $(TD any)        $(TD 0))
8029  *      $(TR $(TD any)    $(TD $(NAN))     $(TD 0))
8030  *      )
8031  */
8032 int feqrel(X)(const X x, const X y) @trusted pure nothrow @nogc
8033 if (isFloatingPoint!(X))
8034 {
8035     /* Public Domain. Author: Don Clugston, 18 Aug 2005.
8036      */
8037     alias F = floatTraits!(X);
8038     static if (F.realFormat == RealFormat.ieeeSingle
8039             || F.realFormat == RealFormat.ieeeDouble
8040             || F.realFormat == RealFormat.ieeeExtended
8041             || F.realFormat == RealFormat.ieeeQuadruple)
8042     {
8043         if (x == y)
8044             return X.mant_dig; // ensure diff != 0, cope with INF.
8045 
8046         Unqual!X diff = fabs(x - y);
8047 
8048         ushort *pa = cast(ushort *)(&x);
8049         ushort *pb = cast(ushort *)(&y);
8050         ushort *pd = cast(ushort *)(&diff);
8051 
8052 
8053         // The difference in abs(exponent) between x or y and abs(x-y)
8054         // is equal to the number of significand bits of x which are
8055         // equal to y. If negative, x and y have different exponents.
8056         // If positive, x and y are equal to 'bitsdiff' bits.
8057         // AND with 0x7FFF to form the absolute value.
8058         // To avoid out-by-1 errors, we subtract 1 so it rounds down
8059         // if the exponents were different. This means 'bitsdiff' is
8060         // always 1 lower than we want, except that if bitsdiff == 0,
8061         // they could have 0 or 1 bits in common.
8062 
8063         int bitsdiff = (((  (pa[F.EXPPOS_SHORT] & F.EXPMASK)
8064                           + (pb[F.EXPPOS_SHORT] & F.EXPMASK)
8065                           - (1 << F.EXPSHIFT)) >> 1)
8066                         - (pd[F.EXPPOS_SHORT] & F.EXPMASK)) >> F.EXPSHIFT;
8067         if ( (pd[F.EXPPOS_SHORT] & F.EXPMASK) == 0)
8068         {   // Difference is subnormal
8069             // For subnormals, we need to add the number of zeros that
8070             // lie at the start of diff's significand.
8071             // We do this by multiplying by 2^^real.mant_dig
8072             diff *= F.RECIP_EPSILON;
8073             return bitsdiff + X.mant_dig - ((pd[F.EXPPOS_SHORT] & F.EXPMASK) >> F.EXPSHIFT);
8074         }
8075 
8076         if (bitsdiff > 0)
8077             return bitsdiff + 1; // add the 1 we subtracted before
8078 
8079         // Avoid out-by-1 errors when factor is almost 2.
8080         if (bitsdiff == 0
8081             && ((pa[F.EXPPOS_SHORT] ^ pb[F.EXPPOS_SHORT]) & F.EXPMASK) == 0)
8082         {
8083             return 1;
8084         } else return 0;
8085     }
8086     else
8087     {
8088         static assert(false, "Not implemented for this architecture");
8089     }
8090 }
8091 
8092 ///
8093 @safe pure unittest
8094 {
8095     assert(feqrel(2.0, 2.0) == 53);
8096     assert(feqrel(2.0f, 2.0f) == 24);
8097     assert(feqrel(2.0, double.nan) == 0);
8098 
8099     // Test that numbers are within n digits of each
8100     // other by testing if feqrel > n * log2(10)
8101 
8102     // five digits
8103     assert(feqrel(2.0, 2.00001) > 16);
8104     // ten digits
8105     assert(feqrel(2.0, 2.00000000001) > 33);
8106 }
8107 
8108 @safe pure nothrow @nogc unittest
8109 {
8110     void testFeqrel(F)()
8111     {
8112        // Exact equality
8113        assert(feqrel(F.max, F.max) == F.mant_dig);
8114        assert(feqrel!(F)(0.0, 0.0) == F.mant_dig);
8115        assert(feqrel(F.infinity, F.infinity) == F.mant_dig);
8116 
8117        // a few bits away from exact equality
8118        F w=1;
8119        for (int i = 1; i < F.mant_dig - 1; ++i)
8120        {
8121           assert(feqrel!(F)(1.0 + w * F.epsilon, 1.0) == F.mant_dig-i);
8122           assert(feqrel!(F)(1.0 - w * F.epsilon, 1.0) == F.mant_dig-i);
8123           assert(feqrel!(F)(1.0, 1 + (w-1) * F.epsilon) == F.mant_dig - i + 1);
8124           w*=2;
8125        }
8126 
8127        assert(feqrel!(F)(1.5+F.epsilon, 1.5) == F.mant_dig-1);
8128        assert(feqrel!(F)(1.5-F.epsilon, 1.5) == F.mant_dig-1);
8129        assert(feqrel!(F)(1.5-F.epsilon, 1.5+F.epsilon) == F.mant_dig-2);
8130 
8131 
8132        // Numbers that are close
8133        assert(feqrel!(F)(0x1.Bp+84, 0x1.B8p+84) == 5);
8134        assert(feqrel!(F)(0x1.8p+10, 0x1.Cp+10) == 2);
8135        assert(feqrel!(F)(1.5 * (1 - F.epsilon), 1.0L) == 2);
8136        assert(feqrel!(F)(1.5, 1.0) == 1);
8137        assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);
8138 
8139        // Factors of 2
8140        assert(feqrel(F.max, F.infinity) == 0);
8141        assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);
8142        assert(feqrel!(F)(1.0, 2.0) == 0);
8143        assert(feqrel!(F)(4.0, 1.0) == 0);
8144 
8145        // Extreme inequality
8146        assert(feqrel(F.nan, F.nan) == 0);
8147        assert(feqrel!(F)(0.0L, -F.nan) == 0);
8148        assert(feqrel(F.nan, F.infinity) == 0);
8149        assert(feqrel(F.infinity, -F.infinity) == 0);
8150        assert(feqrel(F.max, -F.max) == 0);
8151 
8152        assert(feqrel(F.min_normal / 8, F.min_normal / 17) == 3);
8153 
8154        const F Const = 2;
8155        immutable F Immutable = 2;
8156        auto Compiles = feqrel(Const, Immutable);
8157     }
8158 
8159     assert(feqrel(7.1824L, 7.1824L) == real.mant_dig);
8160 
8161     testFeqrel!(real)();
8162     testFeqrel!(double)();
8163     testFeqrel!(float)();
8164 }
8165 
8166 
8167 /***********************************
8168  * Evaluate polynomial A(x) = $(SUB a, 0) + $(SUB a, 1)x + $(SUB a, 2)$(POWER x,2) +
8169  *                          $(SUB a,3)$(POWER x,3); ...
8170  *
8171  * Uses Horner's rule A(x) = $(SUB a, 0) + x($(SUB a, 1) + x($(SUB a, 2) +
8172  *                         x($(SUB a, 3) + ...)))
8173  * Params:
8174  *      x =     the value to evaluate.
8175  *      A =     array of coefficients $(SUB a, 0), $(SUB a, 1), etc.
8176  */
8177 Unqual!(CommonType!(T1, T2)) poly(T1, T2)(T1 x, in T2[] A) @trusted pure nothrow @nogc
8178 if (isFloatingPoint!T1 && isFloatingPoint!T2)
8179 in
8180 {
8181     assert(A.length > 0);
8182 }
8183 do
8184 {
8185     static if (is(immutable T2 == immutable real))
8186     {
8187         return polyImpl(x, A);
8188     }
8189     else
8190     {
8191         return polyImplBase(x, A);
8192     }
8193 }
8194 
8195 /// ditto
8196 Unqual!(CommonType!(T1, T2)) poly(T1, T2, int N)(T1 x, ref const T2[N] A) @safe pure nothrow @nogc
8197 if (isFloatingPoint!T1 && isFloatingPoint!T2 && N > 0 && N <= 10)
8198 {
8199     // statically unrolled version for up to 10 coefficients
8200     typeof(return) r = A[N - 1];
8201     static foreach (i; 1 .. N)
8202     {
8203         r *= x;
8204         r += A[N - 1 - i];
8205     }
8206     return r;
8207 }
8208 
8209 ///
8210 @safe nothrow @nogc unittest
8211 {
8212     real x = 3.1L;
8213     static real[] pp = [56.1L, 32.7L, 6];
8214 
8215     assert(poly(x, pp) == (56.1L + (32.7L + 6.0L * x) * x));
8216 }
8217 
8218 @safe nothrow @nogc unittest
8219 {
8220     double x = 3.1;
8221     static double[] pp = [56.1, 32.7, 6];
8222     double y = x;
8223     y *= 6.0;
8224     y += 32.7;
8225     y *= x;
8226     y += 56.1;
8227     assert(poly(x, pp) == y);
8228 }
8229 
8230 @safe unittest
8231 {
8232     static assert(poly(3.0, [1.0, 2.0, 3.0]) == 34);
8233 }
8234 
8235 private Unqual!(CommonType!(T1, T2)) polyImplBase(T1, T2)(T1 x, in T2[] A) @trusted pure nothrow @nogc
8236 if (isFloatingPoint!T1 && isFloatingPoint!T2)
8237 {
8238     ptrdiff_t i = A.length - 1;
8239     typeof(return) r = A[i];
8240     while (--i >= 0)
8241     {
8242         r *= x;
8243         r += A[i];
8244     }
8245     return r;
8246 }
8247 
8248 private real polyImpl(real x, in real[] A) @trusted pure nothrow @nogc
8249 {
8250     version (D_InlineAsm_X86)
8251     {
8252         if (__ctfe)
8253         {
8254             return polyImplBase(x, A);
8255         }
8256         version (Windows)
8257         {
8258         // BUG: This code assumes a frame pointer in EBP.
8259             asm pure nothrow @nogc // assembler by W. Bright
8260             {
8261                 // EDX = (A.length - 1) * real.sizeof
8262                 mov     ECX,A[EBP]              ; // ECX = A.length
8263                 dec     ECX                     ;
8264                 lea     EDX,[ECX][ECX*8]        ;
8265                 add     EDX,ECX                 ;
8266                 add     EDX,A+4[EBP]            ;
8267                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8268                 jecxz   return_ST               ;
8269                 fld     x[EBP]                  ; // ST0 = x
8270                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8271                 align   4                       ;
8272         L2:     fmul    ST,ST(1)                ; // r *= x
8273                 fld     real ptr -10[EDX]       ;
8274                 sub     EDX,10                  ; // deg--
8275                 faddp   ST(1),ST                ;
8276                 dec     ECX                     ;
8277                 jne     L2                      ;
8278                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8279                 fstp    ST(0)                   ; // dump x
8280                 align   4                       ;
8281         return_ST:                              ;
8282             }
8283         }
8284         else version (linux)
8285         {
8286             asm pure nothrow @nogc // assembler by W. Bright
8287             {
8288                 // EDX = (A.length - 1) * real.sizeof
8289                 mov     ECX,A[EBP]              ; // ECX = A.length
8290                 dec     ECX                     ;
8291                 lea     EDX,[ECX*8]             ;
8292                 lea     EDX,[EDX][ECX*4]        ;
8293                 add     EDX,A+4[EBP]            ;
8294                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8295                 jecxz   return_ST               ;
8296                 fld     x[EBP]                  ; // ST0 = x
8297                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8298                 align   4                       ;
8299         L2:     fmul    ST,ST(1)                ; // r *= x
8300                 fld     real ptr -12[EDX]       ;
8301                 sub     EDX,12                  ; // deg--
8302                 faddp   ST(1),ST                ;
8303                 dec     ECX                     ;
8304                 jne     L2                      ;
8305                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8306                 fstp    ST(0)                   ; // dump x
8307                 align   4                       ;
8308         return_ST:                              ;
8309             }
8310         }
8311         else version (OSX)
8312         {
8313             asm pure nothrow @nogc // assembler by W. Bright
8314             {
8315                 // EDX = (A.length - 1) * real.sizeof
8316                 mov     ECX,A[EBP]              ; // ECX = A.length
8317                 dec     ECX                     ;
8318                 lea     EDX,[ECX*8]             ;
8319                 add     EDX,EDX                 ;
8320                 add     EDX,A+4[EBP]            ;
8321                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8322                 jecxz   return_ST               ;
8323                 fld     x[EBP]                  ; // ST0 = x
8324                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8325                 align   4                       ;
8326         L2:     fmul    ST,ST(1)                ; // r *= x
8327                 fld     real ptr -16[EDX]       ;
8328                 sub     EDX,16                  ; // deg--
8329                 faddp   ST(1),ST                ;
8330                 dec     ECX                     ;
8331                 jne     L2                      ;
8332                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8333                 fstp    ST(0)                   ; // dump x
8334                 align   4                       ;
8335         return_ST:                              ;
8336             }
8337         }
8338         else version (FreeBSD)
8339         {
8340             asm pure nothrow @nogc // assembler by W. Bright
8341             {
8342                 // EDX = (A.length - 1) * real.sizeof
8343                 mov     ECX,A[EBP]              ; // ECX = A.length
8344                 dec     ECX                     ;
8345                 lea     EDX,[ECX*8]             ;
8346                 lea     EDX,[EDX][ECX*4]        ;
8347                 add     EDX,A+4[EBP]            ;
8348                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8349                 jecxz   return_ST               ;
8350                 fld     x[EBP]                  ; // ST0 = x
8351                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8352                 align   4                       ;
8353         L2:     fmul    ST,ST(1)                ; // r *= x
8354                 fld     real ptr -12[EDX]       ;
8355                 sub     EDX,12                  ; // deg--
8356                 faddp   ST(1),ST                ;
8357                 dec     ECX                     ;
8358                 jne     L2                      ;
8359                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8360                 fstp    ST(0)                   ; // dump x
8361                 align   4                       ;
8362         return_ST:                              ;
8363             }
8364         }
8365         else version (Solaris)
8366         {
8367             asm pure nothrow @nogc // assembler by W. Bright
8368             {
8369                 // EDX = (A.length - 1) * real.sizeof
8370                 mov     ECX,A[EBP]              ; // ECX = A.length
8371                 dec     ECX                     ;
8372                 lea     EDX,[ECX*8]             ;
8373                 lea     EDX,[EDX][ECX*4]        ;
8374                 add     EDX,A+4[EBP]            ;
8375                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8376                 jecxz   return_ST               ;
8377                 fld     x[EBP]                  ; // ST0 = x
8378                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8379                 align   4                       ;
8380         L2:     fmul    ST,ST(1)                ; // r *= x
8381                 fld     real ptr -12[EDX]       ;
8382                 sub     EDX,12                  ; // deg--
8383                 faddp   ST(1),ST                ;
8384                 dec     ECX                     ;
8385                 jne     L2                      ;
8386                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8387                 fstp    ST(0)                   ; // dump x
8388                 align   4                       ;
8389         return_ST:                              ;
8390             }
8391         }
8392         else version (DragonFlyBSD)
8393         {
8394             asm pure nothrow @nogc // assembler by W. Bright
8395             {
8396                 // EDX = (A.length - 1) * real.sizeof
8397                 mov     ECX,A[EBP]              ; // ECX = A.length
8398                 dec     ECX                     ;
8399                 lea     EDX,[ECX*8]             ;
8400                 lea     EDX,[EDX][ECX*4]        ;
8401                 add     EDX,A+4[EBP]            ;
8402                 fld     real ptr [EDX]          ; // ST0 = coeff[ECX]
8403                 jecxz   return_ST               ;
8404                 fld     x[EBP]                  ; // ST0 = x
8405                 fxch    ST(1)                   ; // ST1 = x, ST0 = r
8406                 align   4                       ;
8407         L2:     fmul    ST,ST(1)                ; // r *= x
8408                 fld     real ptr -12[EDX]       ;
8409                 sub     EDX,12                  ; // deg--
8410                 faddp   ST(1),ST                ;
8411                 dec     ECX                     ;
8412                 jne     L2                      ;
8413                 fxch    ST(1)                   ; // ST1 = r, ST0 = x
8414                 fstp    ST(0)                   ; // dump x
8415                 align   4                       ;
8416         return_ST:                              ;
8417             }
8418         }
8419         else
8420         {
8421             static assert(0);
8422         }
8423     }
8424     else
8425     {
8426         return polyImplBase(x, A);
8427     }
8428 }
8429 
8430 
8431 /**
8432    Computes whether a values is approximately equal to a reference value,
8433    admitting a maximum relative difference, and a maximum absolute difference.
8434 
8435    Params:
8436         value = Value to compare.
8437         reference = Reference value.
8438         maxRelDiff = Maximum allowable difference relative to `reference`.
8439         Setting to 0.0 disables this check. Defaults to `1e-2`.
8440         maxAbsDiff = Maximum absolute difference. This is mainly usefull
8441         for comparing values to zero. Setting to 0.0 disables this check.
8442         Defaults to `1e-5`.
8443 
8444    Returns:
8445        `true` if `value` is approximately equal to `reference` under
8446        either criterium. It is sufficient, when `value ` satisfies
8447        one of the two criteria.
8448 
8449        If one item is a range, and the other is a single value, then
8450        the result is the logical and-ing of calling `approxEqual` on
8451        each element of the ranged item against the single item. If
8452        both items are ranges, then `approxEqual` returns `true` if
8453        and only if the ranges have the same number of elements and if
8454        `approxEqual` evaluates to `true` for each pair of elements.
8455 
8456     See_Also:
8457         Use $(LREF feqrel) to get the number of equal bits in the mantissa.
8458  */
8459 bool approxEqual(T, U, V)(T value, U reference, V maxRelDiff = 1e-2, V maxAbsDiff = 1e-5)
8460 {
8461     import std.range.primitives : empty, front, isInputRange, popFront;
8462     static if (isInputRange!T)
8463     {
8464         static if (isInputRange!U)
8465         {
8466             // Two ranges
8467             for (;; value.popFront(), reference.popFront())
8468             {
8469                 if (value.empty) return reference.empty;
8470                 if (reference.empty) return value.empty;
8471                 if (!approxEqual(value.front, reference.front, maxRelDiff, maxAbsDiff))
8472                     return false;
8473             }
8474         }
8475         else static if (isIntegral!U)
8476         {
8477             // convert reference to real
8478             return approxEqual(value, real(reference), maxRelDiff, maxAbsDiff);
8479         }
8480         else
8481         {
8482             // value is range, reference is number
8483             for (; !value.empty; value.popFront())
8484             {
8485                 if (!approxEqual(value.front, reference, maxRelDiff, maxAbsDiff))
8486                     return false;
8487             }
8488             return true;
8489         }
8490     }
8491     else
8492     {
8493         static if (isInputRange!U)
8494         {
8495             // value is number, reference is range
8496             for (; !reference.empty; reference.popFront())
8497             {
8498                 if (!approxEqual(value, reference.front, maxRelDiff, maxAbsDiff))
8499                     return false;
8500             }
8501             return true;
8502         }
8503         else static if (isIntegral!T || isIntegral!U)
8504         {
8505             // convert both value and reference to real
8506             return approxEqual(real(value), real(reference), maxRelDiff, maxAbsDiff);
8507         }
8508         else
8509         {
8510             // two numbers
8511             //static assert(is(T : real) && is(U : real));
8512             if (reference == 0)
8513             {
8514                 return fabs(value) <= maxAbsDiff;
8515             }
8516             static if (is(typeof(value.infinity)) && is(typeof(reference.infinity)))
8517             {
8518                 if (value == value.infinity && reference == reference.infinity ||
8519                     value == -value.infinity && reference == -reference.infinity) return true;
8520             }
8521             return fabs((value - reference) / reference) <= maxRelDiff
8522                 || maxAbsDiff != 0 && fabs(value - reference) <= maxAbsDiff;
8523         }
8524     }
8525 }
8526 
8527 ///
8528 @safe pure nothrow unittest
8529 {
8530     assert(approxEqual(1.0, 1.0099));
8531     assert(!approxEqual(1.0, 1.011));
8532     assert(approxEqual(0.00001, 0.0));
8533     assert(!approxEqual(0.00002, 0.0));
8534 
8535     assert(approxEqual(3.0, [3, 3.01, 2.99])); // several reference values is strange
8536     assert(approxEqual([3, 3.01, 2.99], 3.0)); // better
8537 
8538     float[] arr1 = [ 1.0, 2.0, 3.0 ];
8539     double[] arr2 = [ 1.001, 1.999, 3 ];
8540     assert(approxEqual(arr1, arr2));
8541 }
8542 
8543 ///
8544 @safe pure nothrow unittest
8545 {
8546     // relative comparison depends on reference, make sure proper
8547     // side is used when comparing range to single value. Based on
8548     // https://issues.dlang.org/show_bug.cgi?id=15763
8549     auto a = [2e-3 - 1e-5];
8550     auto b = 2e-3 + 1e-5;
8551     assert(a[0].approxEqual(b));
8552     assert(!b.approxEqual(a[0]));
8553     assert(a.approxEqual(b));
8554     assert(!b.approxEqual(a));
8555 }
8556 
8557 ///
8558 @safe pure nothrow @nogc unittest
8559 {
8560     assert(!approxEqual(0.0,1e-15,1e-9,0.0));
8561     assert(approxEqual(0.0,1e-15,1e-9,1e-9));
8562     assert(!approxEqual(1.0,3.0,0.0,1.0));
8563 
8564     assert(approxEqual(1.00000000099,1.0,1e-9,0.0));
8565     assert(!approxEqual(1.0000000011,1.0,1e-9,0.0));
8566 }
8567 
8568 ///
8569 @safe pure nothrow @nogc unittest
8570 {
8571     // maybe unintuitive behavior
8572     assert(approxEqual(1000.0,1010.0));
8573     assert(approxEqual(9_090_000_000.0,9_000_000_000.0));
8574     assert(approxEqual(0.0,1e30,1.0));
8575     assert(approxEqual(0.00001,1e-30));
8576     assert(!approxEqual(-1e-30,1e-30,1e-2,0.0));
8577 }
8578 
8579 @safe pure nothrow @nogc unittest
8580 {
8581     int a = 10;
8582     assert(approxEqual(10, a));
8583 
8584     assert(!approxEqual(3, 0));
8585     assert(approxEqual(3, 3));
8586     assert(approxEqual(3.0, 3));
8587     assert(approxEqual(3, 3.0));
8588 
8589     assert(approxEqual(0.0,0.0));
8590     assert(approxEqual(-0.0,0.0));
8591     assert(approxEqual(0.0f,0.0));
8592 }
8593 
8594 @safe pure nothrow @nogc unittest
8595 {
8596     real num = real.infinity;
8597     assert(num == real.infinity);
8598     assert(approxEqual(num, real.infinity));
8599     num = -real.infinity;
8600     assert(num == -real.infinity);
8601     assert(approxEqual(num, -real.infinity));
8602 
8603     assert(!approxEqual(1,real.nan));
8604     assert(!approxEqual(real.nan,real.max));
8605     assert(!approxEqual(real.nan,real.nan));
8606 }
8607 
8608 @safe pure nothrow unittest
8609 {
8610     assert(!approxEqual([1.0,2.0,3.0],[1.0,2.0]));
8611     assert(!approxEqual([1.0,2.0],[1.0,2.0,3.0]));
8612 
8613 //    assert(approxEqual([],[])); //FIXME: does not work yet
8614     assert(approxEqual(cast(real[])[],cast(real[])[]));
8615 }
8616 
8617 
8618 /**
8619    Computes whether two values are approximately equal, admitting a maximum
8620    relative difference, and a maximum absolute difference.
8621 
8622    Params:
8623         lhs = First item to compare.
8624         rhs = Second item to compare.
8625         maxRelDiff = Maximum allowable relative difference.
8626         Setting to 0.0 disables this check. Default depends on the type of
8627         `lhs` and `rhs`: It is approximately half the number of decimal digits of
8628         precision of the smaller type.
8629         maxAbsDiff = Maximum absolute difference. This is mainly usefull
8630         for comparing values to zero. Setting to 0.0 disables this check.
8631         Defaults to `0.0`.
8632 
8633    Returns:
8634        `true` if the two items are approximately equal under either criterium.
8635        It is sufficient, when `value ` satisfies one of the two criteria.
8636 
8637        If one item is a range, and the other is a single value, then
8638        the result is the logical and-ing of calling `isClose` on
8639        each element of the ranged item against the single item. If
8640        both items are ranges, then `isClose` returns `true` if
8641        and only if the ranges have the same number of elements and if
8642        `isClose` evaluates to `true` for each pair of elements.
8643 
8644     See_Also:
8645         Use $(LREF feqrel) to get the number of equal bits in the mantissa.
8646  */
8647 bool isClose(T, U, V = CommonType!(FloatingPointBaseType!T,FloatingPointBaseType!U))
8648     (T lhs, U rhs, V maxRelDiff = CommonDefaultFor!(T,U), V maxAbsDiff = 0.0)
8649 {
8650     import std.range.primitives : empty, front, isInputRange, popFront;
8651     import std.complex : Complex;
8652     static if (isInputRange!T)
8653     {
8654         static if (isInputRange!U)
8655         {
8656             // Two ranges
8657             for (;; lhs.popFront(), rhs.popFront())
8658             {
8659                 if (lhs.empty) return rhs.empty;
8660                 if (rhs.empty) return lhs.empty;
8661                 if (!isClose(lhs.front, rhs.front, maxRelDiff, maxAbsDiff))
8662                     return false;
8663             }
8664         }
8665         else
8666         {
8667             // lhs is range, rhs is number
8668             for (; !lhs.empty; lhs.popFront())
8669             {
8670                 if (!isClose(lhs.front, rhs, maxRelDiff, maxAbsDiff))
8671                     return false;
8672             }
8673             return true;
8674         }
8675     }
8676     else static if (isInputRange!U)
8677     {
8678         // lhs is number, rhs is range
8679         for (; !rhs.empty; rhs.popFront())
8680         {
8681             if (!isClose(lhs, rhs.front, maxRelDiff, maxAbsDiff))
8682                 return false;
8683         }
8684         return true;
8685     }
8686     else static if (is(T TE == Complex!TE))
8687     {
8688         static if (is(U UE == Complex!UE))
8689         {
8690             // Two complex numbers
8691             return isClose(lhs.re, rhs.re, maxRelDiff, maxAbsDiff)
8692                 && isClose(lhs.im, rhs.im, maxRelDiff, maxAbsDiff);
8693         }
8694         else
8695         {
8696             // lhs is complex, rhs is number
8697             return isClose(lhs.re, rhs, maxRelDiff, maxAbsDiff)
8698                 && isClose(lhs.im, 0.0, maxRelDiff, maxAbsDiff);
8699         }
8700     }
8701     else static if (is(U UE == Complex!UE))
8702     {
8703         // lhs is number, rhs is complex
8704         return isClose(lhs, rhs.re, maxRelDiff, maxAbsDiff)
8705             && isClose(0.0, rhs.im, maxRelDiff, maxAbsDiff);
8706     }
8707     else
8708     {
8709         // two numbers
8710         if (lhs == rhs) return true;
8711 
8712         static if (is(typeof(lhs.infinity)) && is(typeof(rhs.infinity)))
8713         {
8714             if (lhs == lhs.infinity || rhs == rhs.infinity ||
8715                 lhs == -lhs.infinity || rhs == -rhs.infinity) return false;
8716         }
8717 
8718         auto diff = abs(lhs - rhs);
8719 
8720         return diff <= maxRelDiff*abs(lhs)
8721             || diff <= maxRelDiff*abs(rhs)
8722             || diff <= maxAbsDiff;
8723     }
8724 }
8725 
8726 ///
8727 @safe pure nothrow @nogc unittest
8728 {
8729     assert(isClose(1.0,0.999_999_999));
8730     assert(isClose(0.001, 0.000_999_999_999));
8731     assert(isClose(1_000_000_000.0,999_999_999.0));
8732 
8733     assert(isClose(17.123_456_789, 17.123_456_78));
8734     assert(!isClose(17.123_456_789, 17.123_45));
8735 
8736     // use explicit 3rd parameter for less (or more) accuracy
8737     assert(isClose(17.123_456_789, 17.123_45, 1e-6));
8738     assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
8739 
8740     // use 4th parameter when comparing close to zero
8741     assert(!isClose(1e-100, 0.0));
8742     assert(isClose(1e-100, 0.0, 0.0, 1e-90));
8743     assert(!isClose(1e-10, -1e-10));
8744     assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
8745     assert(!isClose(1e-300, 1e-298));
8746     assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
8747 
8748     // different default limits for different floating point types
8749     assert(isClose(1.0f, 0.999_99f));
8750     assert(!isClose(1.0, 0.999_99));
8751     static if (real.sizeof > double.sizeof)
8752         assert(!isClose(1.0L, 0.999_999_999L));
8753 }
8754 
8755 ///
8756 @safe pure nothrow unittest
8757 {
8758     assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
8759     assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
8760     assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
8761 
8762     assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
8763     assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
8764 }
8765 
8766 @safe pure nothrow unittest
8767 {
8768     assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 3.0, 3.0]));
8769     assert(!isClose([2.0, 1.999_999, 2.000_000_001], 2.0));
8770     assert(!isClose(2.0, [2.0, 1.999_999_999, 2.000_000_999]));
8771 }
8772 
8773 @safe pure nothrow @nogc unittest
8774 {
8775     immutable a = 1.00001f;
8776     const b = 1.000019;
8777     assert(isClose(a,b));
8778 
8779     assert(isClose(1.00001f,1.000019f));
8780     assert(isClose(1.00001f,1.000019));
8781     assert(isClose(1.00001,1.000019f));
8782     assert(!isClose(1.00001,1.000019));
8783 
8784     real a1 = 1e-300L;
8785     real a2 = a1.nextUp;
8786     assert(isClose(a1,a2));
8787 }
8788 
8789 @safe pure nothrow unittest
8790 {
8791     float[] arr1 = [ 1.0, 2.0, 3.0 ];
8792     double[] arr2 = [ 1.00001, 1.99999, 3 ];
8793     assert(isClose(arr1, arr2));
8794 }
8795 
8796 @safe pure nothrow @nogc unittest
8797 {
8798     assert(!isClose(1000.0,1010.0));
8799     assert(!isClose(9_090_000_000.0,9_000_000_000.0));
8800     assert(isClose(0.0,1e30,1.0));
8801     assert(!isClose(0.00001,1e-30));
8802     assert(!isClose(-1e-30,1e-30,1e-2,0.0));
8803 }
8804 
8805 @safe pure nothrow @nogc unittest
8806 {
8807     assert(!isClose(3, 0));
8808     assert(isClose(3, 3));
8809     assert(isClose(3.0, 3));
8810     assert(isClose(3, 3.0));
8811 
8812     assert(isClose(0.0,0.0));
8813     assert(isClose(-0.0,0.0));
8814     assert(isClose(0.0f,0.0));
8815 }
8816 
8817 @safe pure nothrow @nogc unittest
8818 {
8819     real num = real.infinity;
8820     assert(num == real.infinity);
8821     assert(isClose(num, real.infinity));
8822     num = -real.infinity;
8823     assert(num == -real.infinity);
8824     assert(isClose(num, -real.infinity));
8825 
8826     assert(!isClose(1,real.nan));
8827     assert(!isClose(real.nan,real.max));
8828     assert(!isClose(real.nan,real.nan));
8829 }
8830 
8831 @safe pure nothrow @nogc unittest
8832 {
8833     assert(isClose!(real[],real[],real)([],[]));
8834     assert(isClose(cast(real[])[],cast(real[])[]));
8835 }
8836 
8837 @safe pure nothrow @nogc unittest
8838 {
8839     import std.conv : to;
8840 
8841     float f = 31.79f;
8842     double d = 31.79;
8843     double f2d = f.to!double;
8844 
8845     assert(isClose(f,f2d));
8846     assert(!isClose(d,f2d));
8847 }
8848 
8849 @safe pure nothrow @nogc unittest
8850 {
8851     import std.conv : to;
8852 
8853     double d = 31.79;
8854     float f = d.to!float;
8855     double f2d = f.to!double;
8856 
8857     assert(isClose(f,f2d));
8858     assert(!isClose(d,f2d));
8859     assert(isClose(d,f2d,1e-4));
8860 }
8861 
8862 private template CommonDefaultFor(T,U)
8863 {
8864     import std.algorithm.comparison : min;
8865 
8866     alias baseT = FloatingPointBaseType!T;
8867     alias baseU = FloatingPointBaseType!U;
8868 
8869     enum CommonType!(baseT, baseU) CommonDefaultFor = 10.0L ^^ -((min(baseT.dig, baseU.dig) + 1) / 2 + 1);
8870 }
8871 
8872 private template FloatingPointBaseType(T)
8873 {
8874     import std.range.primitives : ElementType;
8875     static if (isFloatingPoint!T)
8876     {
8877         alias FloatingPointBaseType = Unqual!T;
8878     }
8879     else static if (isFloatingPoint!(ElementType!(Unqual!T)))
8880     {
8881         alias FloatingPointBaseType = Unqual!(ElementType!(Unqual!T));
8882     }
8883     else
8884     {
8885         alias FloatingPointBaseType = real;
8886     }
8887 }
8888 
8889 
8890 @safe pure nothrow @nogc unittest
8891 {
8892     float f = sqrt(2.0f);
8893     assert(fabs(f * f - 2.0f) < .00001);
8894 
8895     double d = sqrt(2.0);
8896     assert(fabs(d * d - 2.0) < .00001);
8897 
8898     real r = sqrt(2.0L);
8899     assert(fabs(r * r - 2.0) < .00001);
8900 }
8901 
8902 @safe pure nothrow @nogc unittest
8903 {
8904     float f = fabs(-2.0f);
8905     assert(f == 2);
8906 
8907     double d = fabs(-2.0);
8908     assert(d == 2);
8909 
8910     real r = fabs(-2.0L);
8911     assert(r == 2);
8912 }
8913 
8914 @safe pure nothrow @nogc unittest
8915 {
8916     float f = sin(-2.0f);
8917     assert(fabs(f - -0.909297f) < .00001);
8918 
8919     double d = sin(-2.0);
8920     assert(fabs(d - -0.909297f) < .00001);
8921 
8922     real r = sin(-2.0L);
8923     assert(fabs(r - -0.909297f) < .00001);
8924 }
8925 
8926 @safe pure nothrow @nogc unittest
8927 {
8928     float f = cos(-2.0f);
8929     assert(fabs(f - -0.416147f) < .00001);
8930 
8931     double d = cos(-2.0);
8932     assert(fabs(d - -0.416147f) < .00001);
8933 
8934     real r = cos(-2.0L);
8935     assert(fabs(r - -0.416147f) < .00001);
8936 }
8937 
8938 @safe pure nothrow @nogc unittest
8939 {
8940     float f = tan(-2.0f);
8941     assert(fabs(f - 2.18504f) < .00001);
8942 
8943     double d = tan(-2.0);
8944     assert(fabs(d - 2.18504f) < .00001);
8945 
8946     real r = tan(-2.0L);
8947     assert(fabs(r - 2.18504f) < .00001);
8948 
8949     // Verify correct behavior for large inputs
8950     assert(!isNaN(tan(0x1p63)));
8951     assert(!isNaN(tan(-0x1p63)));
8952     static if (real.mant_dig >= 64)
8953     {
8954         assert(!isNaN(tan(0x1p300L)));
8955         assert(!isNaN(tan(-0x1p300L)));
8956     }
8957 }
8958 
8959 // https://issues.dlang.org/show_bug.cgi?id=6381
8960 // floor/ceil should be usable in pure function.
8961 @safe pure nothrow unittest
8962 {
8963     auto x = floor(1.2);
8964     auto y = ceil(1.2);
8965 }
8966 
8967 /***********************************
8968  * Defines a total order on all floating-point numbers.
8969  *
8970  * The order is defined as follows:
8971  * $(UL
8972  *      $(LI All numbers in [-$(INFIN), +$(INFIN)] are ordered
8973  *          the same way as by built-in comparison, with the exception of
8974  *          -0.0, which is less than +0.0;)
8975  *      $(LI If the sign bit is set (that is, it's 'negative'), $(NAN) is less
8976  *          than any number; if the sign bit is not set (it is 'positive'),
8977  *          $(NAN) is greater than any number;)
8978  *      $(LI $(NAN)s of the same sign are ordered by the payload ('negative'
8979  *          ones - in reverse order).)
8980  * )
8981  *
8982  * Returns:
8983  *      negative value if `x` precedes `y` in the order specified above;
8984  *      0 if `x` and `y` are identical, and positive value otherwise.
8985  *
8986  * See_Also:
8987  *      $(MYREF isIdentical)
8988  * Standards: Conforms to IEEE 754-2008
8989  */
8990 int cmp(T)(const(T) x, const(T) y) @nogc @trusted pure nothrow
8991 if (isFloatingPoint!T)
8992 {
8993     alias F = floatTraits!T;
8994 
8995     static if (F.realFormat == RealFormat.ieeeSingle
8996                || F.realFormat == RealFormat.ieeeDouble)
8997     {
8998         static if (T.sizeof == 4)
8999             alias UInt = uint;
9000         else
9001             alias UInt = ulong;
9002 
9003         union Repainter
9004         {
9005             T number;
9006             UInt bits;
9007         }
9008 
9009         enum msb = ~(UInt.max >>> 1);
9010 
9011         import std.typecons : Tuple;
9012         Tuple!(Repainter, Repainter) vars = void;
9013         vars[0].number = x;
9014         vars[1].number = y;
9015 
9016         foreach (ref var; vars)
9017             if (var.bits & msb)
9018                 var.bits = ~var.bits;
9019             else
9020                 var.bits |= msb;
9021 
9022         if (vars[0].bits < vars[1].bits)
9023             return -1;
9024         else if (vars[0].bits > vars[1].bits)
9025             return 1;
9026         else
9027             return 0;
9028     }
9029     else static if (F.realFormat == RealFormat.ieeeExtended53
9030                     || F.realFormat == RealFormat.ieeeExtended
9031                     || F.realFormat == RealFormat.ieeeQuadruple)
9032     {
9033         static if (F.realFormat == RealFormat.ieeeQuadruple)
9034             alias RemT = ulong;
9035         else
9036             alias RemT = ushort;
9037 
9038         struct Bits
9039         {
9040             ulong bulk;
9041             RemT rem;
9042         }
9043 
9044         union Repainter
9045         {
9046             T number;
9047             Bits bits;
9048             ubyte[T.sizeof] bytes;
9049         }
9050 
9051         import std.typecons : Tuple;
9052         Tuple!(Repainter, Repainter) vars = void;
9053         vars[0].number = x;
9054         vars[1].number = y;
9055 
9056         foreach (ref var; vars)
9057             if (var.bytes[F.SIGNPOS_BYTE] & 0x80)
9058             {
9059                 var.bits.bulk = ~var.bits.bulk;
9060                 var.bits.rem = cast(typeof(var.bits.rem))(-1 - var.bits.rem); // ~var.bits.rem
9061             }
9062             else
9063             {
9064                 var.bytes[F.SIGNPOS_BYTE] |= 0x80;
9065             }
9066 
9067         version (LittleEndian)
9068         {
9069             if (vars[0].bits.rem < vars[1].bits.rem)
9070                 return -1;
9071             else if (vars[0].bits.rem > vars[1].bits.rem)
9072                 return 1;
9073             else if (vars[0].bits.bulk < vars[1].bits.bulk)
9074                 return -1;
9075             else if (vars[0].bits.bulk > vars[1].bits.bulk)
9076                 return 1;
9077             else
9078                 return 0;
9079         }
9080         else
9081         {
9082             if (vars[0].bits.bulk < vars[1].bits.bulk)
9083                 return -1;
9084             else if (vars[0].bits.bulk > vars[1].bits.bulk)
9085                 return 1;
9086             else if (vars[0].bits.rem < vars[1].bits.rem)
9087                 return -1;
9088             else if (vars[0].bits.rem > vars[1].bits.rem)
9089                 return 1;
9090             else
9091                 return 0;
9092         }
9093     }
9094     else
9095     {
9096         // IBM Extended doubledouble does not follow the general
9097         // sign-exponent-significand layout, so has to be handled generically
9098 
9099         const int xSign = signbit(x),
9100             ySign = signbit(y);
9101 
9102         if (xSign == 1 && ySign == 1)
9103             return cmp(-y, -x);
9104         else if (xSign == 1)
9105             return -1;
9106         else if (ySign == 1)
9107             return 1;
9108         else if (x < y)
9109             return -1;
9110         else if (x == y)
9111             return 0;
9112         else if (x > y)
9113             return 1;
9114         else if (isNaN(x) && !isNaN(y))
9115             return 1;
9116         else if (isNaN(y) && !isNaN(x))
9117             return -1;
9118         else if (getNaNPayload(x) < getNaNPayload(y))
9119             return -1;
9120         else if (getNaNPayload(x) > getNaNPayload(y))
9121             return 1;
9122         else
9123             return 0;
9124     }
9125 }
9126 
9127 /// Most numbers are ordered naturally.
9128 @safe unittest
9129 {
9130     assert(cmp(-double.infinity, -double.max) < 0);
9131     assert(cmp(-double.max, -100.0) < 0);
9132     assert(cmp(-100.0, -0.5) < 0);
9133     assert(cmp(-0.5, 0.0) < 0);
9134     assert(cmp(0.0, 0.5) < 0);
9135     assert(cmp(0.5, 100.0) < 0);
9136     assert(cmp(100.0, double.max) < 0);
9137     assert(cmp(double.max, double.infinity) < 0);
9138 
9139     assert(cmp(1.0, 1.0) == 0);
9140 }
9141 
9142 /// Positive and negative zeroes are distinct.
9143 @safe unittest
9144 {
9145     assert(cmp(-0.0, +0.0) < 0);
9146     assert(cmp(+0.0, -0.0) > 0);
9147 }
9148 
9149 /// Depending on the sign, $(NAN)s go to either end of the spectrum.
9150 @safe unittest
9151 {
9152     assert(cmp(-double.nan, -double.infinity) < 0);
9153     assert(cmp(double.infinity, double.nan) < 0);
9154     assert(cmp(-double.nan, double.nan) < 0);
9155 }
9156 
9157 /// $(NAN)s of the same sign are ordered by the payload.
9158 @safe unittest
9159 {
9160     assert(cmp(NaN(10), NaN(20)) < 0);
9161     assert(cmp(-NaN(20), -NaN(10)) < 0);
9162 }
9163 
9164 @safe unittest
9165 {
9166     import std.meta : AliasSeq;
9167     static foreach (T; AliasSeq!(float, double, real))
9168     {{
9169         T[] values = [-cast(T) NaN(20), -cast(T) NaN(10), -T.nan, -T.infinity,
9170                       -T.max, -T.max / 2, T(-16.0), T(-1.0).nextDown,
9171                       T(-1.0), T(-1.0).nextUp,
9172                       T(-0.5), -T.min_normal, (-T.min_normal).nextUp,
9173                       -2 * T.min_normal * T.epsilon,
9174                       -T.min_normal * T.epsilon,
9175                       T(-0.0), T(0.0),
9176                       T.min_normal * T.epsilon,
9177                       2 * T.min_normal * T.epsilon,
9178                       T.min_normal.nextDown, T.min_normal, T(0.5),
9179                       T(1.0).nextDown, T(1.0),
9180                       T(1.0).nextUp, T(16.0), T.max / 2, T.max,
9181                       T.infinity, T.nan, cast(T) NaN(10), cast(T) NaN(20)];
9182 
9183         foreach (i, x; values)
9184         {
9185             foreach (y; values[i + 1 .. $])
9186             {
9187                 assert(cmp(x, y) < 0);
9188                 assert(cmp(y, x) > 0);
9189             }
9190             assert(cmp(x, x) == 0);
9191         }
9192     }}
9193 }
9194 
9195 private enum PowType
9196 {
9197     floor,
9198     ceil
9199 }
9200 
9201 pragma(inline, true)
9202 private T powIntegralImpl(PowType type, T)(T val)
9203 {
9204     import core.bitop : bsr;
9205 
9206     if (val == 0 || (type == PowType.ceil && (val > T.max / 2 || val == T.min)))
9207         return 0;
9208     else
9209     {
9210         static if (isSigned!T)
9211             return cast(Unqual!T) (val < 0 ? -(T(1) << bsr(0 - val) + type) : T(1) << bsr(val) + type);
9212         else
9213             return cast(Unqual!T) (T(1) << bsr(val) + type);
9214     }
9215 }
9216 
9217 private T powFloatingPointImpl(PowType type, T)(T x)
9218 {
9219     if (!x.isFinite)
9220         return x;
9221 
9222     if (!x)
9223         return x;
9224 
9225     int exp;
9226     auto y = frexp(x, exp);
9227 
9228     static if (type == PowType.ceil)
9229         y = ldexp(cast(T) 0.5, exp + 1);
9230     else
9231         y = ldexp(cast(T) 0.5, exp);
9232 
9233     if (!y.isFinite)
9234         return cast(T) 0.0;
9235 
9236     y = copysign(y, x);
9237 
9238     return y;
9239 }
9240 
9241 /**
9242  * Gives the next power of two after `val`. `T` can be any built-in
9243  * numerical type.
9244  *
9245  * If the operation would lead to an over/underflow, this function will
9246  * return `0`.
9247  *
9248  * Params:
9249  *     val = any number
9250  *
9251  * Returns:
9252  *     the next power of two after `val`
9253  */
9254 T nextPow2(T)(const T val)
9255 if (isIntegral!T)
9256 {
9257     return powIntegralImpl!(PowType.ceil)(val);
9258 }
9259 
9260 /// ditto
9261 T nextPow2(T)(const T val)
9262 if (isFloatingPoint!T)
9263 {
9264     return powFloatingPointImpl!(PowType.ceil)(val);
9265 }
9266 
9267 ///
9268 @safe @nogc pure nothrow unittest
9269 {
9270     assert(nextPow2(2) == 4);
9271     assert(nextPow2(10) == 16);
9272     assert(nextPow2(4000) == 4096);
9273 
9274     assert(nextPow2(-2) == -4);
9275     assert(nextPow2(-10) == -16);
9276 
9277     assert(nextPow2(uint.max) == 0);
9278     assert(nextPow2(uint.min) == 0);
9279     assert(nextPow2(size_t.max) == 0);
9280     assert(nextPow2(size_t.min) == 0);
9281 
9282     assert(nextPow2(int.max) == 0);
9283     assert(nextPow2(int.min) == 0);
9284     assert(nextPow2(long.max) == 0);
9285     assert(nextPow2(long.min) == 0);
9286 }
9287 
9288 ///
9289 @safe @nogc pure nothrow unittest
9290 {
9291     assert(nextPow2(2.1) == 4.0);
9292     assert(nextPow2(-2.0) == -4.0);
9293     assert(nextPow2(0.25) == 0.5);
9294     assert(nextPow2(-4.0) == -8.0);
9295 
9296     assert(nextPow2(double.max) == 0.0);
9297     assert(nextPow2(double.infinity) == double.infinity);
9298 }
9299 
9300 @safe @nogc pure nothrow unittest
9301 {
9302     assert(nextPow2(ubyte(2)) == 4);
9303     assert(nextPow2(ubyte(10)) == 16);
9304 
9305     assert(nextPow2(byte(2)) == 4);
9306     assert(nextPow2(byte(10)) == 16);
9307 
9308     assert(nextPow2(short(2)) == 4);
9309     assert(nextPow2(short(10)) == 16);
9310     assert(nextPow2(short(4000)) == 4096);
9311 
9312     assert(nextPow2(ushort(2)) == 4);
9313     assert(nextPow2(ushort(10)) == 16);
9314     assert(nextPow2(ushort(4000)) == 4096);
9315 }
9316 
9317 @safe @nogc pure nothrow unittest
9318 {
9319     foreach (ulong i; 1 .. 62)
9320     {
9321         assert(nextPow2(1UL << i) == 2UL << i);
9322         assert(nextPow2((1UL << i) - 1) == 1UL << i);
9323         assert(nextPow2((1UL << i) + 1) == 2UL << i);
9324         assert(nextPow2((1UL << i) + (1UL<<(i-1))) == 2UL << i);
9325     }
9326 }
9327 
9328 @safe @nogc pure nothrow unittest
9329 {
9330     import std.meta : AliasSeq;
9331 
9332     static foreach (T; AliasSeq!(float, double, real))
9333     {{
9334         enum T subNormal = T.min_normal / 2;
9335 
9336         static if (subNormal) assert(nextPow2(subNormal) == T.min_normal);
9337 
9338         assert(nextPow2(T(0.0)) == 0.0);
9339 
9340         assert(nextPow2(T(2.0)) == 4.0);
9341         assert(nextPow2(T(2.1)) == 4.0);
9342         assert(nextPow2(T(3.1)) == 4.0);
9343         assert(nextPow2(T(4.0)) == 8.0);
9344         assert(nextPow2(T(0.25)) == 0.5);
9345 
9346         assert(nextPow2(T(-2.0)) == -4.0);
9347         assert(nextPow2(T(-2.1)) == -4.0);
9348         assert(nextPow2(T(-3.1)) == -4.0);
9349         assert(nextPow2(T(-4.0)) == -8.0);
9350         assert(nextPow2(T(-0.25)) == -0.5);
9351 
9352         assert(nextPow2(T.max) == 0);
9353         assert(nextPow2(-T.max) == 0);
9354 
9355         assert(nextPow2(T.infinity) == T.infinity);
9356         assert(nextPow2(T.init).isNaN);
9357     }}
9358 }
9359 
9360 // https://issues.dlang.org/show_bug.cgi?id=15973
9361 @safe @nogc pure nothrow unittest
9362 {
9363     assert(nextPow2(uint.max / 2) == uint.max / 2 + 1);
9364     assert(nextPow2(uint.max / 2 + 2) == 0);
9365     assert(nextPow2(int.max / 2) == int.max / 2 + 1);
9366     assert(nextPow2(int.max / 2 + 2) == 0);
9367     assert(nextPow2(int.min + 1) == int.min);
9368 }
9369 
9370 /**
9371  * Gives the last power of two before `val`. $(T) can be any built-in
9372  * numerical type.
9373  *
9374  * Params:
9375  *     val = any number
9376  *
9377  * Returns:
9378  *     the last power of two before `val`
9379  */
9380 T truncPow2(T)(const T val)
9381 if (isIntegral!T)
9382 {
9383     return powIntegralImpl!(PowType.floor)(val);
9384 }
9385 
9386 /// ditto
9387 T truncPow2(T)(const T val)
9388 if (isFloatingPoint!T)
9389 {
9390     return powFloatingPointImpl!(PowType.floor)(val);
9391 }
9392 
9393 ///
9394 @safe @nogc pure nothrow unittest
9395 {
9396     assert(truncPow2(3) == 2);
9397     assert(truncPow2(4) == 4);
9398     assert(truncPow2(10) == 8);
9399     assert(truncPow2(4000) == 2048);
9400 
9401     assert(truncPow2(-5) == -4);
9402     assert(truncPow2(-20) == -16);
9403 
9404     assert(truncPow2(uint.max) == int.max + 1);
9405     assert(truncPow2(uint.min) == 0);
9406     assert(truncPow2(ulong.max) == long.max + 1);
9407     assert(truncPow2(ulong.min) == 0);
9408 
9409     assert(truncPow2(int.max) == (int.max / 2) + 1);
9410     assert(truncPow2(int.min) == int.min);
9411     assert(truncPow2(long.max) == (long.max / 2) + 1);
9412     assert(truncPow2(long.min) == long.min);
9413 }
9414 
9415 ///
9416 @safe @nogc pure nothrow unittest
9417 {
9418     assert(truncPow2(2.1) == 2.0);
9419     assert(truncPow2(7.0) == 4.0);
9420     assert(truncPow2(-1.9) == -1.0);
9421     assert(truncPow2(0.24) == 0.125);
9422     assert(truncPow2(-7.0) == -4.0);
9423 
9424     assert(truncPow2(double.infinity) == double.infinity);
9425 }
9426 
9427 @safe @nogc pure nothrow unittest
9428 {
9429     assert(truncPow2(ubyte(3)) == 2);
9430     assert(truncPow2(ubyte(4)) == 4);
9431     assert(truncPow2(ubyte(10)) == 8);
9432 
9433     assert(truncPow2(byte(3)) == 2);
9434     assert(truncPow2(byte(4)) == 4);
9435     assert(truncPow2(byte(10)) == 8);
9436 
9437     assert(truncPow2(ushort(3)) == 2);
9438     assert(truncPow2(ushort(4)) == 4);
9439     assert(truncPow2(ushort(10)) == 8);
9440     assert(truncPow2(ushort(4000)) == 2048);
9441 
9442     assert(truncPow2(short(3)) == 2);
9443     assert(truncPow2(short(4)) == 4);
9444     assert(truncPow2(short(10)) == 8);
9445     assert(truncPow2(short(4000)) == 2048);
9446 }
9447 
9448 @safe @nogc pure nothrow unittest
9449 {
9450     foreach (ulong i; 1 .. 62)
9451     {
9452         assert(truncPow2(2UL << i) == 2UL << i);
9453         assert(truncPow2((2UL << i) + 1) == 2UL << i);
9454         assert(truncPow2((2UL << i) - 1) == 1UL << i);
9455         assert(truncPow2((2UL << i) - (2UL<<(i-1))) == 1UL << i);
9456     }
9457 }
9458 
9459 @safe @nogc pure nothrow unittest
9460 {
9461     import std.meta : AliasSeq;
9462 
9463     static foreach (T; AliasSeq!(float, double, real))
9464     {
9465         assert(truncPow2(T(0.0)) == 0.0);
9466 
9467         assert(truncPow2(T(4.0)) == 4.0);
9468         assert(truncPow2(T(2.1)) == 2.0);
9469         assert(truncPow2(T(3.5)) == 2.0);
9470         assert(truncPow2(T(7.0)) == 4.0);
9471         assert(truncPow2(T(0.24)) == 0.125);
9472 
9473         assert(truncPow2(T(-2.0)) == -2.0);
9474         assert(truncPow2(T(-2.1)) == -2.0);
9475         assert(truncPow2(T(-3.1)) == -2.0);
9476         assert(truncPow2(T(-7.0)) == -4.0);
9477         assert(truncPow2(T(-0.24)) == -0.125);
9478 
9479         assert(truncPow2(T.infinity) == T.infinity);
9480         assert(truncPow2(T.init).isNaN);
9481     }
9482 }
9483 
9484 /**
9485 Check whether a number is an integer power of two.
9486 
9487 Note that only positive numbers can be integer powers of two. This
9488 function always return `false` if `x` is negative or zero.
9489 
9490 Params:
9491     x = the number to test
9492 
9493 Returns:
9494     `true` if `x` is an integer power of two.
9495 */
9496 bool isPowerOf2(X)(const X x) pure @safe nothrow @nogc
9497 if (isNumeric!X)
9498 {
9499     static if (isFloatingPoint!X)
9500     {
9501         int exp;
9502         const X sig = frexp(x, exp);
9503 
9504         return (exp != int.min) && (sig is cast(X) 0.5L);
9505     }
9506     else
9507     {
9508         static if (isSigned!X)
9509         {
9510             auto y = cast(typeof(x + 0))x;
9511             return y > 0 && !(y & (y - 1));
9512         }
9513         else
9514         {
9515             auto y = cast(typeof(x + 0u))x;
9516             return (y & -y) > (y - 1);
9517         }
9518     }
9519 }
9520 ///
9521 @safe unittest
9522 {
9523     assert( isPowerOf2(1.0L));
9524     assert( isPowerOf2(2.0L));
9525     assert( isPowerOf2(0.5L));
9526     assert( isPowerOf2(pow(2.0L, 96)));
9527     assert( isPowerOf2(pow(2.0L, -77)));
9528 
9529     assert(!isPowerOf2(-2.0L));
9530     assert(!isPowerOf2(-0.5L));
9531     assert(!isPowerOf2(0.0L));
9532     assert(!isPowerOf2(4.315));
9533     assert(!isPowerOf2(1.0L / 3.0L));
9534 
9535     assert(!isPowerOf2(real.nan));
9536     assert(!isPowerOf2(real.infinity));
9537 }
9538 ///
9539 @safe unittest
9540 {
9541     assert( isPowerOf2(1));
9542     assert( isPowerOf2(2));
9543     assert( isPowerOf2(1uL << 63));
9544 
9545     assert(!isPowerOf2(-4));
9546     assert(!isPowerOf2(0));
9547     assert(!isPowerOf2(1337u));
9548 }
9549 
9550 @safe unittest
9551 {
9552     import std.meta : AliasSeq;
9553 
9554     enum smallP2 = pow(2.0L, -62);
9555     enum bigP2 = pow(2.0L, 50);
9556     enum smallP7 = pow(7.0L, -35);
9557     enum bigP7 = pow(7.0L, 30);
9558 
9559     static foreach (X; AliasSeq!(float, double, real))
9560     {{
9561         immutable min_sub = X.min_normal * X.epsilon;
9562 
9563         foreach (x; [smallP2, min_sub, X.min_normal, .25L, 0.5L, 1.0L,
9564                               2.0L, 8.0L, pow(2.0L, X.max_exp - 1), bigP2])
9565         {
9566             assert( isPowerOf2(cast(X) x));
9567             assert(!isPowerOf2(cast(X)-x));
9568         }
9569 
9570         foreach (x; [0.0L, 3 * min_sub, smallP7, 0.1L, 1337.0L, bigP7, X.max, real.nan, real.infinity])
9571         {
9572             assert(!isPowerOf2(cast(X) x));
9573             assert(!isPowerOf2(cast(X)-x));
9574         }
9575     }}
9576 
9577     static foreach (X; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
9578     {{
9579         foreach (x; [1, 2, 4, 8, (X.max >>> 1) + 1])
9580         {
9581             assert( isPowerOf2(cast(X) x));
9582             static if (isSigned!X)
9583                 assert(!isPowerOf2(cast(X)-x));
9584         }
9585 
9586         foreach (x; [0, 3, 5, 13, 77, X.min, X.max])
9587             assert(!isPowerOf2(cast(X) x));
9588     }}
9589 
9590     // CTFE
9591     static foreach (X; AliasSeq!(float, double, real))
9592     {{
9593         enum min_sub = X.min_normal * X.epsilon;
9594 
9595         static foreach (x; [smallP2, min_sub, X.min_normal, .25L, 0.5L, 1.0L,
9596                               2.0L, 8.0L, pow(2.0L, X.max_exp - 1), bigP2])
9597         {
9598             static assert( isPowerOf2(cast(X) x));
9599             static assert(!isPowerOf2(cast(X)-x));
9600         }
9601 
9602         static foreach (x; [0.0L, 3 * min_sub, smallP7, 0.1L, 1337.0L, bigP7, X.max, real.nan, real.infinity])
9603         {
9604             static assert(!isPowerOf2(cast(X) x));
9605             static assert(!isPowerOf2(cast(X)-x));
9606         }
9607     }}
9608 
9609     static foreach (X; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
9610     {{
9611         static foreach (x; [1, 2, 4, 8, (X.max >>> 1) + 1])
9612         {
9613             static assert( isPowerOf2(cast(X) x));
9614             static if (isSigned!X)
9615                 static assert(!isPowerOf2(cast(X)-x));
9616         }
9617 
9618         static foreach (x; [0, 3, 5, 13, 77, X.min, X.max])
9619             static assert(!isPowerOf2(cast(X) x));
9620     }}
9621 }
9622 
9623 package: // Not public yet
9624 /* Return the value that lies halfway between x and y on the IEEE number line.
9625  *
9626  * Formally, the result is the arithmetic mean of the binary significands of x
9627  * and y, multiplied by the geometric mean of the binary exponents of x and y.
9628  * x and y must have the same sign, and must not be NaN.
9629  * Note: this function is useful for ensuring O(log n) behaviour in algorithms
9630  * involving a 'binary chop'.
9631  *
9632  * Special cases:
9633  * If x and y are within a factor of 2, (ie, feqrel(x, y) > 0), the return value
9634  * is the arithmetic mean (x + y) / 2.
9635  * If x and y are even powers of 2, the return value is the geometric mean,
9636  *   ieeeMean(x, y) = sqrt(x * y).
9637  *
9638  */
9639 T ieeeMean(T)(const T x, const T y)  @trusted pure nothrow @nogc
9640 in
9641 {
9642     // both x and y must have the same sign, and must not be NaN.
9643     assert(signbit(x) == signbit(y));
9644     assert(x == x && y == y);
9645 }
9646 do
9647 {
9648     // Runtime behaviour for contract violation:
9649     // If signs are opposite, or one is a NaN, return 0.
9650     if (!((x >= 0 && y >= 0) || (x <= 0 && y <= 0))) return 0.0;
9651 
9652     // The implementation is simple: cast x and y to integers,
9653     // average them (avoiding overflow), and cast the result back to a floating-point number.
9654 
9655     alias F = floatTraits!(T);
9656     T u;
9657     static if (F.realFormat == RealFormat.ieeeExtended)
9658     {
9659         // There's slight additional complexity because they are actually
9660         // 79-bit reals...
9661         ushort *ue = cast(ushort *)&u;
9662         ulong *ul = cast(ulong *)&u;
9663         ushort *xe = cast(ushort *)&x;
9664         ulong *xl = cast(ulong *)&x;
9665         ushort *ye = cast(ushort *)&y;
9666         ulong *yl = cast(ulong *)&y;
9667 
9668         // Ignore the useless implicit bit. (Bonus: this prevents overflows)
9669         ulong m = ((*xl) & 0x7FFF_FFFF_FFFF_FFFFL) + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL);
9670 
9671         // @@@ BUG? @@@
9672         // Cast shouldn't be here
9673         ushort e = cast(ushort) ((xe[F.EXPPOS_SHORT] & F.EXPMASK)
9674                                  + (ye[F.EXPPOS_SHORT] & F.EXPMASK));
9675         if (m & 0x8000_0000_0000_0000L)
9676         {
9677             ++e;
9678             m &= 0x7FFF_FFFF_FFFF_FFFFL;
9679         }
9680         // Now do a multi-byte right shift
9681         const uint c = e & 1; // carry
9682         e >>= 1;
9683         m >>>= 1;
9684         if (c)
9685             m |= 0x4000_0000_0000_0000L; // shift carry into significand
9686         if (e)
9687             *ul = m | 0x8000_0000_0000_0000L; // set implicit bit...
9688         else
9689             *ul = m; // ... unless exponent is 0 (subnormal or zero).
9690 
9691         ue[4]= e | (xe[F.EXPPOS_SHORT]& 0x8000); // restore sign bit
9692     }
9693     else static if (F.realFormat == RealFormat.ieeeQuadruple)
9694     {
9695         // This would be trivial if 'ucent' were implemented...
9696         ulong *ul = cast(ulong *)&u;
9697         ulong *xl = cast(ulong *)&x;
9698         ulong *yl = cast(ulong *)&y;
9699 
9700         // Multi-byte add, then multi-byte right shift.
9701         import core.checkedint : addu;
9702         bool carry;
9703         ulong ml = addu(xl[MANTISSA_LSB], yl[MANTISSA_LSB], carry);
9704 
9705         ulong mh = carry + (xl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL) +
9706             (yl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL);
9707 
9708         ul[MANTISSA_MSB] = (mh >>> 1) | (xl[MANTISSA_MSB] & 0x8000_0000_0000_0000);
9709         ul[MANTISSA_LSB] = (ml >>> 1) | (mh & 1) << 63;
9710     }
9711     else static if (F.realFormat == RealFormat.ieeeDouble)
9712     {
9713         ulong *ul = cast(ulong *)&u;
9714         ulong *xl = cast(ulong *)&x;
9715         ulong *yl = cast(ulong *)&y;
9716         ulong m = (((*xl) & 0x7FFF_FFFF_FFFF_FFFFL)
9717                    + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL)) >>> 1;
9718         m |= ((*xl) & 0x8000_0000_0000_0000L);
9719         *ul = m;
9720     }
9721     else static if (F.realFormat == RealFormat.ieeeSingle)
9722     {
9723         uint *ul = cast(uint *)&u;
9724         uint *xl = cast(uint *)&x;
9725         uint *yl = cast(uint *)&y;
9726         uint m = (((*xl) & 0x7FFF_FFFF) + ((*yl) & 0x7FFF_FFFF)) >>> 1;
9727         m |= ((*xl) & 0x8000_0000);
9728         *ul = m;
9729     }
9730     else
9731     {
9732         assert(0, "Not implemented");
9733     }
9734     return u;
9735 }
9736 
9737 @safe pure nothrow @nogc unittest
9738 {
9739     assert(ieeeMean(-0.0,-1e-20)<0);
9740     assert(ieeeMean(0.0,1e-20)>0);
9741 
9742     assert(ieeeMean(1.0L,4.0L)==2L);
9743     assert(ieeeMean(2.0*1.013,8.0*1.013)==4*1.013);
9744     assert(ieeeMean(-1.0L,-4.0L)==-2L);
9745     assert(ieeeMean(-1.0,-4.0)==-2);
9746     assert(ieeeMean(-1.0f,-4.0f)==-2f);
9747     assert(ieeeMean(-1.0,-2.0)==-1.5);
9748     assert(ieeeMean(-1*(1+8*real.epsilon),-2*(1+8*real.epsilon))
9749                  ==-1.5*(1+5*real.epsilon));
9750     assert(ieeeMean(0x1p60,0x1p-10)==0x1p25);
9751 
9752     static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
9753     {
9754       assert(ieeeMean(1.0L,real.infinity)==0x1p8192L);
9755       assert(ieeeMean(0.0L,real.infinity)==1.5);
9756     }
9757     assert(ieeeMean(0.5*real.min_normal*(1-4*real.epsilon),0.5*real.min_normal)
9758            == 0.5*real.min_normal*(1-2*real.epsilon));
9759 }
9760 
9761 
9762 // The following IEEE 'real' formats are currently supported.
9763 version (LittleEndian)
9764 {
9765     static assert(real.mant_dig == 53 || real.mant_dig == 64
9766                || real.mant_dig == 113,
9767       "Only 64-bit, 80-bit, and 128-bit reals"~
9768       " are supported for LittleEndian CPUs");
9769 }
9770 else
9771 {
9772     static assert(real.mant_dig == 53 || real.mant_dig == 113,
9773     "Only 64-bit and 128-bit reals are supported for BigEndian CPUs.");
9774 }
9775 
9776 // Underlying format exposed through floatTraits
9777 enum RealFormat
9778 {
9779     ieeeHalf,
9780     ieeeSingle,
9781     ieeeDouble,
9782     ieeeExtended,   // x87 80-bit real
9783     ieeeExtended53, // x87 real rounded to precision of double.
9784     ibmExtended,    // IBM 128-bit extended
9785     ieeeQuadruple,
9786 }
9787 
9788 // Constants used for extracting the components of the representation.
9789 // They supplement the built-in floating point properties.
9790 template floatTraits(T)
9791 {
9792     // EXPMASK is a ushort mask to select the exponent portion (without sign)
9793     // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort
9794     // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).
9795     // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
9796     // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
9797     // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
9798     enum Unqual!T RECIP_EPSILON = (1/T.epsilon);
9799     static if (T.mant_dig == 24)
9800     {
9801         // Single precision float
9802         enum ushort EXPMASK = 0x7F80;
9803         enum ushort EXPSHIFT = 7;
9804         enum ushort EXPBIAS = 0x3F00;
9805         enum uint EXPMASK_INT = 0x7F80_0000;
9806         enum uint MANTISSAMASK_INT = 0x007F_FFFF;
9807         enum realFormat = RealFormat.ieeeSingle;
9808         version (LittleEndian)
9809         {
9810             enum EXPPOS_SHORT = 1;
9811             enum SIGNPOS_BYTE = 3;
9812         }
9813         else
9814         {
9815             enum EXPPOS_SHORT = 0;
9816             enum SIGNPOS_BYTE = 0;
9817         }
9818     }
9819     else static if (T.mant_dig == 53)
9820     {
9821         static if (T.sizeof == 8)
9822         {
9823             // Double precision float, or real == double
9824             enum ushort EXPMASK = 0x7FF0;
9825             enum ushort EXPSHIFT = 4;
9826             enum ushort EXPBIAS = 0x3FE0;
9827             enum uint EXPMASK_INT = 0x7FF0_0000;
9828             enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
9829             enum realFormat = RealFormat.ieeeDouble;
9830             version (LittleEndian)
9831             {
9832                 enum EXPPOS_SHORT = 3;
9833                 enum SIGNPOS_BYTE = 7;
9834             }
9835             else
9836             {
9837                 enum EXPPOS_SHORT = 0;
9838                 enum SIGNPOS_BYTE = 0;
9839             }
9840         }
9841         else static if (T.sizeof == 12)
9842         {
9843             // Intel extended real80 rounded to double
9844             enum ushort EXPMASK = 0x7FFF;
9845             enum ushort EXPSHIFT = 0;
9846             enum ushort EXPBIAS = 0x3FFE;
9847             enum realFormat = RealFormat.ieeeExtended53;
9848             version (LittleEndian)
9849             {
9850                 enum EXPPOS_SHORT = 4;
9851                 enum SIGNPOS_BYTE = 9;
9852             }
9853             else
9854             {
9855                 enum EXPPOS_SHORT = 0;
9856                 enum SIGNPOS_BYTE = 0;
9857             }
9858         }
9859         else
9860             static assert(false, "No traits support for " ~ T.stringof);
9861     }
9862     else static if (T.mant_dig == 64)
9863     {
9864         // Intel extended real80
9865         enum ushort EXPMASK = 0x7FFF;
9866         enum ushort EXPSHIFT = 0;
9867         enum ushort EXPBIAS = 0x3FFE;
9868         enum realFormat = RealFormat.ieeeExtended;
9869         version (LittleEndian)
9870         {
9871             enum EXPPOS_SHORT = 4;
9872             enum SIGNPOS_BYTE = 9;
9873         }
9874         else
9875         {
9876             enum EXPPOS_SHORT = 0;
9877             enum SIGNPOS_BYTE = 0;
9878         }
9879     }
9880     else static if (T.mant_dig == 113)
9881     {
9882         // Quadruple precision float
9883         enum ushort EXPMASK = 0x7FFF;
9884         enum ushort EXPSHIFT = 0;
9885         enum ushort EXPBIAS = 0x3FFE;
9886         enum realFormat = RealFormat.ieeeQuadruple;
9887         version (LittleEndian)
9888         {
9889             enum EXPPOS_SHORT = 7;
9890             enum SIGNPOS_BYTE = 15;
9891         }
9892         else
9893         {
9894             enum EXPPOS_SHORT = 0;
9895             enum SIGNPOS_BYTE = 0;
9896         }
9897     }
9898     else static if (T.mant_dig == 106)
9899     {
9900         // IBM Extended doubledouble
9901         enum ushort EXPMASK = 0x7FF0;
9902         enum ushort EXPSHIFT = 4;
9903         enum realFormat = RealFormat.ibmExtended;
9904 
9905         // For IBM doubledouble the larger magnitude double comes first.
9906         // It's really a double[2] and arrays don't index differently
9907         // between little and big-endian targets.
9908         enum DOUBLEPAIR_MSB = 0;
9909         enum DOUBLEPAIR_LSB = 1;
9910 
9911         // The exponent/sign byte is for most significant part.
9912         version (LittleEndian)
9913         {
9914             enum EXPPOS_SHORT = 3;
9915             enum SIGNPOS_BYTE = 7;
9916         }
9917         else
9918         {
9919             enum EXPPOS_SHORT = 0;
9920             enum SIGNPOS_BYTE = 0;
9921         }
9922     }
9923     else
9924         static assert(false, "No traits support for " ~ T.stringof);
9925 }
9926 
9927 // These apply to all floating-point types
9928 version (LittleEndian)
9929 {
9930     enum MANTISSA_LSB = 0;
9931     enum MANTISSA_MSB = 1;
9932 }
9933 else
9934 {
9935     enum MANTISSA_LSB = 1;
9936     enum MANTISSA_MSB = 0;
9937 }
9938 
9939 // Common code for math implementations.
9940 
9941 // Helper for floor/ceil
9942 T floorImpl(T)(const T x) @trusted pure nothrow @nogc
9943 {
9944     alias F = floatTraits!(T);
9945     // Take care not to trigger library calls from the compiler,
9946     // while ensuring that we don't get defeated by some optimizers.
9947     union floatBits
9948     {
9949         T rv;
9950         ushort[T.sizeof/2] vu;
9951 
9952         // Other kinds of extractors for real formats.
9953         static if (F.realFormat == RealFormat.ieeeSingle)
9954             int vi;
9955     }
9956     floatBits y = void;
9957     y.rv = x;
9958 
9959     // Find the exponent (power of 2)
9960     // Do this by shifting the raw value so that the exponent lies in the low bits,
9961     // then mask out the sign bit, and subtract the bias.
9962     static if (F.realFormat == RealFormat.ieeeSingle)
9963     {
9964         int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
9965     }
9966     else static if (F.realFormat == RealFormat.ieeeDouble)
9967     {
9968         int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
9969 
9970         version (LittleEndian)
9971             int pos = 0;
9972         else
9973             int pos = 3;
9974     }
9975     else static if (F.realFormat == RealFormat.ieeeExtended)
9976     {
9977         int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
9978 
9979         version (LittleEndian)
9980             int pos = 0;
9981         else
9982             int pos = 4;
9983     }
9984     else static if (F.realFormat == RealFormat.ieeeQuadruple)
9985     {
9986         int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
9987 
9988         version (LittleEndian)
9989             int pos = 0;
9990         else
9991             int pos = 7;
9992     }
9993     else
9994         static assert(false, "Not implemented for this architecture");
9995 
9996     if (exp < 0)
9997     {
9998         if (x < 0.0)
9999             return -1.0;
10000         else
10001             return 0.0;
10002     }
10003 
10004     static if (F.realFormat == RealFormat.ieeeSingle)
10005     {
10006         if (exp < (T.mant_dig - 1))
10007         {
10008             // Clear all bits representing the fraction part.
10009             const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
10010 
10011             if ((y.vi & fraction_mask) != 0)
10012             {
10013                 // If 'x' is negative, then first substract 1.0 from the value.
10014                 if (y.vi < 0)
10015                     y.vi += 0x00800000 >> exp;
10016                 y.vi &= ~fraction_mask;
10017             }
10018         }
10019     }
10020     else
10021     {
10022         exp = (T.mant_dig - 1) - exp;
10023 
10024         // Zero 16 bits at a time.
10025         while (exp >= 16)
10026         {
10027             version (LittleEndian)
10028                 y.vu[pos++] = 0;
10029             else
10030                 y.vu[pos--] = 0;
10031             exp -= 16;
10032         }
10033 
10034         // Clear the remaining bits.
10035         if (exp > 0)
10036             y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
10037 
10038         if ((x < 0.0) && (x != y.rv))
10039             y.rv -= 1.0;
10040     }
10041 
10042     return y.rv;
10043 }
Suggestion Box / Bug Report