PageRenderTime 79ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/std/math.d

http://github.com/jcd/phobos
D | 5827 lines | 3914 code | 563 blank | 1350 comment | 779 complexity | 9fbdeb980627c624e3f89cb331d11a13 MD5 | raw file
  1. // Written in the D programming language.
  2. /**
  3. * Elementary mathematical functions
  4. *
  5. * Contains the elementary mathematical functions (powers, roots,
  6. * and trignometric functions), and low-level floating-point operations.
  7. * Mathematical special functions are available in std.mathspecial.
  8. *
  9. * The functionality closely follows the IEEE754-2008 standard for
  10. * floating-point arithmetic, including the use of camelCase names rather
  11. * than C99-style lower case names. All of these functions behave correctly
  12. * when presented with an infinity or NaN.
  13. *
  14. * Unlike C, there is no global 'errno' variable. Consequently, almost all of
  15. * these functions are pure nothrow.
  16. *
  17. * Status:
  18. * The semantics and names of feqrel and approxEqual will be revised.
  19. *
  20. * Macros:
  21. * WIKI = Phobos/StdMath
  22. *
  23. * TABLE_SV = <table border=1 cellpadding=4 cellspacing=0>
  24. * <caption>Special Values</caption>
  25. * $0</table>
  26. * SVH = $(TR $(TH $1) $(TH $2))
  27. * SV = $(TR $(TD $1) $(TD $2))
  28. *
  29. * NAN = $(RED NAN)
  30. * SUP = <span style="vertical-align:super;font-size:smaller">$0</span>
  31. * GAMMA = &#915;
  32. * THETA = &theta;
  33. * INTEGRAL = &#8747;
  34. * INTEGRATE = $(BIG &#8747;<sub>$(SMALL $1)</sub><sup>$2</sup>)
  35. * POWER = $1<sup>$2</sup>
  36. * SUB = $1<sub>$2</sub>
  37. * BIGSUM = $(BIG &Sigma; <sup>$2</sup><sub>$(SMALL $1)</sub>)
  38. * CHOOSE = $(BIG &#40;) <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG &#41;)
  39. * PLUSMN = &plusmn;
  40. * INFIN = &infin;
  41. * PLUSMNINF = &plusmn;&infin;
  42. * PI = &pi;
  43. * LT = &lt;
  44. * GT = &gt;
  45. * SQRT = &radic;
  46. * HALF = &frac12;
  47. *
  48. * Copyright: Copyright Digital Mars 2000 - 2011.
  49. * D implementations of tan, atan, atan2, exp, expm1, exp2, log, log10, log1p,
  50. * log2, floor, ceil and lrint functions are based on the CEPHES math library,
  51. * which is Copyright (C) 2001 Stephen L. Moshier <steve@moshier.net>
  52. * and are incorporated herein by permission of the author. The author
  53. * reserves the right to distribute this material elsewhere under different
  54. * copying permissions. These modifications are distributed here under
  55. * the following terms:
  56. * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
  57. * Authors: $(WEB digitalmars.com, Walter Bright),
  58. * Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw
  59. * Source: $(PHOBOSSRC std/_math.d)
  60. */
  61. module std.math;
  62. import core.stdc.math;
  63. import std.traits;
  64. version(unittest)
  65. {
  66. import std.typetuple;
  67. }
  68. version(LDC)
  69. {
  70. import ldc.intrinsics;
  71. }
  72. version(DigitalMars)
  73. {
  74. version = INLINE_YL2X; // x87 has opcodes for these
  75. }
  76. version (X86)
  77. {
  78. version = X86_Any;
  79. }
  80. version (X86_64)
  81. {
  82. version = X86_Any;
  83. }
  84. version(D_InlineAsm_X86)
  85. {
  86. version = InlineAsm_X86_Any;
  87. }
  88. else version(D_InlineAsm_X86_64)
  89. {
  90. version = InlineAsm_X86_Any;
  91. }
  92. version(unittest)
  93. {
  94. import core.stdc.stdio;
  95. static if(real.sizeof > double.sizeof)
  96. enum uint useDigits = 16;
  97. else
  98. enum uint useDigits = 15;
  99. /******************************************
  100. * Compare floating point numbers to n decimal digits of precision.
  101. * Returns:
  102. * 1 match
  103. * 0 nomatch
  104. */
  105. private bool equalsDigit(real x, real y, uint ndigits)
  106. {
  107. if (signbit(x) != signbit(y))
  108. return 0;
  109. if (isinf(x) && isinf(y))
  110. return 1;
  111. if (isinf(x) || isinf(y))
  112. return 0;
  113. if (isnan(x) && isnan(y))
  114. return 1;
  115. if (isnan(x) || isnan(y))
  116. return 0;
  117. char[30] bufx;
  118. char[30] bufy;
  119. assert(ndigits < bufx.length);
  120. int ix;
  121. int iy;
  122. ix = sprintf(bufx.ptr, "%.*Lg", ndigits, x);
  123. assert(ix < bufx.length && ix > 0);
  124. iy = sprintf(bufy.ptr, "%.*Lg", ndigits, y);
  125. assert(ix < bufy.length && ix > 0);
  126. return bufx[0 .. ix] == bufy[0 .. iy];
  127. }
  128. }
  129. private:
  130. /*
  131. * The following IEEE 'real' formats are currently supported:
  132. * 64 bit Big-endian 'double' (eg PowerPC)
  133. * 128 bit Big-endian 'quadruple' (eg SPARC)
  134. * 64 bit Little-endian 'double' (eg x86-SSE2)
  135. * 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium).
  136. * 128 bit Little-endian 'quadruple' (not implemented on any known processor!)
  137. *
  138. * Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
  139. */
  140. version(LittleEndian)
  141. {
  142. static assert(real.mant_dig == 53 || real.mant_dig==64
  143. || real.mant_dig == 113,
  144. "Only 64-bit, 80-bit, and 128-bit reals"
  145. " are supported for LittleEndian CPUs");
  146. }
  147. else
  148. {
  149. static assert(real.mant_dig == 53 || real.mant_dig==106
  150. || real.mant_dig == 113,
  151. "Only 64-bit and 128-bit reals are supported for BigEndian CPUs."
  152. " double-double reals have partial support");
  153. }
  154. // Constants used for extracting the components of the representation.
  155. // They supplement the built-in floating point properties.
  156. template floatTraits(T)
  157. {
  158. // EXPMASK is a ushort mask to select the exponent portion (without sign)
  159. // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
  160. // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
  161. // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
  162. enum T RECIP_EPSILON = (1/T.epsilon);
  163. static if (T.mant_dig == 24)
  164. { // float
  165. enum ushort EXPMASK = 0x7F80;
  166. enum ushort EXPBIAS = 0x3F00;
  167. enum uint EXPMASK_INT = 0x7F80_0000;
  168. enum uint MANTISSAMASK_INT = 0x007F_FFFF;
  169. version(LittleEndian)
  170. {
  171. enum EXPPOS_SHORT = 1;
  172. }
  173. else
  174. {
  175. enum EXPPOS_SHORT = 0;
  176. }
  177. }
  178. else static if (T.mant_dig == 53) // double, or real==double
  179. {
  180. enum ushort EXPMASK = 0x7FF0;
  181. enum ushort EXPBIAS = 0x3FE0;
  182. enum uint EXPMASK_INT = 0x7FF0_0000;
  183. enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
  184. version(LittleEndian)
  185. {
  186. enum EXPPOS_SHORT = 3;
  187. enum SIGNPOS_BYTE = 7;
  188. }
  189. else
  190. {
  191. enum EXPPOS_SHORT = 0;
  192. enum SIGNPOS_BYTE = 0;
  193. }
  194. }
  195. else static if (T.mant_dig == 64) // real80
  196. {
  197. enum ushort EXPMASK = 0x7FFF;
  198. enum ushort EXPBIAS = 0x3FFE;
  199. version(LittleEndian)
  200. {
  201. enum EXPPOS_SHORT = 4;
  202. enum SIGNPOS_BYTE = 9;
  203. }
  204. else
  205. {
  206. enum EXPPOS_SHORT = 0;
  207. enum SIGNPOS_BYTE = 0;
  208. }
  209. }
  210. else static if (T.mant_dig == 113) // quadruple
  211. {
  212. enum ushort EXPMASK = 0x7FFF;
  213. version(LittleEndian)
  214. {
  215. enum EXPPOS_SHORT = 7;
  216. enum SIGNPOS_BYTE = 15;
  217. }
  218. else
  219. {
  220. enum EXPPOS_SHORT = 0;
  221. enum SIGNPOS_BYTE = 0;
  222. }
  223. }
  224. else static if (T.mant_dig == 106) // doubledouble
  225. {
  226. enum ushort EXPMASK = 0x7FF0;
  227. // the exponent byte is not unique
  228. version(LittleEndian)
  229. {
  230. enum EXPPOS_SHORT = 7; // [3] is also an exp short
  231. enum SIGNPOS_BYTE = 15;
  232. }
  233. else
  234. {
  235. enum EXPPOS_SHORT = 0; // [4] is also an exp short
  236. enum SIGNPOS_BYTE = 0;
  237. }
  238. }
  239. }
  240. // These apply to all floating-point types
  241. version(LittleEndian)
  242. {
  243. enum MANTISSA_LSB = 0;
  244. enum MANTISSA_MSB = 1;
  245. }
  246. else
  247. {
  248. enum MANTISSA_LSB = 1;
  249. enum MANTISSA_MSB = 0;
  250. }
  251. public:
  252. // Values obtained from Wolfram Alpha. 116 bits ought to be enough for anybody.
  253. // Wolfram Alpha LLC. 2011. Wolfram|Alpha. http://www.wolframalpha.com/input/?i=e+in+base+16 (access July 6, 2011).
  254. enum real E = 0x1.5bf0a8b1457695355fb8ac404e7a8p+1L; /** e = 2.718281... */
  255. enum real LOG2T = 0x1.a934f0979a3715fc9257edfe9b5fbp+1L; /** $(SUB log, 2)10 = 3.321928... */
  256. enum real LOG2E = 0x1.71547652b82fe1777d0ffda0d23a8p+0L; /** $(SUB log, 2)e = 1.442695... */
  257. enum real LOG2 = 0x1.34413509f79fef311f12b35816f92p-2L; /** $(SUB log, 10)2 = 0.301029... */
  258. enum real LOG10E = 0x1.bcb7b1526e50e32a6ab7555f5a67cp-2L; /** $(SUB log, 10)e = 0.434294... */
  259. enum real LN2 = 0x1.62e42fefa39ef35793c7673007e5fp-1L; /** ln 2 = 0.693147... */
  260. enum real LN10 = 0x1.26bb1bbb5551582dd4adac5705a61p+1L; /** ln 10 = 2.302585... */
  261. enum real PI = 0x1.921fb54442d18469898cc51701b84p+1L; /** $(_PI) = 3.141592... */
  262. enum real PI_2 = PI/2; /** $(PI) / 2 = 1.570796... */
  263. enum real PI_4 = PI/4; /** $(PI) / 4 = 0.785398... */
  264. enum real M_1_PI = 0x1.45f306dc9c882a53f84eafa3ea69cp-2L; /** 1 / $(PI) = 0.318309... */
  265. enum real M_2_PI = 2*M_1_PI; /** 2 / $(PI) = 0.636619... */
  266. enum real M_2_SQRTPI = 0x1.20dd750429b6d11ae3a914fed7fd8p+0L; /** 2 / $(SQRT)$(PI) = 1.128379... */
  267. enum real SQRT2 = 0x1.6a09e667f3bcc908b2fb1366ea958p+0L; /** $(SQRT)2 = 1.414213... */
  268. enum real SQRT1_2 = SQRT2/2; /** $(SQRT)$(HALF) = 0.707106... */
  269. // Note: Make sure the magic numbers in compiler backend for x87 match these.
  270. /***********************************
  271. * Calculates the absolute value
  272. *
  273. * For complex numbers, abs(z) = sqrt( $(POWER z.re, 2) + $(POWER z.im, 2) )
  274. * = hypot(z.re, z.im).
  275. */
  276. Num abs(Num)(Num x) @safe pure nothrow
  277. if (is(typeof(Num.init >= 0)) && is(typeof(-Num.init)) &&
  278. !(is(Num* : const(ifloat*)) || is(Num* : const(idouble*))
  279. || is(Num* : const(ireal*))))
  280. {
  281. static if (isFloatingPoint!(Num))
  282. return fabs(x);
  283. else
  284. return x>=0 ? x : -x;
  285. }
  286. auto abs(Num)(Num z) @safe pure nothrow
  287. if (is(Num* : const(cfloat*)) || is(Num* : const(cdouble*))
  288. || is(Num* : const(creal*)))
  289. {
  290. return hypot(z.re, z.im);
  291. }
  292. /** ditto */
  293. real abs(Num)(Num y) @safe pure nothrow
  294. if (is(Num* : const(ifloat*)) || is(Num* : const(idouble*))
  295. || is(Num* : const(ireal*)))
  296. {
  297. return fabs(y.im);
  298. }
  299. unittest
  300. {
  301. assert(isIdentical(abs(-0.0L), 0.0L));
  302. assert(isNaN(abs(real.nan)));
  303. assert(abs(-real.infinity) == real.infinity);
  304. assert(abs(-3.2Li) == 3.2L);
  305. assert(abs(71.6Li) == 71.6L);
  306. assert(abs(-56) == 56);
  307. assert(abs(2321312L) == 2321312L);
  308. assert(abs(-1+1i) == sqrt(2.0L));
  309. }
  310. /***********************************
  311. * Complex conjugate
  312. *
  313. * conj(x + iy) = x - iy
  314. *
  315. * Note that z * conj(z) = $(POWER z.re, 2) - $(POWER z.im, 2)
  316. * is always a real number
  317. */
  318. creal conj(creal z) @safe pure nothrow
  319. {
  320. return z.re - z.im*1i;
  321. }
  322. /** ditto */
  323. ireal conj(ireal y) @safe pure nothrow
  324. {
  325. return -y;
  326. }
  327. unittest
  328. {
  329. assert(conj(7 + 3i) == 7-3i);
  330. ireal z = -3.2Li;
  331. assert(conj(z) == -z);
  332. }
  333. /***********************************
  334. * Returns cosine of x. x is in radians.
  335. *
  336. * $(TABLE_SV
  337. * $(TR $(TH x) $(TH cos(x)) $(TH invalid?))
  338. * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes) )
  339. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN)) $(TD yes) )
  340. * )
  341. * Bugs:
  342. * Results are undefined if |x| >= $(POWER 2,64).
  343. */
  344. real cos(real x) @safe pure nothrow; /* intrinsic */
  345. /***********************************
  346. * Returns sine of x. x is in radians.
  347. *
  348. * $(TABLE_SV
  349. * $(TR $(TH x) $(TH sin(x)) $(TH invalid?))
  350. * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes))
  351. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
  352. * $(TR $(TD $(PLUSMNINF)) $(TD $(NAN)) $(TD yes))
  353. * )
  354. * Bugs:
  355. * Results are undefined if |x| >= $(POWER 2,64).
  356. */
  357. real sin(real x) @safe pure nothrow; /* intrinsic */
  358. /***********************************
  359. * sine, complex and imaginary
  360. *
  361. * sin(z) = sin(z.re)*cosh(z.im) + cos(z.re)*sinh(z.im)i
  362. *
  363. * If both sin($(THETA)) and cos($(THETA)) are required,
  364. * it is most efficient to use expi($(THETA)).
  365. */
  366. creal sin(creal z) @safe pure nothrow
  367. {
  368. creal cs = expi(z.re);
  369. creal csh = coshisinh(z.im);
  370. return cs.im * csh.re + cs.re * csh.im * 1i;
  371. }
  372. /** ditto */
  373. ireal sin(ireal y) @safe pure nothrow
  374. {
  375. return cosh(y.im)*1i;
  376. }
  377. unittest
  378. {
  379. assert(sin(0.0+0.0i) == 0.0);
  380. assert(sin(2.0+0.0i) == sin(2.0L) );
  381. }
  382. /***********************************
  383. * cosine, complex and imaginary
  384. *
  385. * cos(z) = cos(z.re)*cosh(z.im) - sin(z.re)*sinh(z.im)i
  386. */
  387. creal cos(creal z) @safe pure nothrow
  388. {
  389. creal cs = expi(z.re);
  390. creal csh = coshisinh(z.im);
  391. return cs.re * csh.re - cs.im * csh.im * 1i;
  392. }
  393. /** ditto */
  394. real cos(ireal y) @safe pure nothrow
  395. {
  396. return cosh(y.im);
  397. }
  398. unittest
  399. {
  400. assert(cos(0.0+0.0i)==1.0);
  401. assert(cos(1.3L+0.0i)==cos(1.3L));
  402. assert(cos(5.2Li)== cosh(5.2L));
  403. }
  404. /****************************************************************************
  405. * Returns tangent of x. x is in radians.
  406. *
  407. * $(TABLE_SV
  408. * $(TR $(TH x) $(TH tan(x)) $(TH invalid?))
  409. * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes))
  410. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
  411. * $(TR $(TD $(PLUSMNINF)) $(TD $(NAN)) $(TD yes))
  412. * )
  413. */
  414. real tan(real x) @trusted pure nothrow
  415. {
  416. version(D_InlineAsm_X86)
  417. {
  418. asm
  419. {
  420. fld x[EBP] ; // load theta
  421. fxam ; // test for oddball values
  422. fstsw AX ;
  423. sahf ;
  424. jc trigerr ; // x is NAN, infinity, or empty
  425. // 387's can handle subnormals
  426. SC18: fptan ;
  427. fstp ST(0) ; // dump X, which is always 1
  428. fstsw AX ;
  429. sahf ;
  430. jnp Lret ; // C2 = 1 (x is out of range)
  431. // Do argument reduction to bring x into range
  432. fldpi ;
  433. fxch ;
  434. SC17: fprem1 ;
  435. fstsw AX ;
  436. sahf ;
  437. jp SC17 ;
  438. fstp ST(1) ; // remove pi from stack
  439. jmp SC18 ;
  440. trigerr:
  441. jnp Lret ; // if theta is NAN, return theta
  442. fstp ST(0) ; // dump theta
  443. }
  444. return real.nan;
  445. Lret: {}
  446. }
  447. else version(D_InlineAsm_X86_64)
  448. {
  449. version (Win64)
  450. {
  451. asm
  452. {
  453. fld real ptr [RCX] ; // load theta
  454. }
  455. }
  456. else
  457. {
  458. asm
  459. {
  460. fld x[RBP] ; // load theta
  461. }
  462. }
  463. asm
  464. {
  465. fxam ; // test for oddball values
  466. fstsw AX ;
  467. test AH,1 ;
  468. jnz trigerr ; // x is NAN, infinity, or empty
  469. // 387's can handle subnormals
  470. SC18: fptan ;
  471. fstp ST(0) ; // dump X, which is always 1
  472. fstsw AX ;
  473. test AH,4 ;
  474. jz Lret ; // C2 = 1 (x is out of range)
  475. // Do argument reduction to bring x into range
  476. fldpi ;
  477. fxch ;
  478. SC17: fprem1 ;
  479. fstsw AX ;
  480. test AH,4 ;
  481. jnz SC17 ;
  482. fstp ST(1) ; // remove pi from stack
  483. jmp SC18 ;
  484. trigerr:
  485. test AH,4 ;
  486. jz Lret ; // if theta is NAN, return theta
  487. fstp ST(0) ; // dump theta
  488. }
  489. return real.nan;
  490. Lret: {}
  491. }
  492. else
  493. {
  494. // Coefficients for tan(x)
  495. static immutable real[3] P = [
  496. -1.7956525197648487798769E7L,
  497. 1.1535166483858741613983E6L,
  498. -1.3093693918138377764608E4L,
  499. ];
  500. static immutable real[5] Q = [
  501. -5.3869575592945462988123E7L,
  502. 2.5008380182335791583922E7L,
  503. -1.3208923444021096744731E6L,
  504. 1.3681296347069295467845E4L,
  505. 1.0000000000000000000000E0L,
  506. ];
  507. // PI/4 split into three parts.
  508. enum real P1 = 7.853981554508209228515625E-1L;
  509. enum real P2 = 7.946627356147928367136046290398E-9L;
  510. enum real P3 = 3.061616997868382943065164830688E-17L;
  511. // Special cases.
  512. if (x == 0.0 || isNaN(x))
  513. return x;
  514. if (isInfinity(x))
  515. return real.nan;
  516. // Make argument positive but save the sign.
  517. bool sign = false;
  518. if (signbit(x))
  519. {
  520. sign = true;
  521. x = -x;
  522. }
  523. // Compute x mod PI/4.
  524. real y = floor(x / PI_4);
  525. // Strip high bits of integer part.
  526. real z = ldexp(y, -4);
  527. // Compute y - 16 * (y / 16).
  528. z = y - ldexp(floor(z), 4);
  529. // Integer and fraction part modulo one octant.
  530. int j = cast(int)(z);
  531. // Map zeros and singularities to origin.
  532. if (j & 1)
  533. {
  534. j += 1;
  535. y += 1.0;
  536. }
  537. z = ((x - y * P1) - y * P2) - y * P3;
  538. real zz = z * z;
  539. if (zz > 1.0e-20L)
  540. y = z + z * (zz * poly(zz, P) / poly(zz, Q));
  541. else
  542. y = z;
  543. if (j & 2)
  544. y = -1.0 / y;
  545. return (sign) ? -y : y;
  546. }
  547. }
  548. unittest
  549. {
  550. static real[2][] vals = // angle,tan
  551. [
  552. [ 0, 0],
  553. [ .5, .5463024898],
  554. [ 1, 1.557407725],
  555. [ 1.5, 14.10141995],
  556. [ 2, -2.185039863],
  557. [ 2.5,-.7470222972],
  558. [ 3, -.1425465431],
  559. [ 3.5, .3745856402],
  560. [ 4, 1.157821282],
  561. [ 4.5, 4.637332055],
  562. [ 5, -3.380515006],
  563. [ 5.5,-.9955840522],
  564. [ 6, -.2910061914],
  565. [ 6.5, .2202772003],
  566. [ 10, .6483608275],
  567. // special angles
  568. [ PI_4, 1],
  569. //[ PI_2, real.infinity], // PI_2 is not _exactly_ pi/2.
  570. [ 3*PI_4, -1],
  571. [ PI, 0],
  572. [ 5*PI_4, 1],
  573. //[ 3*PI_2, -real.infinity],
  574. [ 7*PI_4, -1],
  575. [ 2*PI, 0],
  576. ];
  577. int i;
  578. for (i = 0; i < vals.length; i++)
  579. {
  580. real x = vals[i][0];
  581. real r = vals[i][1];
  582. real t = tan(x);
  583. //printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
  584. if (!isIdentical(r, t)) assert(fabs(r-t) <= .0000001);
  585. x = -x;
  586. r = -r;
  587. t = tan(x);
  588. //printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
  589. if (!isIdentical(r, t) && !(r!=r && t!=t)) assert(fabs(r-t) <= .0000001);
  590. }
  591. // overflow
  592. assert(isNaN(tan(real.infinity)));
  593. assert(isNaN(tan(-real.infinity)));
  594. // NaN propagation
  595. assert(isIdentical( tan(NaN(0x0123L)), NaN(0x0123L) ));
  596. }
  597. unittest
  598. {
  599. assert(equalsDigit(tan(PI / 3), std.math.sqrt(3.0), useDigits));
  600. }
  601. /***************
  602. * Calculates the arc cosine of x,
  603. * returning a value ranging from 0 to $(PI).
  604. *
  605. * $(TABLE_SV
  606. * $(TR $(TH x) $(TH acos(x)) $(TH invalid?))
  607. * $(TR $(TD $(GT)1.0) $(TD $(NAN)) $(TD yes))
  608. * $(TR $(TD $(LT)-1.0) $(TD $(NAN)) $(TD yes))
  609. * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes))
  610. * )
  611. */
  612. real acos(real x) @safe pure nothrow
  613. {
  614. return atan2(sqrt(1-x*x), x);
  615. }
  616. /// ditto
  617. double acos(double x) @safe pure nothrow { return acos(cast(real)x); }
  618. /// ditto
  619. float acos(float x) @safe pure nothrow { return acos(cast(real)x); }
  620. unittest
  621. {
  622. assert(equalsDigit(acos(0.5), std.math.PI / 3, useDigits));
  623. }
  624. /***************
  625. * Calculates the arc sine of x,
  626. * returning a value ranging from -$(PI)/2 to $(PI)/2.
  627. *
  628. * $(TABLE_SV
  629. * $(TR $(TH x) $(TH asin(x)) $(TH invalid?))
  630. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
  631. * $(TR $(TD $(GT)1.0) $(TD $(NAN)) $(TD yes))
  632. * $(TR $(TD $(LT)-1.0) $(TD $(NAN)) $(TD yes))
  633. * )
  634. */
  635. real asin(real x) @safe pure nothrow
  636. {
  637. return atan2(x, sqrt(1-x*x));
  638. }
  639. /// ditto
  640. double asin(double x) @safe pure nothrow { return asin(cast(real)x); }
  641. /// ditto
  642. float asin(float x) @safe pure nothrow { return asin(cast(real)x); }
  643. unittest
  644. {
  645. assert(equalsDigit(asin(0.5), PI / 6, useDigits));
  646. }
  647. /***************
  648. * Calculates the arc tangent of x,
  649. * returning a value ranging from -$(PI)/2 to $(PI)/2.
  650. *
  651. * $(TABLE_SV
  652. * $(TR $(TH x) $(TH atan(x)) $(TH invalid?))
  653. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
  654. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN)) $(TD yes))
  655. * )
  656. */
  657. real atan(real x) @safe pure nothrow
  658. {
  659. version(InlineAsm_X86_Any)
  660. {
  661. return atan2(x, 1.0L);
  662. }
  663. else
  664. {
  665. // Coefficients for atan(x)
  666. static immutable real[5] P = [
  667. -5.0894116899623603312185E1L,
  668. -9.9988763777265819915721E1L,
  669. -6.3976888655834347413154E1L,
  670. -1.4683508633175792446076E1L,
  671. -8.6863818178092187535440E-1L,
  672. ];
  673. static immutable real[6] Q = [
  674. 1.5268235069887081006606E2L,
  675. 3.9157570175111990631099E2L,
  676. 3.6144079386152023162701E2L,
  677. 1.4399096122250781605352E2L,
  678. 2.2981886733594175366172E1L,
  679. 1.0000000000000000000000E0L,
  680. ];
  681. // tan(PI/8)
  682. enum real TAN_PI_8 = 4.1421356237309504880169e-1L;
  683. // tan(3 * PI/8)
  684. enum real TAN3_PI_8 = 2.41421356237309504880169L;
  685. // Special cases.
  686. if (x == 0.0)
  687. return x;
  688. if (isInfinity(x))
  689. return copysign(PI_2, x);
  690. // Make argument positive but save the sign.
  691. bool sign = false;
  692. if (signbit(x))
  693. {
  694. sign = true;
  695. x = -x;
  696. }
  697. // Range reduction.
  698. real y;
  699. if (x > TAN3_PI_8)
  700. {
  701. y = PI_2;
  702. x = -(1.0 / x);
  703. }
  704. else if (x > TAN_PI_8)
  705. {
  706. y = PI_4;
  707. x = (x - 1.0)/(x + 1.0);
  708. }
  709. else
  710. y = 0.0;
  711. // Rational form in x^^2.
  712. real z = x * x;
  713. y = y + (poly(z, P) / poly(z, Q)) * z * x + x;
  714. return (sign) ? -y : y;
  715. }
  716. }
  717. /// ditto
  718. double atan(double x) @safe pure nothrow { return atan(cast(real)x); }
  719. /// ditto
  720. float atan(float x) @safe pure nothrow { return atan(cast(real)x); }
  721. unittest
  722. {
  723. assert(equalsDigit(atan(std.math.sqrt(3.0)), PI / 3, useDigits));
  724. }
  725. /***************
  726. * Calculates the arc tangent of y / x,
  727. * returning a value ranging from -$(PI) to $(PI).
  728. *
  729. * $(TABLE_SV
  730. * $(TR $(TH y) $(TH x) $(TH atan(y, x)))
  731. * $(TR $(TD $(NAN)) $(TD anything) $(TD $(NAN)) )
  732. * $(TR $(TD anything) $(TD $(NAN)) $(TD $(NAN)) )
  733. * $(TR $(TD $(PLUSMN)0.0) $(TD $(GT)0.0) $(TD $(PLUSMN)0.0) )
  734. * $(TR $(TD $(PLUSMN)0.0) $(TD +0.0) $(TD $(PLUSMN)0.0) )
  735. * $(TR $(TD $(PLUSMN)0.0) $(TD $(LT)0.0) $(TD $(PLUSMN)$(PI)))
  736. * $(TR $(TD $(PLUSMN)0.0) $(TD -0.0) $(TD $(PLUSMN)$(PI)))
  737. * $(TR $(TD $(GT)0.0) $(TD $(PLUSMN)0.0) $(TD $(PI)/2) )
  738. * $(TR $(TD $(LT)0.0) $(TD $(PLUSMN)0.0) $(TD -$(PI)/2) )
  739. * $(TR $(TD $(GT)0.0) $(TD $(INFIN)) $(TD $(PLUSMN)0.0) )
  740. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD anything) $(TD $(PLUSMN)$(PI)/2))
  741. * $(TR $(TD $(GT)0.0) $(TD -$(INFIN)) $(TD $(PLUSMN)$(PI)) )
  742. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(INFIN)) $(TD $(PLUSMN)$(PI)/4))
  743. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD -$(INFIN)) $(TD $(PLUSMN)3$(PI)/4))
  744. * )
  745. */
  746. real atan2(real y, real x) @trusted pure nothrow
  747. {
  748. version(InlineAsm_X86_Any)
  749. {
  750. version (Win64)
  751. {
  752. asm {
  753. naked;
  754. fld real ptr [RDX]; // y
  755. fld real ptr [RCX]; // x
  756. fpatan;
  757. ret;
  758. }
  759. }
  760. else
  761. {
  762. asm {
  763. fld y;
  764. fld x;
  765. fpatan;
  766. }
  767. }
  768. }
  769. else
  770. {
  771. // Special cases.
  772. if (isNaN(x) || isNaN(y))
  773. return real.nan;
  774. if (y == 0.0)
  775. {
  776. if (x >= 0 && !signbit(x))
  777. return copysign(0, y);
  778. else
  779. return copysign(PI, y);
  780. }
  781. if (x == 0.0)
  782. return copysign(PI_2, y);
  783. if (isInfinity(x))
  784. {
  785. if (signbit(x))
  786. {
  787. if (isInfinity(y))
  788. return copysign(3*PI_4, y);
  789. else
  790. return copysign(PI, y);
  791. }
  792. else
  793. {
  794. if (isInfinity(y))
  795. return copysign(PI_4, y);
  796. else
  797. return copysign(0.0, y);
  798. }
  799. }
  800. if (isInfinity(y))
  801. return copysign(PI_2, y);
  802. // Call atan and determine the quadrant.
  803. real z = atan(y / x);
  804. if (signbit(x))
  805. {
  806. if (signbit(y))
  807. z = z - PI;
  808. else
  809. z = z + PI;
  810. }
  811. if (z == 0.0)
  812. return copysign(z, y);
  813. return z;
  814. }
  815. }
  816. /// ditto
  817. double atan2(double y, double x) @safe pure nothrow
  818. {
  819. return atan2(cast(real)y, cast(real)x);
  820. }
  821. /// ditto
  822. float atan2(float y, float x) @safe pure nothrow
  823. {
  824. return atan2(cast(real)y, cast(real)x);
  825. }
  826. unittest
  827. {
  828. assert(equalsDigit(atan2(1.0L, std.math.sqrt(3.0L)), PI / 6, useDigits));
  829. }
  830. /***********************************
  831. * Calculates the hyperbolic cosine of x.
  832. *
  833. * $(TABLE_SV
  834. * $(TR $(TH x) $(TH cosh(x)) $(TH invalid?))
  835. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)0.0) $(TD no) )
  836. * )
  837. */
  838. real cosh(real x) @safe pure nothrow
  839. {
  840. // cosh = (exp(x)+exp(-x))/2.
  841. // The naive implementation works correctly.
  842. real y = exp(x);
  843. return (y + 1.0/y) * 0.5;
  844. }
  845. /// ditto
  846. double cosh(double x) @safe pure nothrow { return cosh(cast(real)x); }
  847. /// ditto
  848. float cosh(float x) @safe pure nothrow { return cosh(cast(real)x); }
  849. unittest
  850. {
  851. assert(equalsDigit(cosh(1.0), (E + 1.0 / E) / 2, useDigits));
  852. }
  853. /***********************************
  854. * Calculates the hyperbolic sine of x.
  855. *
  856. * $(TABLE_SV
  857. * $(TR $(TH x) $(TH sinh(x)) $(TH invalid?))
  858. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no))
  859. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no))
  860. * )
  861. */
  862. real sinh(real x) @safe pure nothrow
  863. {
  864. // sinh(x) = (exp(x)-exp(-x))/2;
  865. // Very large arguments could cause an overflow, but
  866. // the maximum value of x for which exp(x) + exp(-x)) != exp(x)
  867. // is x = 0.5 * (real.mant_dig) * LN2. // = 22.1807 for real80.
  868. if (fabs(x) > real.mant_dig * LN2)
  869. {
  870. return copysign(0.5 * exp(fabs(x)), x);
  871. }
  872. real y = expm1(x);
  873. return 0.5 * y / (y+1) * (y+2);
  874. }
  875. /// ditto
  876. double sinh(double x) @safe pure nothrow { return sinh(cast(real)x); }
  877. /// ditto
  878. float sinh(float x) @safe pure nothrow { return sinh(cast(real)x); }
  879. unittest
  880. {
  881. assert(equalsDigit(sinh(1.0), (E - 1.0 / E) / 2, useDigits));
  882. }
  883. /***********************************
  884. * Calculates the hyperbolic tangent of x.
  885. *
  886. * $(TABLE_SV
  887. * $(TR $(TH x) $(TH tanh(x)) $(TH invalid?))
  888. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no) )
  889. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)1.0) $(TD no))
  890. * )
  891. */
  892. real tanh(real x) @safe pure nothrow
  893. {
  894. // tanh(x) = (exp(x) - exp(-x))/(exp(x)+exp(-x))
  895. if (fabs(x) > real.mant_dig * LN2)
  896. {
  897. return copysign(1, x);
  898. }
  899. real y = expm1(2*x);
  900. return y / (y + 2);
  901. }
  902. /// ditto
  903. double tanh(double x) @safe pure nothrow { return tanh(cast(real)x); }
  904. /// ditto
  905. float tanh(float x) @safe pure nothrow { return tanh(cast(real)x); }
  906. unittest
  907. {
  908. assert(equalsDigit(tanh(1.0), sinh(1.0) / cosh(1.0), 15));
  909. }
  910. package:
  911. /* Returns cosh(x) + I * sinh(x)
  912. * Only one call to exp() is performed.
  913. */
  914. creal coshisinh(real x) @safe pure nothrow
  915. {
  916. // See comments for cosh, sinh.
  917. if (fabs(x) > real.mant_dig * LN2)
  918. {
  919. real y = exp(fabs(x));
  920. return y * 0.5 + 0.5i * copysign(y, x);
  921. }
  922. else
  923. {
  924. real y = expm1(x);
  925. return (y + 1.0 + 1.0/(y + 1.0)) * 0.5 + 0.5i * y / (y+1) * (y+2);
  926. }
  927. }
  928. unittest
  929. {
  930. creal c = coshisinh(3.0L);
  931. assert(c.re == cosh(3.0L));
  932. assert(c.im == sinh(3.0L));
  933. }
  934. public:
  935. /***********************************
  936. * Calculates the inverse hyperbolic cosine of x.
  937. *
  938. * Mathematically, acosh(x) = log(x + sqrt( x*x - 1))
  939. *
  940. * $(TABLE_DOMRG
  941. * $(DOMAIN 1..$(INFIN))
  942. * $(RANGE 1..log(real.max), $(INFIN)) )
  943. * $(TABLE_SV
  944. * $(SVH x, acosh(x) )
  945. * $(SV $(NAN), $(NAN) )
  946. * $(SV $(LT)1, $(NAN) )
  947. * $(SV 1, 0 )
  948. * $(SV +$(INFIN),+$(INFIN))
  949. * )
  950. */
  951. real acosh(real x) @safe pure nothrow
  952. {
  953. if (x > 1/real.epsilon)
  954. return LN2 + log(x);
  955. else
  956. return log(x + sqrt(x*x - 1));
  957. }
  958. /// ditto
  959. double acosh(double x) @safe pure nothrow { return acosh(cast(real)x); }
  960. /// ditto
  961. float acosh(float x) @safe pure nothrow { return acosh(cast(real)x); }
  962. unittest
  963. {
  964. assert(isNaN(acosh(0.9)));
  965. assert(isNaN(acosh(real.nan)));
  966. assert(acosh(1.0)==0.0);
  967. assert(acosh(real.infinity) == real.infinity);
  968. assert(isNaN(acosh(0.5)));
  969. assert(equalsDigit(acosh(cosh(3.0)), 3, useDigits));
  970. }
  971. /***********************************
  972. * Calculates the inverse hyperbolic sine of x.
  973. *
  974. * Mathematically,
  975. * ---------------
  976. * asinh(x) = log( x + sqrt( x*x + 1 )) // if x >= +0
  977. * asinh(x) = -log(-x + sqrt( x*x + 1 )) // if x <= -0
  978. * -------------
  979. *
  980. * $(TABLE_SV
  981. * $(SVH x, asinh(x) )
  982. * $(SV $(NAN), $(NAN) )
  983. * $(SV $(PLUSMN)0, $(PLUSMN)0 )
  984. * $(SV $(PLUSMN)$(INFIN),$(PLUSMN)$(INFIN))
  985. * )
  986. */
  987. real asinh(real x) @safe pure nothrow
  988. {
  989. return (fabs(x) > 1 / real.epsilon)
  990. // beyond this point, x*x + 1 == x*x
  991. ? copysign(LN2 + log(fabs(x)), x)
  992. // sqrt(x*x + 1) == 1 + x * x / ( 1 + sqrt(x*x + 1) )
  993. : copysign(log1p(fabs(x) + x*x / (1 + sqrt(x*x + 1)) ), x);
  994. }
  995. /// ditto
  996. double asinh(double x) @safe pure nothrow { return asinh(cast(real)x); }
  997. /// ditto
  998. float asinh(float x) @safe pure nothrow { return asinh(cast(real)x); }
  999. unittest
  1000. {
  1001. assert(isIdentical(asinh(0.0), 0.0));
  1002. assert(isIdentical(asinh(-0.0), -0.0));
  1003. assert(asinh(real.infinity) == real.infinity);
  1004. assert(asinh(-real.infinity) == -real.infinity);
  1005. assert(isNaN(asinh(real.nan)));
  1006. assert(equalsDigit(asinh(sinh(3.0)), 3, useDigits));
  1007. }
  1008. /***********************************
  1009. * Calculates the inverse hyperbolic tangent of x,
  1010. * returning a value from ranging from -1 to 1.
  1011. *
  1012. * Mathematically, atanh(x) = log( (1+x)/(1-x) ) / 2
  1013. *
  1014. *
  1015. * $(TABLE_DOMRG
  1016. * $(DOMAIN -$(INFIN)..$(INFIN))
  1017. * $(RANGE -1..1) )
  1018. * $(TABLE_SV
  1019. * $(SVH x, acosh(x) )
  1020. * $(SV $(NAN), $(NAN) )
  1021. * $(SV $(PLUSMN)0, $(PLUSMN)0)
  1022. * $(SV -$(INFIN), -0)
  1023. * )
  1024. */
  1025. real atanh(real x) @safe pure nothrow
  1026. {
  1027. // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) )
  1028. return 0.5 * log1p( 2 * x / (1 - x) );
  1029. }
  1030. /// ditto
  1031. double atanh(double x) @safe pure nothrow { return atanh(cast(real)x); }
  1032. /// ditto
  1033. float atanh(float x) @safe pure nothrow { return atanh(cast(real)x); }
  1034. unittest
  1035. {
  1036. assert(isIdentical(atanh(0.0), 0.0));
  1037. assert(isIdentical(atanh(-0.0),-0.0));
  1038. assert(isNaN(atanh(real.nan)));
  1039. assert(isNaN(atanh(-real.infinity)));
  1040. assert(atanh(0.0) == 0);
  1041. assert(equalsDigit(atanh(tanh(0.5L)), 0.5, useDigits));
  1042. }
  1043. /*****************************************
  1044. * Returns x rounded to a long value using the current rounding mode.
  1045. * If the integer value of x is
  1046. * greater than long.max, the result is
  1047. * indeterminate.
  1048. */
  1049. long rndtol(real x) @safe pure nothrow; /* intrinsic */
  1050. /*****************************************
  1051. * Returns x rounded to a long value using the FE_TONEAREST rounding mode.
  1052. * If the integer value of x is
  1053. * greater than long.max, the result is
  1054. * indeterminate.
  1055. */
  1056. extern (C) real rndtonl(real x);
  1057. /***************************************
  1058. * Compute square root of x.
  1059. *
  1060. * $(TABLE_SV
  1061. * $(TR $(TH x) $(TH sqrt(x)) $(TH invalid?))
  1062. * $(TR $(TD -0.0) $(TD -0.0) $(TD no))
  1063. * $(TR $(TD $(LT)0.0) $(TD $(NAN)) $(TD yes))
  1064. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no))
  1065. * )
  1066. */
  1067. float sqrt(float x) @safe pure nothrow; /* intrinsic */
  1068. /// ditto
  1069. double sqrt(double x) @safe pure nothrow; /* intrinsic */
  1070. /// ditto
  1071. real sqrt(real x) @safe pure nothrow; /* intrinsic */
  1072. unittest
  1073. {
  1074. //ctfe
  1075. enum ZX80 = sqrt(7.0f);
  1076. enum ZX81 = sqrt(7.0);
  1077. enum ZX82 = sqrt(7.0L);
  1078. }
  1079. creal sqrt(creal z) @safe pure nothrow
  1080. {
  1081. creal c;
  1082. real x,y,w,r;
  1083. if (z == 0)
  1084. {
  1085. c = 0 + 0i;
  1086. }
  1087. else
  1088. {
  1089. real z_re = z.re;
  1090. real z_im = z.im;
  1091. x = fabs(z_re);
  1092. y = fabs(z_im);
  1093. if (x >= y)
  1094. {
  1095. r = y / x;
  1096. w = sqrt(x) * sqrt(0.5 * (1 + sqrt(1 + r * r)));
  1097. }
  1098. else
  1099. {
  1100. r = x / y;
  1101. w = sqrt(y) * sqrt(0.5 * (r + sqrt(1 + r * r)));
  1102. }
  1103. if (z_re >= 0)
  1104. {
  1105. c = w + (z_im / (w + w)) * 1.0i;
  1106. }
  1107. else
  1108. {
  1109. if (z_im < 0)
  1110. w = -w;
  1111. c = z_im / (w + w) + w * 1.0i;
  1112. }
  1113. }
  1114. return c;
  1115. }
  1116. /**
  1117. * Calculates e$(SUP x).
  1118. *
  1119. * $(TABLE_SV
  1120. * $(TR $(TH x) $(TH e$(SUP x)) )
  1121. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) )
  1122. * $(TR $(TD -$(INFIN)) $(TD +0.0) )
  1123. * $(TR $(TD $(NAN)) $(TD $(NAN)) )
  1124. * )
  1125. */
  1126. real exp(real x) @trusted pure nothrow
  1127. {
  1128. version(D_InlineAsm_X86)
  1129. {
  1130. // e^^x = 2^^(LOG2E*x)
  1131. // (This is valid because the overflow & underflow limits for exp
  1132. // and exp2 are so similar).
  1133. return exp2(LOG2E*x);
  1134. }
  1135. else version(D_InlineAsm_X86_64)
  1136. {
  1137. // e^^x = 2^^(LOG2E*x)
  1138. // (This is valid because the overflow & underflow limits for exp
  1139. // and exp2 are so similar).
  1140. return exp2(LOG2E*x);
  1141. }
  1142. else
  1143. {
  1144. // Coefficients for exp(x)
  1145. static immutable real[3] P = [
  1146. 9.9999999999999999991025E-1L,
  1147. 3.0299440770744196129956E-2L,
  1148. 1.2617719307481059087798E-4L,
  1149. ];
  1150. static immutable real[4] Q = [
  1151. 2.0000000000000000000897E0L,
  1152. 2.2726554820815502876593E-1L,
  1153. 2.5244834034968410419224E-3L,
  1154. 3.0019850513866445504159E-6L,
  1155. ];
  1156. // C1 + C2 = LN2.
  1157. enum real C1 = 6.9314575195312500000000E-1L;
  1158. enum real C2 = 1.428606820309417232121458176568075500134E-6L;
  1159. // Overflow and Underflow limits.
  1160. enum real OF = 1.1356523406294143949492E4L;
  1161. enum real UF = -1.1432769596155737933527E4L;
  1162. // Special cases.
  1163. if (isNaN(x))
  1164. return x;
  1165. if (x > OF)
  1166. return real.infinity;
  1167. if (x < UF)
  1168. return 0.0;
  1169. // Express: e^^x = e^^g * 2^^n
  1170. // = e^^g * e^^(n * LOG2E)
  1171. // = e^^(g + n * LOG2E)
  1172. int n = cast(int)floor(LOG2E * x + 0.5);
  1173. x -= n * C1;
  1174. x -= n * C2;
  1175. // Rational approximation for exponential of the fractional part:
  1176. // e^^x = 1 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))
  1177. real xx = x * x;
  1178. real px = x * poly(xx, P);
  1179. x = px / (poly(xx, Q) - px);
  1180. x = 1.0 + ldexp(x, 1);
  1181. // Scale by power of 2.
  1182. x = ldexp(x, n);
  1183. return x;
  1184. }
  1185. }
  1186. /// ditto
  1187. double exp(double x) @safe pure nothrow { return exp(cast(real)x); }
  1188. /// ditto
  1189. float exp(float x) @safe pure nothrow { return exp(cast(real)x); }
  1190. unittest
  1191. {
  1192. assert(equalsDigit(exp(3.0L), E * E * E, useDigits));
  1193. }
  1194. /**
  1195. * Calculates the value of the natural logarithm base (e)
  1196. * raised to the power of x, minus 1.
  1197. *
  1198. * For very small x, expm1(x) is more accurate
  1199. * than exp(x)-1.
  1200. *
  1201. * $(TABLE_SV
  1202. * $(TR $(TH x) $(TH e$(SUP x)-1) )
  1203. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) )
  1204. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) )
  1205. * $(TR $(TD -$(INFIN)) $(TD -1.0) )
  1206. * $(TR $(TD $(NAN)) $(TD $(NAN)) )
  1207. * )
  1208. */
  1209. real expm1(real x) @trusted pure nothrow
  1210. {
  1211. version(D_InlineAsm_X86)
  1212. {
  1213. enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4
  1214. asm
  1215. {
  1216. /* expm1() for x87 80-bit reals, IEEE754-2008 conformant.
  1217. * Author: Don Clugston.
  1218. *
  1219. * expm1(x) = 2^^(rndint(y))* 2^^(y-rndint(y)) - 1 where y = LN2*x.
  1220. * = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^^(rndint(y))
  1221. * and 2ym1 = (2^^(y-rndint(y))-1).
  1222. * If 2rndy < 0.5*real.epsilon, result is -1.
  1223. * Implementation is otherwise the same as for exp2()
  1224. */
  1225. naked;
  1226. fld real ptr [ESP+4] ; // x
  1227. mov AX, [ESP+4+8]; // AX = exponent and sign
  1228. sub ESP, 12+8; // Create scratch space on the stack
  1229. // [ESP,ESP+2] = scratchint
  1230. // [ESP+4..+6, +8..+10, +10] = scratchreal
  1231. // set scratchreal mantissa = 1.0
  1232. mov dword ptr [ESP+8], 0;
  1233. mov dword ptr [ESP+8+4], 0x80000000;
  1234. and AX, 0x7FFF; // drop sign bit
  1235. cmp AX, 0x401D; // avoid InvalidException in fist
  1236. jae L_extreme;
  1237. fldl2e;
  1238. fmulp ST(1), ST; // y = x*log2(e)
  1239. fist dword ptr [ESP]; // scratchint = rndint(y)
  1240. fisub dword ptr [ESP]; // y - rndint(y)
  1241. // and now set scratchreal exponent
  1242. mov EAX, [ESP];
  1243. add EAX, 0x3fff;
  1244. jle short L_largenegative;
  1245. cmp EAX,0x8000;
  1246. jge short L_largepositive;
  1247. mov [ESP+8+8],AX;
  1248. f2xm1; // 2ym1 = 2^^(y-rndint(y)) -1
  1249. fld real ptr [ESP+8] ; // 2rndy = 2^^rndint(y)
  1250. fmul ST(1), ST; // ST=2rndy, ST(1)=2rndy*2ym1
  1251. fld1;
  1252. fsubp ST(1), ST; // ST = 2rndy-1, ST(1) = 2rndy * 2ym1 - 1
  1253. faddp ST(1), ST; // ST = 2rndy * 2ym1 + 2rndy - 1
  1254. add ESP,12+8;
  1255. ret PARAMSIZE;
  1256. L_extreme: // Extreme exponent. X is very large positive, very
  1257. // large negative, infinity, or NaN.
  1258. fxam;
  1259. fstsw AX;
  1260. test AX, 0x0400; // NaN_or_zero, but we already know x!=0
  1261. jz L_was_nan; // if x is NaN, returns x
  1262. test AX, 0x0200;
  1263. jnz L_largenegative;
  1264. L_largepositive:
  1265. // Set scratchreal = real.max.
  1266. // squaring it will create infinity, and set overflow flag.
  1267. mov word ptr [ESP+8+8], 0x7FFE;
  1268. fstp ST(0);
  1269. fld real ptr [ESP+8]; // load scratchreal
  1270. fmul ST(0), ST; // square it, to create havoc!
  1271. L_was_nan:
  1272. add ESP,12+8;
  1273. ret PARAMSIZE;
  1274. L_largenegative:
  1275. fstp ST(0);
  1276. fld1;
  1277. fchs; // return -1. Underflow flag is not set.
  1278. add ESP,12+8;
  1279. ret PARAMSIZE;
  1280. }
  1281. }
  1282. else version(D_InlineAsm_X86_64)
  1283. {
  1284. asm
  1285. {
  1286. naked;
  1287. }
  1288. version (Win64)
  1289. {
  1290. asm
  1291. {
  1292. fld real ptr [RCX]; // x
  1293. mov AX,[RCX+8]; // AX = exponent and sign
  1294. }
  1295. }
  1296. else
  1297. {
  1298. asm
  1299. {
  1300. fld real ptr [RSP+8]; // x
  1301. mov AX,[RSP+8+8]; // AX = exponent and sign
  1302. }
  1303. }
  1304. asm
  1305. {
  1306. /* expm1() for x87 80-bit reals, IEEE754-2008 conformant.
  1307. * Author: Don Clugston.
  1308. *
  1309. * expm1(x) = 2^(rndint(y))* 2^(y-rndint(y)) - 1 where y = LN2*x.
  1310. * = 2rndy * 2ym1 + 2rndy - 1, where 2rndy = 2^(rndint(y))
  1311. * and 2ym1 = (2^(y-rndint(y))-1).
  1312. * If 2rndy < 0.5*real.epsilon, result is -1.
  1313. * Implementation is otherwise the same as for exp2()
  1314. */
  1315. sub RSP, 24; // Create scratch space on the stack
  1316. // [RSP,RSP+2] = scratchint
  1317. // [RSP+4..+6, +8..+10, +10] = scratchreal
  1318. // set scratchreal mantissa = 1.0
  1319. mov dword ptr [RSP+8], 0;
  1320. mov dword ptr [RSP+8+4], 0x80000000;
  1321. and AX, 0x7FFF; // drop sign bit
  1322. cmp AX, 0x401D; // avoid InvalidException in fist
  1323. jae L_extreme;
  1324. fldl2e;
  1325. fmul ; // y = x*log2(e)
  1326. fist dword ptr [RSP]; // scratchint = rndint(y)
  1327. fisub dword ptr [RSP]; // y - rndint(y)
  1328. // and now set scratchreal exponent
  1329. mov EAX, [RSP];
  1330. add EAX, 0x3fff;
  1331. jle short L_largenegative;
  1332. cmp EAX,0x8000;
  1333. jge short L_largepositive;
  1334. mov [RSP+8+8],AX;
  1335. f2xm1; // 2^(y-rndint(y)) -1
  1336. fld real ptr [RSP+8] ; // 2^rndint(y)
  1337. fmul ST(1), ST;
  1338. fld1;
  1339. fsubp ST(1), ST;
  1340. fadd;
  1341. add RSP,24;
  1342. ret;
  1343. L_extreme: // Extreme exponent. X is very large positive, very
  1344. // large negative, infinity, or NaN.
  1345. fxam;
  1346. fstsw AX;
  1347. test AX, 0x0400; // NaN_or_zero, but we already know x!=0
  1348. jz L_was_nan; // if x is NaN, returns x
  1349. test AX, 0x0200;
  1350. jnz L_largenegative;
  1351. L_largepositive:
  1352. // Set scratchreal = real.max.
  1353. // squaring it will create infinity, and set overflow flag.
  1354. mov word ptr [RSP+8+8], 0x7FFE;
  1355. fstp ST(0);
  1356. fld real ptr [RSP+8]; // load scratchreal
  1357. fmul ST(0), ST; // square it, to create havoc!
  1358. L_was_nan:
  1359. add RSP,24;
  1360. ret;
  1361. L_largenegative:
  1362. fstp ST(0);
  1363. fld1;
  1364. fchs; // return -1. Underflow flag is not set.
  1365. add RSP,24;
  1366. ret;
  1367. }
  1368. }
  1369. else
  1370. {
  1371. // Coefficients for exp(x) - 1
  1372. static immutable real[5] P = [
  1373. -1.586135578666346600772998894928250240826E4L,
  1374. 2.642771505685952966904660652518429479531E3L,
  1375. -3.423199068835684263987132888286791620673E2L,
  1376. 1.800826371455042224581246202420972737840E1L,
  1377. -5.238523121205561042771939008061958820811E-1L,
  1378. ];
  1379. static immutable real[6] Q = [
  1380. -9.516813471998079611319047060563358064497E4L,
  1381. 3.964866271411091674556850458227710004570E4L,
  1382. -7.207678383830091850230366618190187434796E3L,
  1383. 7.206038318724600171970199625081491823079E2L,
  1384. -4.002027679107076077238836622982900945173E1L,
  1385. 1.000000000000000000000000000000000000000E0L,
  1386. ];
  1387. // C1 + C2 = LN2.
  1388. enum real C1 = 6.9314575195312500000000E-1L;
  1389. enum real C2 = 1.4286068203094172321215E-6L;
  1390. // Overflow and Underflow limits.
  1391. enum real OF = 1.1356523406294143949492E4L;
  1392. enum real UF = -4.5054566736396445112120088E1L;
  1393. // Special cases.
  1394. if (x > OF)
  1395. return real.infinity;
  1396. if (x == 0.0)
  1397. return x;
  1398. if (x < UF)
  1399. return -1.0;
  1400. // Express x = LN2 (n + remainder), remainder not exceeding 1/2.
  1401. int n = cast(int)floor(0.5 + x / LN2);
  1402. x -= n * C1;
  1403. x -= n * C2;
  1404. // Rational approximation:
  1405. // exp(x) - 1 = x + 0.5 x^^2 + x^^3 P(x) / Q(x)
  1406. real px = x * poly(x, P);
  1407. real qx = poly(x, Q);
  1408. real xx = x * x;
  1409. qx = x + (0.5 * xx + xx * px / qx);
  1410. // We have qx = exp(remainder LN2) - 1, so:
  1411. // exp(x) - 1 = 2^^n (qx + 1) - 1 = 2^^n qx + 2^^n - 1.
  1412. px = ldexp(1.0, n);
  1413. x = px * qx + (px - 1.0);
  1414. return x;
  1415. }
  1416. }
  1417. /**
  1418. * Calculates 2$(SUP x).
  1419. *
  1420. * $(TABLE_SV
  1421. * $(TR $(TH x) $(TH exp2(x)) )
  1422. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) )
  1423. * $(TR $(TD -$(INFIN)) $(TD +0.0) )
  1424. * $(TR $(TD $(NAN)) $(TD $(NAN)) )
  1425. * )
  1426. */
  1427. real exp2(real x) @trusted pure nothrow
  1428. {
  1429. version(D_InlineAsm_X86)
  1430. {
  1431. enum PARAMSIZE = (real.sizeof+3)&(0xFFFF_FFFC); // always a multiple of 4
  1432. asm
  1433. {
  1434. /* exp2() for x87 80-bit reals, IEEE754-2008 conformant.
  1435. * Author: Don Clugston.
  1436. *
  1437. * exp2(x) = 2^^(rndint(x))* 2^^(y-rndint(x))
  1438. * The trick for high performance is to avoid the fscale(28cycles on core2),
  1439. * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.
  1440. *
  1441. * We can do frndint by using fist. BUT we can't use it for huge numbers,
  1442. * because it will set the Invalid Operation flag if overflow or NaN occurs.
  1443. * Fortunately, whenever this happens the result would be zero or infinity.
  1444. *
  1445. * We can perform fscale by directly poking into the exponent. BUT this doesn't
  1446. * work for the (very rare) cases where the result is subnormal. So we fall back
  1447. * to the slow method in that case.
  1448. */
  1449. naked;
  1450. fld real ptr [ESP+4] ; // x
  1451. mov AX, [ESP+4+8]; // AX = exponent and sign
  1452. sub ESP, 12+8; // Create scratch space on the stack
  1453. // [ESP,ESP+2] = scratchint
  1454. // [ESP+4..+6, +8..+10, +10] = scratchreal
  1455. // set scratchreal mantissa = 1.0
  1456. mov dword ptr [ESP+8], 0;
  1457. mov dword ptr [ESP+8+4], 0x80000000;
  1458. and AX, 0x7FFF; // drop sign bit
  1459. cmp AX, 0x401D; // avoid InvalidException in fist
  1460. jae L_extreme;
  1461. fist dword ptr [ESP]; // scratchint = rndint(x)
  1462. fisub dword ptr [ESP]; // x - rndint(x)
  1463. // and now set scratchreal exponent
  1464. mov EAX, [ESP];
  1465. add EAX, 0x3fff;
  1466. jle short L_subnormal;
  1467. cmp EAX,0x8000;
  1468. jge short L_overflow;
  1469. mov [ESP+8+8],AX;
  1470. L_normal:
  1471. f2xm1;
  1472. fld1;
  1473. faddp ST(1), ST; // 2^^(x-rndint(x))
  1474. fld real ptr [ESP+8] ; // 2^^rndint(x)
  1475. add ESP,12+8;
  1476. fmulp ST(1), ST;
  1477. ret PARAMSIZE;
  1478. L_subnormal:
  1479. // Result will be subnormal.
  1480. // In this rare case, the simple poking method doesn't work.
  1481. // The speed doesn't matter, so use the slow fscale method.
  1482. fild dword ptr [ESP]; // scratchint
  1483. fld1;
  1484. fscale;
  1485. fstp real ptr [ESP+8]; // scratchreal = 2^^scratchint
  1486. fstp ST(0); // drop scratchint
  1487. jmp L_normal;
  1488. L_extreme: // Extreme exponent. X is very large positive, very
  1489. // large negative, infinity, or NaN.
  1490. fxam;
  1491. fstsw AX;
  1492. test AX, 0x0400; // NaN_or_zero, but we already know x!=0
  1493. jz L_was_nan; // if x is NaN, returns x
  1494. // set scratchreal = real.min_normal
  1495. // squaring it will return 0, setting underflow flag
  1496. mov word ptr [ESP+8+8], 1;
  1497. test AX, 0x0200;
  1498. jnz L_waslargenegative;
  1499. L_overflow:
  1500. // Set scratchreal = real.max.
  1501. // squaring it will create infinity, and set overflow flag.
  1502. mov word ptr [ESP+8+8], 0x7FFE;
  1503. L_waslargenegative:
  1504. fstp ST(0);
  1505. fld real ptr [ESP+8]; // load scratchreal
  1506. fmul ST(0), ST; // square it, to create havoc!
  1507. L_was_nan:
  1508. add ESP,12+8;
  1509. ret PARAMSIZE;
  1510. }
  1511. }
  1512. else version(D_InlineAsm_X86_64)
  1513. {
  1514. asm
  1515. {
  1516. naked;
  1517. }
  1518. version (Win64)
  1519. {
  1520. asm
  1521. {
  1522. fld real ptr [RCX]; // x
  1523. mov AX,[RCX+8]; // AX = exponent and sign
  1524. }
  1525. }
  1526. else
  1527. {
  1528. asm
  1529. {
  1530. fld real ptr [RSP+8]; // x
  1531. mov AX,[RSP+8+8]; // AX = exponent and sign
  1532. }
  1533. }
  1534. asm
  1535. {
  1536. /* exp2() for x87 80-bit reals, IEEE754-2008 conformant.
  1537. * Author: Don Clugston.
  1538. *
  1539. * exp2(x) = 2^(rndint(x))* 2^(y-rndint(x))
  1540. * The trick for high performance is to avoid the fscale(28cycles on core2),
  1541. * frndint(19 cycles), leaving f2xm1(19 cycles) as the only slow instruction.
  1542. *
  1543. * We can do frndint by using fist. BUT we can't use it for huge numbers,
  1544. * because it will set the Invalid Operation flag is overflow or NaN occurs.
  1545. * Fortunately, whenever this happens the result would be zero or infinity.
  1546. *
  1547. * We can perform fscale by directly poking into the exponent. BUT this doesn't
  1548. * work for the (very rare) cases where the result is subnormal. So we fall back
  1549. * to the slow method in that case.
  1550. */
  1551. sub RSP, 24; // Create scratch space on the stack
  1552. // [RSP,RSP+2] = scratchint
  1553. // [RSP+4..+6, +8..+10, +10] = scratchreal
  1554. // set scratchreal mantissa = 1.0
  1555. mov dword ptr [RSP+8], 0;
  1556. mov dword ptr [RSP+8+4], 0x80000000;
  1557. and AX, 0x7FFF; // drop sign bit
  1558. cmp AX, 0x401D; // avoid InvalidException in fist
  1559. jae L_extreme;
  1560. fist dword ptr [RSP]; // scratchint = rndint(x)
  1561. fisub dword ptr [RSP]; // x - rndint(x)
  1562. // and now set scratchreal exponent
  1563. mov EAX, [RSP];
  1564. add EAX, 0x3fff;
  1565. jle short L_subnormal;
  1566. cmp EAX,0x8000;
  1567. jge short L_overflow;
  1568. mov [RSP+8+8],AX;
  1569. L_normal:
  1570. f2xm1;
  1571. fld1;
  1572. fadd; // 2^(x-rndint(x))
  1573. fld real ptr [RSP+8] ; // 2^rndint(x)
  1574. add RSP,24;
  1575. fmulp ST(1), ST;
  1576. ret;
  1577. L_subnormal:
  1578. // Result will be subnormal.
  1579. // In this rare case, the simple poking method doesn't work.
  1580. // The speed doesn't matter, so use the slow fscale method.
  1581. fild dword ptr [RSP]; // scratchint
  1582. fld1;
  1583. fscale;
  1584. fstp real ptr [RSP+8]; // scratchreal = 2^scratchint
  1585. fstp ST(0); // drop scratchint
  1586. jmp L_normal;
  1587. L_extreme: // Extreme exponent. X is very large positive, very
  1588. // large negative, infinity, or NaN.
  1589. fxam;
  1590. fstsw AX;
  1591. test AX, 0x0400; // NaN_or_zero, but we already know x!=0
  1592. jz L_was_nan; // if x is NaN, returns x
  1593. // set scratchreal = real.min
  1594. // squaring it will return 0, setting underflow flag
  1595. mov word ptr [RSP+8+8], 1;
  1596. test AX, 0x0200;
  1597. jnz L_waslargenegative;
  1598. L_overflow:
  1599. // Set scratchreal = real.max.
  1600. // squaring it will create infinity, and set overflow flag.
  1601. mov word ptr [RSP+8+8], 0x7FFE;
  1602. L_waslargenegative:
  1603. fstp ST(0);
  1604. fld real ptr [RSP+8]; // load scratchreal
  1605. fmul ST(0), ST; // square it, to create havoc!
  1606. L_was_nan:
  1607. add RSP,24;
  1608. ret;
  1609. }
  1610. }
  1611. else
  1612. {
  1613. // Coefficients for exp2(x)
  1614. static immutable real[3] P = [
  1615. 2.0803843631901852422887E6L,
  1616. 3.0286971917562792508623E4L,
  1617. 6.0614853552242266094567E1L,
  1618. ];
  1619. static immutable real[4] Q = [
  1620. 6.0027204078348487957118E6L,
  1621. 3.2772515434906797273099E5L,
  1622. 1.7492876999891839021063E3L,
  1623. 1.0000000000000000000000E0L,
  1624. ];
  1625. // Overflow and Underflow limits.
  1626. enum real OF = 16384.0L;
  1627. enum real UF = -16382.0L;
  1628. // Special cases.
  1629. if (isNaN(x))
  1630. return x;
  1631. if (x > OF)
  1632. return real.infinity;
  1633. if (x < UF)
  1634. return 0.0;
  1635. // Separate into integer and fractional parts.
  1636. int n = cast(int)floor(x + 0.5);
  1637. x -= n;
  1638. // Rational approximation:
  1639. // exp2(x) = 1.0 + 2x P(x^^2) / (Q(x^^2) - P(x^^2))
  1640. real xx = x * x;
  1641. real px = x * poly(xx, P);
  1642. x = px / (poly(xx, Q) - px);
  1643. x = 1.0 + ldexp(x, 1);
  1644. // Scale by power of 2.
  1645. x = ldexp(x, n);
  1646. return x;
  1647. }
  1648. }
  1649. unittest
  1650. {
  1651. assert(exp2(0.5L)== SQRT2);
  1652. assert(exp2(8.0L) == 256.0);
  1653. assert(exp2(-9.0L)== 1.0L/512.0);
  1654. assert( core.stdc.math.exp2f(0.0f) == 1 );
  1655. assert( core.stdc.math.exp2 (0.0) == 1 );
  1656. assert( core.stdc.math.exp2l(0.0L) == 1 );
  1657. }
  1658. unittest
  1659. {
  1660. FloatingPointControl ctrl;
  1661. ctrl.disableExceptions(FloatingPointControl.allExceptions);
  1662. ctrl.rounding = FloatingPointControl.roundToNearest;
  1663. // @@BUG@@: Non-immutable array literals are ridiculous.
  1664. // Note that these are only valid for 80-bit reals: overflow will be different for 64-bit reals.
  1665. static const real [2][] exptestpoints =
  1666. [ // x, exp(x)
  1667. [1.0L, E ],
  1668. [0.5L, 0x1.A612_98E1_E069_BC97p+0L ],
  1669. [3.0L, E*E*E ],
  1670. [0x1.1p13L, 0x1.29aeffefc8ec645p+12557L ], // near overflow
  1671. [-0x1.18p13L, 0x1.5e4bf54b4806db9p-12927L ], // near underflow
  1672. [-0x1.625p13L, 0x1.a6bd68a39d11f35cp-16358L],
  1673. [-0x1p30L, 0 ], // underflow - subnormal
  1674. [-0x1.62DAFp13L, 0x1.96c53d30277021dp-16383L ],
  1675. [-0x1.643p13L, 0x1p-16444L ],
  1676. [-0x1.645p13L, 0 ], // underflow to zero
  1677. [0x1p80L, real.infinity ], // far overflow
  1678. [real.infinity, real.infinity ],
  1679. [0x1.7p13L, real.infinity ] // close overflow
  1680. ];
  1681. real x;
  1682. IeeeFlags f;
  1683. for (int i=0; i<exptestpoints.length;++i)
  1684. {
  1685. resetIeeeFlags();
  1686. x = exp(exptestpoints[i][0]);
  1687. f = ieeeFlags;
  1688. assert(x == exptestpoints[i][1]);
  1689. // Check the overflow bit
  1690. assert(f.overflow == (fabs(x) == real.infinity));
  1691. // Check the underflow bit
  1692. assert(f.underflow == (fabs(x) < real.min_normal));
  1693. // Invalid and div by zero shouldn't be affected.
  1694. assert(!f.invalid);
  1695. assert(!f.divByZero);
  1696. }
  1697. // Ideally, exp(0) would not set the inexact flag.
  1698. // Unfortunately, fldl2e sets it!
  1699. // So it's not realistic to avoid setting it.
  1700. assert(exp(0.0L) == 1.0);
  1701. // NaN propagation. Doesn't set flags, bcos was already NaN.
  1702. resetIeeeFlags();
  1703. x = exp(real.nan);
  1704. f = ieeeFlags;
  1705. assert(isIdentical(abs(x), real.nan));
  1706. assert(f.flags == 0);
  1707. resetIeeeFlags();
  1708. x = exp(-real.nan);
  1709. f = ieeeFlags;
  1710. assert(isIdentical(abs(x), real.nan));
  1711. assert(f.flags == 0);
  1712. x = exp(NaN(0x123));
  1713. assert(isIdentical(x, NaN(0x123)));
  1714. // High resolution test
  1715. assert(exp(0.5L) == 0x1.A612_98E1_E069_BC97_2DFE_FAB6D_33Fp+0L);
  1716. }
  1717. /**
  1718. * Calculate cos(y) + i sin(y).
  1719. *
  1720. * On many CPUs (such as x86), this is a very efficient operation;
  1721. * almost twice as fast as calculating sin(y) and cos(y) separately,
  1722. * and is the preferred method when both are required.
  1723. */
  1724. creal expi(real y) @trusted pure nothrow
  1725. {
  1726. version(InlineAsm_X86_Any)
  1727. {
  1728. version (Win64)
  1729. {
  1730. asm
  1731. {
  1732. naked;
  1733. fld real ptr [ECX];
  1734. fsincos;
  1735. fxch ST(1), ST(0);
  1736. ret;
  1737. }
  1738. }
  1739. else
  1740. {
  1741. asm
  1742. {
  1743. fld y;
  1744. fsincos;
  1745. fxch ST(1), ST(0);
  1746. }
  1747. }
  1748. }
  1749. else
  1750. {
  1751. return cos(y) + sin(y)*1i;
  1752. }
  1753. }
  1754. unittest
  1755. {
  1756. assert(expi(1.3e5L) == cos(1.3e5L) + sin(1.3e5L) * 1i);
  1757. assert(expi(0.0L) == 1L + 0.0Li);
  1758. }
  1759. /*********************************************************************
  1760. * Separate floating point value into significand and exponent.
  1761. *
  1762. * Returns:
  1763. * Calculate and return $(I x) and $(I exp) such that
  1764. * value =$(I x)*2$(SUP exp) and
  1765. * .5 $(LT)= |$(I x)| $(LT) 1.0
  1766. *
  1767. * $(I x) has same sign as value.
  1768. *
  1769. * $(TABLE_SV
  1770. * $(TR $(TH value) $(TH returns) $(TH exp))
  1771. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD 0))
  1772. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD int.max))
  1773. * $(TR $(TD -$(INFIN)) $(TD -$(INFIN)) $(TD int.min))
  1774. * $(TR $(TD $(PLUSMN)$(NAN)) $(TD $(PLUSMN)$(NAN)) $(TD int.min))
  1775. * )
  1776. */
  1777. real frexp(real value, out int exp) @trusted pure nothrow
  1778. {
  1779. ushort* vu = cast(ushort*)&value;
  1780. long* vl = cast(long*)&value;
  1781. int ex;
  1782. alias floatTraits!(real) F;
  1783. ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
  1784. static if (real.mant_dig == 64) // real80
  1785. {
  1786. if (ex)
  1787. { // If exponent is non-zero
  1788. if (ex == F.EXPMASK) // infinity or NaN
  1789. {
  1790. if (*vl & 0x7FFF_FFFF_FFFF_FFFF) // NaN
  1791. {
  1792. *vl |= 0xC000_0000_0000_0000; // convert NaNS to NaNQ
  1793. exp = int.min;
  1794. }
  1795. else if (vu[F.EXPPOS_SHORT] & 0x8000) // negative infinity
  1796. exp = int.min;
  1797. else // positive infinity
  1798. exp = int.max;
  1799. }
  1800. else
  1801. {
  1802. exp = ex - F.EXPBIAS;
  1803. vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE;
  1804. }
  1805. }
  1806. else if (!*vl)
  1807. {
  1808. // value is +-0.0
  1809. exp = 0;
  1810. }
  1811. else
  1812. {
  1813. // subnormal
  1814. value *= F.RECIP_EPSILON;
  1815. ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
  1816. exp = ex - F.EXPBIAS - real.mant_dig + 1;
  1817. vu[F.EXPPOS_SHORT] = (0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE;
  1818. }
  1819. return value;
  1820. }
  1821. else static if (real.mant_dig == 113) // quadruple
  1822. {
  1823. if (ex) // If exponent is non-zero
  1824. {
  1825. if (ex == F.EXPMASK)
  1826. { // infinity or NaN
  1827. if (vl[MANTISSA_LSB] |
  1828. ( vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) // NaN
  1829. {
  1830. // convert NaNS to NaNQ
  1831. vl[MANTISSA_MSB] |= 0x0000_8000_0000_0000;
  1832. exp = int.min;
  1833. }
  1834. else if (vu[F.EXPPOS_SHORT] & 0x8000) // negative infinity
  1835. exp = int.min;
  1836. else // positive infinity
  1837. exp = int.max;
  1838. }
  1839. else
  1840. {
  1841. exp = ex - F.EXPBIAS;
  1842. vu[F.EXPPOS_SHORT] =
  1843. cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE);
  1844. }
  1845. }
  1846. else if ((vl[MANTISSA_LSB]
  1847. |(vl[MANTISSA_MSB] & 0x0000_FFFF_FFFF_FFFF)) == 0)
  1848. {
  1849. // value is +-0.0
  1850. exp = 0;
  1851. }
  1852. else
  1853. {
  1854. // subnormal
  1855. value *= F.RECIP_EPSILON;
  1856. ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
  1857. exp = ex - F.EXPBIAS - real.mant_dig + 1;
  1858. vu[F.EXPPOS_SHORT] =
  1859. cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FFE);
  1860. }
  1861. return value;
  1862. }
  1863. else static if (real.mant_dig==53) // real is double
  1864. {
  1865. if (ex) // If exponent is non-zero
  1866. {
  1867. if (ex == F.EXPMASK) // infinity or NaN
  1868. {
  1869. if (*vl == 0x7FF0_0000_0000_0000) // positive infinity
  1870. {
  1871. exp = int.max;
  1872. }
  1873. else if (*vl == 0xFFF0_0000_0000_0000) // negative infinity
  1874. exp = int.min;
  1875. else
  1876. { // NaN
  1877. *vl |= 0x0008_0000_0000_0000; // convert NaNS to NaNQ
  1878. exp = int.min;
  1879. }
  1880. }
  1881. else
  1882. {
  1883. exp = (ex - F.EXPBIAS) >> 4;
  1884. vu[F.EXPPOS_SHORT] = cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FE0);
  1885. }
  1886. }
  1887. else if (!(*vl & 0x7FFF_FFFF_FFFF_FFFF))
  1888. {
  1889. // value is +-0.0
  1890. exp = 0;
  1891. }
  1892. else
  1893. {
  1894. // subnormal
  1895. value *= F.RECIP_EPSILON;
  1896. ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
  1897. exp = ((ex - F.EXPBIAS)>> 4) - real.mant_dig + 1;
  1898. vu[F.EXPPOS_SHORT] =
  1899. cast(ushort)((0x8000 & vu[F.EXPPOS_SHORT]) | 0x3FE0);
  1900. }
  1901. return value;
  1902. }
  1903. else // static if (real.mant_dig==106) // real is doubledouble
  1904. {
  1905. assert (0, "frexp not implemented");
  1906. }
  1907. }
  1908. unittest
  1909. {
  1910. static real[3][] vals = // x,frexp,exp
  1911. [
  1912. [0.0, 0.0, 0],
  1913. [-0.0, -0.0, 0],
  1914. [1.0, .5, 1],
  1915. [-1.0, -.5, 1],
  1916. [2.0, .5, 2],
  1917. [double.min_normal/2.0, .5, -1022],
  1918. [real.infinity,real.infinity,int.max],
  1919. [-real.infinity,-real.infinity,int.min],
  1920. [real.nan,real.nan,int.min],
  1921. [-real.nan,-real.nan,int.min],
  1922. ];
  1923. int i;
  1924. for (i = 0; i < vals.length; i++)
  1925. {
  1926. real x = vals[i][0];
  1927. real e = vals[i][1];
  1928. int exp = cast(int)vals[i][2];
  1929. int eptr;
  1930. real v = frexp(x, eptr);
  1931. assert(isIdentical(e, v));
  1932. assert(exp == eptr);
  1933. }
  1934. static if (real.mant_dig == 64)
  1935. {
  1936. static real[3][] extendedvals = [ // x,frexp,exp
  1937. [0x1.a5f1c2eb3fe4efp+73L, 0x1.A5F1C2EB3FE4EFp-1L, 74], // normal
  1938. [0x1.fa01712e8f0471ap-1064L, 0x1.fa01712e8f0471ap-1L, -1063],
  1939. [real.min_normal, .5, -16381],
  1940. [real.min_normal/2.0L, .5, -16382] // subnormal
  1941. ];
  1942. for (i = 0; i < extendedvals.length; i++)
  1943. {
  1944. real x = extendedvals[i][0];
  1945. real e = extendedvals[i][1];
  1946. int exp = cast(int)extendedvals[i][2];
  1947. int eptr;
  1948. real v = frexp(x, eptr);
  1949. assert(isIdentical(e, v));
  1950. assert(exp == eptr);
  1951. }
  1952. }
  1953. }
  1954. unittest
  1955. {
  1956. int exp;
  1957. real mantissa = frexp(123.456, exp);
  1958. assert(equalsDigit(mantissa * pow(2.0L, cast(real)exp), 123.456, 19));
  1959. assert(frexp(-real.nan, exp) && exp == int.min);
  1960. assert(frexp(real.nan, exp) && exp == int.min);
  1961. assert(frexp(-real.infinity, exp) == -real.infinity && exp == int.min);
  1962. assert(frexp(real.infinity, exp) == real.infinity && exp == int.max);
  1963. assert(frexp(-0.0, exp) == -0.0 && exp == 0);
  1964. assert(frexp(0.0, exp) == 0.0 && exp == 0);
  1965. }
  1966. /******************************************
  1967. * Extracts the exponent of x as a signed integral value.
  1968. *
  1969. * If x is not a special value, the result is the same as
  1970. * $(D cast(int)logb(x)).
  1971. *
  1972. * $(TABLE_SV
  1973. * $(TR $(TH x) $(TH ilogb(x)) $(TH Range error?))
  1974. * $(TR $(TD 0) $(TD FP_ILOGB0) $(TD yes))
  1975. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD int.max) $(TD no))
  1976. * $(TR $(TD $(NAN)) $(TD FP_ILOGBNAN) $(TD no))
  1977. * )
  1978. */
  1979. int ilogb(real x) @trusted nothrow
  1980. {
  1981. version (Win64)
  1982. {
  1983. asm
  1984. {
  1985. naked ;
  1986. fld real ptr [RCX] ;
  1987. fxam ;
  1988. fstsw AX ;
  1989. and AH,0x45 ;
  1990. cmp AH,0x40 ;
  1991. jz Lzeronan ;
  1992. cmp AH,5 ;
  1993. jz Linfinity ;
  1994. cmp AH,1 ;
  1995. jz Lzeronan ;
  1996. fxtract ;
  1997. fstp ST(0) ;
  1998. fistp dword ptr 8[RSP] ;
  1999. mov EAX,8[RSP] ;
  2000. ret ;
  2001. Lzeronan:
  2002. mov EAX,0x80000000 ;
  2003. fstp ST(0) ;
  2004. ret ;
  2005. Linfinity:
  2006. mov EAX,0x7FFFFFFF ;
  2007. fstp ST(0) ;
  2008. ret ;
  2009. }
  2010. }
  2011. else
  2012. return core.stdc.math.ilogbl(x);
  2013. }
  2014. alias core.stdc.math.FP_ILOGB0 FP_ILOGB0;
  2015. alias core.stdc.math.FP_ILOGBNAN FP_ILOGBNAN;
  2016. /*******************************************
  2017. * Compute n * 2$(SUP exp)
  2018. * References: frexp
  2019. */
  2020. real ldexp(real n, int exp) @safe pure nothrow; /* intrinsic */
  2021. unittest
  2022. {
  2023. assert(ldexp(1, -16384) == 0x1p-16384L);
  2024. assert(ldexp(1, -16382) == 0x1p-16382L);
  2025. int x;
  2026. real n = frexp(0x1p-16384L, x);
  2027. assert(n==0.5L);
  2028. assert(x==-16383);
  2029. assert(ldexp(n, x)==0x1p-16384L);
  2030. }
  2031. unittest
  2032. {
  2033. static real[3][] vals = // value,exp,ldexp
  2034. [
  2035. [ 0, 0, 0],
  2036. [ 1, 0, 1],
  2037. [ -1, 0, -1],
  2038. [ 1, 1, 2],
  2039. [ 123, 10, 125952],
  2040. [ real.max, int.max, real.infinity],
  2041. [ real.max, -int.max, 0],
  2042. [ real.min_normal, -int.max, 0],
  2043. ];
  2044. int i;
  2045. for (i = 0; i < vals.length; i++)
  2046. {
  2047. real x = vals[i][0];
  2048. int exp = cast(int)vals[i][1];
  2049. real z = vals[i][2];
  2050. real l = ldexp(x, exp);
  2051. assert(equalsDigit(z, l, 7));
  2052. }
  2053. }
  2054. unittest
  2055. {
  2056. real r;
  2057. r = ldexp(3.0L, 3);
  2058. assert(r == 24);
  2059. r = ldexp(cast(real) 3.0, cast(int) 3);
  2060. assert(r == 24);
  2061. real n = 3.0;
  2062. int exp = 3;
  2063. r = ldexp(n, exp);
  2064. assert(r == 24);
  2065. }
  2066. /**************************************
  2067. * Calculate the natural logarithm of x.
  2068. *
  2069. * $(TABLE_SV
  2070. * $(TR $(TH x) $(TH log(x)) $(TH divide by 0?) $(TH invalid?))
  2071. * $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes) $(TD no))
  2072. * $(TR $(TD $(LT)0.0) $(TD $(NAN)) $(TD no) $(TD yes))
  2073. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no))
  2074. * )
  2075. */
  2076. real log(real x) @safe pure nothrow
  2077. {
  2078. version (INLINE_YL2X)
  2079. return yl2x(x, LN2);
  2080. else
  2081. {
  2082. // Coefficients for log(1 + x)
  2083. static immutable real[7] P = [
  2084. 2.0039553499201281259648E1L,
  2085. 5.7112963590585538103336E1L,
  2086. 6.0949667980987787057556E1L,
  2087. 2.9911919328553073277375E1L,
  2088. 6.5787325942061044846969E0L,
  2089. 4.9854102823193375972212E-1L,
  2090. 4.5270000862445199635215E-5L,
  2091. ];
  2092. static immutable real[7] Q = [
  2093. 6.0118660497603843919306E1L,
  2094. 2.1642788614495947685003E2L,
  2095. 3.0909872225312059774938E2L,
  2096. 2.2176239823732856465394E2L,
  2097. 8.3047565967967209469434E1L,
  2098. 1.5062909083469192043167E1L,
  2099. 1.0000000000000000000000E0L,
  2100. ];
  2101. // Coefficients for log(x)
  2102. static immutable real[4] R = [
  2103. -3.5717684488096787370998E1L,
  2104. 1.0777257190312272158094E1L,
  2105. -7.1990767473014147232598E-1L,
  2106. 1.9757429581415468984296E-3L,
  2107. ];
  2108. static immutable real[4] S = [
  2109. -4.2861221385716144629696E2L,
  2110. 1.9361891836232102174846E2L,
  2111. -2.6201045551331104417768E1L,
  2112. 1.0000000000000000000000E0L,
  2113. ];
  2114. // C1 + C2 = LN2.
  2115. enum real C1 = 6.9314575195312500000000E-1L;
  2116. enum real C2 = 1.4286068203094172321215E-6L;
  2117. // Special cases.
  2118. if (isNaN(x))
  2119. return x;
  2120. if (isInfinity(x) && !signbit(x))
  2121. return x;
  2122. if (x == 0.0)
  2123. return -real.infinity;
  2124. if (x < 0.0)
  2125. return real.nan;
  2126. // Separate mantissa from exponent.
  2127. // Note, frexp is used so that denormal numbers will be handled properly.
  2128. real y, z;
  2129. int exp;
  2130. x = frexp(x, exp);
  2131. // Logarithm using log(x) = z + z^^3 P(z) / Q(z),
  2132. // where z = 2(x - 1)/(x + 1)
  2133. if((exp > 2) || (exp < -2))
  2134. {
  2135. if(x < SQRT1_2)
  2136. { // 2(2x - 1)/(2x + 1)
  2137. exp -= 1;
  2138. z = x - 0.5;
  2139. y = 0.5 * z + 0.5;
  2140. }
  2141. else
  2142. { // 2(x - 1)/(x + 1)
  2143. z = x - 0.5;
  2144. z -= 0.5;
  2145. y = 0.5 * x + 0.5;
  2146. }
  2147. x = z / y;
  2148. z = x * x;
  2149. z = x * (z * poly(z, R) / poly(z, S));
  2150. z += exp * C2;
  2151. z += x;
  2152. z += exp * C1;
  2153. return z;
  2154. }
  2155. // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
  2156. if (x < SQRT1_2)
  2157. { // 2x - 1
  2158. exp -= 1;
  2159. x = ldexp(x, 1) - 1.0;
  2160. }
  2161. else
  2162. {
  2163. x = x - 1.0;
  2164. }
  2165. z = x * x;
  2166. y = x * (z * poly(x, P) / poly(x, Q));
  2167. y += exp * C2;
  2168. z = y - ldexp(z, -1);
  2169. // Note, the sum of above terms does not exceed x/4,
  2170. // so it contributes at most about 1/4 lsb to the error.
  2171. z += x;
  2172. z += exp * C1;
  2173. return z;
  2174. }
  2175. }
  2176. unittest
  2177. {
  2178. assert(log(E) == 1);
  2179. }
  2180. /**************************************
  2181. * Calculate the base-10 logarithm of x.
  2182. *
  2183. * $(TABLE_SV
  2184. * $(TR $(TH x) $(TH log10(x)) $(TH divide by 0?) $(TH invalid?))
  2185. * $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes) $(TD no))
  2186. * $(TR $(TD $(LT)0.0) $(TD $(NAN)) $(TD no) $(TD yes))
  2187. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no))
  2188. * )
  2189. */
  2190. real log10(real x) @safe pure nothrow
  2191. {
  2192. version (INLINE_YL2X)
  2193. return yl2x(x, LOG2);
  2194. else
  2195. {
  2196. // Coefficients for log(1 + x)
  2197. static immutable real[7] P = [
  2198. 2.0039553499201281259648E1L,
  2199. 5.7112963590585538103336E1L,
  2200. 6.0949667980987787057556E1L,
  2201. 2.9911919328553073277375E1L,
  2202. 6.5787325942061044846969E0L,
  2203. 4.9854102823193375972212E-1L,
  2204. 4.5270000862445199635215E-5L,
  2205. ];
  2206. static immutable real[7] Q = [
  2207. 6.0118660497603843919306E1L,
  2208. 2.1642788614495947685003E2L,
  2209. 3.0909872225312059774938E2L,
  2210. 2.2176239823732856465394E2L,
  2211. 8.3047565967967209469434E1L,
  2212. 1.5062909083469192043167E1L,
  2213. 1.0000000000000000000000E0L,
  2214. ];
  2215. // Coefficients for log(x)
  2216. static immutable real[4] R = [
  2217. -3.5717684488096787370998E1L,
  2218. 1.0777257190312272158094E1L,
  2219. -7.1990767473014147232598E-1L,
  2220. 1.9757429581415468984296E-3L,
  2221. ];
  2222. static immutable real[4] S = [
  2223. -4.2861221385716144629696E2L,
  2224. 1.9361891836232102174846E2L,
  2225. -2.6201045551331104417768E1L,
  2226. 1.0000000000000000000000E0L,
  2227. ];
  2228. // log10(2) split into two parts.
  2229. enum real L102A = 0.3125L;
  2230. enum real L102B = -1.14700043360188047862611052755069732318101185E-2L;
  2231. // log10(e) split into two parts.
  2232. enum real L10EA = 0.5L;
  2233. enum real L10EB = -6.570551809674817234887108108339491770560299E-2L;
  2234. // Special cases are the same as for log.
  2235. if (isNaN(x))
  2236. return x;
  2237. if (isInfinity(x) && !signbit(x))
  2238. return x;
  2239. if (x == 0.0)
  2240. return -real.infinity;
  2241. if (x < 0.0)
  2242. return real.nan;
  2243. // Separate mantissa from exponent.
  2244. // Note, frexp is used so that denormal numbers will be handled properly.
  2245. real y, z;
  2246. int exp;
  2247. x = frexp(x, exp);
  2248. // Logarithm using log(x) = z + z^^3 P(z) / Q(z),
  2249. // where z = 2(x - 1)/(x + 1)
  2250. if((exp > 2) || (exp < -2))
  2251. {
  2252. if(x < SQRT1_2)
  2253. { // 2(2x - 1)/(2x + 1)
  2254. exp -= 1;
  2255. z = x - 0.5;
  2256. y = 0.5 * z + 0.5;
  2257. }
  2258. else
  2259. { // 2(x - 1)/(x + 1)
  2260. z = x - 0.5;
  2261. z -= 0.5;
  2262. y = 0.5 * x + 0.5;
  2263. }
  2264. x = z / y;
  2265. z = x * x;
  2266. y = x * (z * poly(z, R) / poly(z, S));
  2267. goto Ldone;
  2268. }
  2269. // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
  2270. if (x < SQRT1_2)
  2271. { // 2x - 1
  2272. exp -= 1;
  2273. x = ldexp(x, 1) - 1.0;
  2274. }
  2275. else
  2276. x = x - 1.0;
  2277. z = x * x;
  2278. y = x * (z * poly(x, P) / poly(x, Q));
  2279. y = y - ldexp(z, -1);
  2280. // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
  2281. // This sequence of operations is critical and it may be horribly
  2282. // defeated by some compiler optimizers.
  2283. Ldone:
  2284. z = y * L10EB;
  2285. z += x * L10EB;
  2286. z += exp * L102B;
  2287. z += y * L10EA;
  2288. z += x * L10EA;
  2289. z += exp * L102A;
  2290. return z;
  2291. }
  2292. }
  2293. unittest
  2294. {
  2295. //printf("%Lg\n", log10(1000) - 3);
  2296. assert(fabs(log10(1000) - 3) < .000001);
  2297. }
  2298. /******************************************
  2299. * Calculates the natural logarithm of 1 + x.
  2300. *
  2301. * For very small x, log1p(x) will be more accurate than
  2302. * log(1 + x).
  2303. *
  2304. * $(TABLE_SV
  2305. * $(TR $(TH x) $(TH log1p(x)) $(TH divide by 0?) $(TH invalid?))
  2306. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no) $(TD no))
  2307. * $(TR $(TD -1.0) $(TD -$(INFIN)) $(TD yes) $(TD no))
  2308. * $(TR $(TD $(LT)-1.0) $(TD $(NAN)) $(TD no) $(TD yes))
  2309. * $(TR $(TD +$(INFIN)) $(TD -$(INFIN)) $(TD no) $(TD no))
  2310. * )
  2311. */
  2312. real log1p(real x) @safe pure nothrow
  2313. {
  2314. version(INLINE_YL2X)
  2315. {
  2316. // On x87, yl2xp1 is valid if and only if -0.5 <= lg(x) <= 0.5,
  2317. // ie if -0.29<=x<=0.414
  2318. return (fabs(x) <= 0.25) ? yl2xp1(x, LN2) : yl2x(x+1, LN2);
  2319. }
  2320. else
  2321. {
  2322. // Special cases.
  2323. if (isNaN(x) || x == 0.0)
  2324. return x;
  2325. if (isInfinity(x) && !signbit(x))
  2326. return x;
  2327. if (x == -1.0)
  2328. return -real.infinity;
  2329. if (x < -1.0)
  2330. return real.nan;
  2331. return log(x + 1.0);
  2332. }
  2333. }
  2334. /***************************************
  2335. * Calculates the base-2 logarithm of x:
  2336. * $(SUB log, 2)x
  2337. *
  2338. * $(TABLE_SV
  2339. * $(TR $(TH x) $(TH log2(x)) $(TH divide by 0?) $(TH invalid?))
  2340. * $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes) $(TD no) )
  2341. * $(TR $(TD $(LT)0.0) $(TD $(NAN)) $(TD no) $(TD yes) )
  2342. * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no) )
  2343. * )
  2344. */
  2345. real log2(real x) @safe pure nothrow
  2346. {
  2347. version (INLINE_YL2X)
  2348. return yl2x(x, 1);
  2349. else
  2350. {
  2351. // Coefficients for log(1 + x)
  2352. static immutable real[7] P = [
  2353. 2.0039553499201281259648E1L,
  2354. 5.7112963590585538103336E1L,
  2355. 6.0949667980987787057556E1L,
  2356. 2.9911919328553073277375E1L,
  2357. 6.5787325942061044846969E0L,
  2358. 4.9854102823193375972212E-1L,
  2359. 4.5270000862445199635215E-5L,
  2360. ];
  2361. static immutable real[7] Q = [
  2362. 6.0118660497603843919306E1L,
  2363. 2.1642788614495947685003E2L,
  2364. 3.0909872225312059774938E2L,
  2365. 2.2176239823732856465394E2L,
  2366. 8.3047565967967209469434E1L,
  2367. 1.5062909083469192043167E1L,
  2368. 1.0000000000000000000000E0L,
  2369. ];
  2370. // Coefficients for log(x)
  2371. static immutable real[4] R = [
  2372. -3.5717684488096787370998E1L,
  2373. 1.0777257190312272158094E1L,
  2374. -7.1990767473014147232598E-1L,
  2375. 1.9757429581415468984296E-3L,
  2376. ];
  2377. static immutable real[4] S = [
  2378. -4.2861221385716144629696E2L,
  2379. 1.9361891836232102174846E2L,
  2380. -2.6201045551331104417768E1L,
  2381. 1.0000000000000000000000E0L,
  2382. ];
  2383. // Special cases are the same as for log.
  2384. if (isNaN(x))
  2385. return x;
  2386. if (isInfinity(x) && !signbit(x))
  2387. return x;
  2388. if (x == 0.0)
  2389. return -real.infinity;
  2390. if (x < 0.0)
  2391. return real.nan;
  2392. // Separate mantissa from exponent.
  2393. // Note, frexp is used so that denormal numbers will be handled properly.
  2394. real y, z;
  2395. int exp;
  2396. x = frexp(x, exp);
  2397. // Logarithm using log(x) = z + z^^3 P(z) / Q(z),
  2398. // where z = 2(x - 1)/(x + 1)
  2399. if((exp > 2) || (exp < -2))
  2400. {
  2401. if(x < SQRT1_2)
  2402. { // 2(2x - 1)/(2x + 1)
  2403. exp -= 1;
  2404. z = x - 0.5;
  2405. y = 0.5 * z + 0.5;
  2406. }
  2407. else
  2408. { // 2(x - 1)/(x + 1)
  2409. z = x - 0.5;
  2410. z -= 0.5;
  2411. y = 0.5 * x + 0.5;
  2412. }
  2413. x = z / y;
  2414. z = x * x;
  2415. y = x * (z * poly(z, R) / poly(z, S));
  2416. goto Ldone;
  2417. }
  2418. // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x)
  2419. if (x < SQRT1_2)
  2420. { // 2x - 1
  2421. exp -= 1;
  2422. x = ldexp(x, 1) - 1.0;
  2423. }
  2424. else
  2425. x = x - 1.0;
  2426. z = x * x;
  2427. y = x * (z * poly(x, P) / poly(x, Q));
  2428. y = y - ldexp(z, -1);
  2429. // Multiply log of fraction by log10(e) and base 2 exponent by log10(2).
  2430. // This sequence of operations is critical and it may be horribly
  2431. // defeated by some compiler optimizers.
  2432. Ldone:
  2433. z = y * (LOG2E - 1.0);
  2434. z += x * (LOG2E - 1.0);
  2435. z += y;
  2436. z += x;
  2437. z += exp;
  2438. return z;
  2439. }
  2440. }
  2441. unittest
  2442. {
  2443. assert(equalsDigit(log2(1024), 10, 19));
  2444. }
  2445. /*****************************************
  2446. * Extracts the exponent of x as a signed integral value.
  2447. *
  2448. * If x is subnormal, it is treated as if it were normalized.
  2449. * For a positive, finite x:
  2450. *
  2451. * 1 $(LT)= $(I x) * FLT_RADIX$(SUP -logb(x)) $(LT) FLT_RADIX
  2452. *
  2453. * $(TABLE_SV
  2454. * $(TR $(TH x) $(TH logb(x)) $(TH divide by 0?) )
  2455. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) $(TD no))
  2456. * $(TR $(TD $(PLUSMN)0.0) $(TD -$(INFIN)) $(TD yes) )
  2457. * )
  2458. */
  2459. real logb(real x) @trusted nothrow
  2460. {
  2461. version (Win64)
  2462. {
  2463. asm
  2464. {
  2465. naked ;
  2466. fld real ptr [RCX] ;
  2467. fxtract ;
  2468. fstp ST(0) ;
  2469. ret ;
  2470. }
  2471. }
  2472. else
  2473. return core.stdc.math.logbl(x);
  2474. }
  2475. /************************************
  2476. * Calculates the remainder from the calculation x/y.
  2477. * Returns:
  2478. * The value of x - i * y, where i is the number of times that y can
  2479. * be completely subtracted from x. The result has the same sign as x.
  2480. *
  2481. * $(TABLE_SV
  2482. * $(TR $(TH x) $(TH y) $(TH fmod(x, y)) $(TH invalid?))
  2483. * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD no))
  2484. * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(NAN)) $(TD yes))
  2485. * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(NAN)) $(TD yes))
  2486. * $(TR $(TD !=$(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD no))
  2487. * )
  2488. */
  2489. real fmod(real x, real y) @trusted nothrow
  2490. {
  2491. version (Win64)
  2492. {
  2493. return x % y;
  2494. }
  2495. else
  2496. return core.stdc.math.fmodl(x, y);
  2497. }
  2498. /************************************
  2499. * Breaks x into an integral part and a fractional part, each of which has
  2500. * the same sign as x. The integral part is stored in i.
  2501. * Returns:
  2502. * The fractional part of x.
  2503. *
  2504. * $(TABLE_SV
  2505. * $(TR $(TH x) $(TH i (on input)) $(TH modf(x, i)) $(TH i (on return)))
  2506. * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(PLUSMNINF)))
  2507. * )
  2508. */
  2509. real modf(real x, ref real i) @trusted nothrow
  2510. {
  2511. version (Win64)
  2512. {
  2513. i = trunc(x);
  2514. return copysign(isInfinity(x) ? 0.0 : x - i, x);
  2515. }
  2516. else
  2517. return core.stdc.math.modfl(x,&i);
  2518. }
  2519. /*************************************
  2520. * Efficiently calculates x * 2$(SUP n).
  2521. *
  2522. * scalbn handles underflow and overflow in
  2523. * the same fashion as the basic arithmetic operators.
  2524. *
  2525. * $(TABLE_SV
  2526. * $(TR $(TH x) $(TH scalb(x)))
  2527. * $(TR $(TD $(PLUSMNINF)) $(TD $(PLUSMNINF)) )
  2528. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) )
  2529. * )
  2530. */
  2531. real scalbn(real x, int n) @trusted nothrow
  2532. {
  2533. version(InlineAsm_X86_Any) {
  2534. // scalbnl is not supported on DMD-Windows, so use asm.
  2535. version (Win64)
  2536. {
  2537. asm {
  2538. naked ;
  2539. mov 16[RSP],RCX ;
  2540. fild word ptr 16[RSP] ;
  2541. fld real ptr [RDX] ;
  2542. fscale ;
  2543. fstp ST(1) ;
  2544. ret ;
  2545. }
  2546. }
  2547. else
  2548. {
  2549. asm {
  2550. fild n;
  2551. fld x;
  2552. fscale;
  2553. fstp ST(1);
  2554. }
  2555. }
  2556. }
  2557. else
  2558. {
  2559. return core.stdc.math.scalbnl(x, n);
  2560. }
  2561. }
  2562. unittest
  2563. {
  2564. assert(scalbn(-real.infinity, 5) == -real.infinity);
  2565. }
  2566. /***************
  2567. * Calculates the cube root of x.
  2568. *
  2569. * $(TABLE_SV
  2570. * $(TR $(TH $(I x)) $(TH cbrt(x)) $(TH invalid?))
  2571. * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no) )
  2572. * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes) )
  2573. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD $(PLUSMN)$(INFIN)) $(TD no) )
  2574. * )
  2575. */
  2576. real cbrt(real x) @trusted nothrow
  2577. {
  2578. version (Win64)
  2579. {
  2580. return copysign(exp2(yl2x(fabs(x), 1.0L/3.0L)), x);
  2581. }
  2582. else
  2583. return core.stdc.math.cbrtl(x);
  2584. }
  2585. /*******************************
  2586. * Returns |x|
  2587. *
  2588. * $(TABLE_SV
  2589. * $(TR $(TH x) $(TH fabs(x)))
  2590. * $(TR $(TD $(PLUSMN)0.0) $(TD +0.0) )
  2591. * $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )
  2592. * )
  2593. */
  2594. real fabs(real x) @safe pure nothrow; /* intrinsic */
  2595. /***********************************************************************
  2596. * Calculates the length of the
  2597. * hypotenuse of a right-angled triangle with sides of length x and y.
  2598. * The hypotenuse is the value of the square root of
  2599. * the sums of the squares of x and y:
  2600. *
  2601. * sqrt($(POWER x, 2) + $(POWER y, 2))
  2602. *
  2603. * Note that hypot(x, y), hypot(y, x) and
  2604. * hypot(x, -y) are equivalent.
  2605. *
  2606. * $(TABLE_SV
  2607. * $(TR $(TH x) $(TH y) $(TH hypot(x, y)) $(TH invalid?))
  2608. * $(TR $(TD x) $(TD $(PLUSMN)0.0) $(TD |x|) $(TD no))
  2609. * $(TR $(TD $(PLUSMNINF)) $(TD y) $(TD +$(INFIN)) $(TD no))
  2610. * $(TR $(TD $(PLUSMNINF)) $(TD $(NAN)) $(TD +$(INFIN)) $(TD no))
  2611. * )
  2612. */
  2613. real hypot(real x, real y) @safe pure nothrow
  2614. {
  2615. // Scale x and y to avoid underflow and overflow.
  2616. // If one is huge and the other tiny, return the larger.
  2617. // If both are huge, avoid overflow by scaling by 1/sqrt(real.max/2).
  2618. // If both are tiny, avoid underflow by scaling by sqrt(real.min_normal*real.epsilon).
  2619. enum real SQRTMIN = 0.5 * sqrt(real.min_normal); // This is a power of 2.
  2620. enum real SQRTMAX = 1.0L / SQRTMIN; // 2^^((max_exp)/2) = nextUp(sqrt(real.max))
  2621. static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
  2622. // Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
  2623. static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
  2624. real u = fabs(x);
  2625. real v = fabs(y);
  2626. if (!(u >= v)) // check for NaN as well.
  2627. {
  2628. v = u;
  2629. u = fabs(y);
  2630. if (u == real.infinity) return u; // hypot(inf, nan) == inf
  2631. if (v == real.infinity) return v; // hypot(nan, inf) == inf
  2632. }
  2633. // Now u >= v, or else one is NaN.
  2634. if (v >= SQRTMAX*0.5)
  2635. {
  2636. // hypot(huge, huge) -- avoid overflow
  2637. u *= SQRTMIN*0.5;
  2638. v *= SQRTMIN*0.5;
  2639. return sqrt(u*u + v*v) * SQRTMAX * 2.0;
  2640. }
  2641. if (u <= SQRTMIN)
  2642. {
  2643. // hypot (tiny, tiny) -- avoid underflow
  2644. // This is only necessary to avoid setting the underflow
  2645. // flag.
  2646. u *= SQRTMAX / real.epsilon;
  2647. v *= SQRTMAX / real.epsilon;
  2648. return sqrt(u*u + v*v) * SQRTMIN * real.epsilon;
  2649. }
  2650. if (u * real.epsilon > v)
  2651. {
  2652. // hypot (huge, tiny) = huge
  2653. return u;
  2654. }
  2655. // both are in the normal range
  2656. return sqrt(u*u + v*v);
  2657. }
  2658. unittest
  2659. {
  2660. static real[3][] vals = // x,y,hypot
  2661. [
  2662. [ 0.0, 0.0, 0.0],
  2663. [ 0.0, -0.0, 0.0],
  2664. [ -0.0, -0.0, 0.0],
  2665. [ 3.0, 4.0, 5.0],
  2666. [ -300, -400, 500],
  2667. [0.0, 7.0, 7.0],
  2668. [9.0, 9*real.epsilon, 9.0],
  2669. [88/(64*sqrt(real.min_normal)), 105/(64*sqrt(real.min_normal)), 137/(64*sqrt(real.min_normal))],
  2670. [88/(128*sqrt(real.min_normal)), 105/(128*sqrt(real.min_normal)), 137/(128*sqrt(real.min_normal))],
  2671. [3*real.min_normal*real.epsilon, 4*real.min_normal*real.epsilon, 5*real.min_normal*real.epsilon],
  2672. [ real.min_normal, real.min_normal, sqrt(2.0L)*real.min_normal],
  2673. [ real.max/sqrt(2.0L), real.max/sqrt(2.0L), real.max],
  2674. [ real.infinity, real.nan, real.infinity],
  2675. [ real.nan, real.infinity, real.infinity],
  2676. [ real.nan, real.nan, real.nan],
  2677. [ real.nan, real.max, real.nan],
  2678. [ real.max, real.nan, real.nan],
  2679. ];
  2680. for (int i = 0; i < vals.length; i++)
  2681. {
  2682. real x = vals[i][0];
  2683. real y = vals[i][1];
  2684. real z = vals[i][2];
  2685. real h = hypot(x, y);
  2686. assert(isIdentical(z, h));
  2687. }
  2688. }
  2689. /**************************************
  2690. * Returns the value of x rounded upward to the next integer
  2691. * (toward positive infinity).
  2692. */
  2693. real ceil(real x) @trusted pure nothrow
  2694. {
  2695. version (Win64)
  2696. {
  2697. asm
  2698. {
  2699. naked ;
  2700. fld real ptr [RCX] ;
  2701. fstcw 8[RSP] ;
  2702. mov AL,9[RSP] ;
  2703. mov DL,AL ;
  2704. and AL,0xC3 ;
  2705. or AL,0x08 ; // round to +infinity
  2706. mov 9[RSP],AL ;
  2707. fldcw 8[RSP] ;
  2708. frndint ;
  2709. mov 9[RSP],DL ;
  2710. fldcw 8[RSP] ;
  2711. ret ;
  2712. }
  2713. }
  2714. else
  2715. {
  2716. // Special cases.
  2717. if (isNaN(x) || isInfinity(x))
  2718. return x;
  2719. real y = floor(x);
  2720. if (y < x)
  2721. y += 1.0;
  2722. return y;
  2723. }
  2724. }
  2725. unittest
  2726. {
  2727. assert(ceil(+123.456) == +124);
  2728. assert(ceil(-123.456) == -123);
  2729. assert(ceil(-1.234) == -1);
  2730. assert(ceil(-0.123) == 0);
  2731. assert(ceil(0.0) == 0);
  2732. assert(ceil(+0.123) == 1);
  2733. assert(ceil(+1.234) == 2);
  2734. assert(ceil(real.infinity) == real.infinity);
  2735. assert(isNaN(ceil(real.nan)));
  2736. assert(isNaN(ceil(real.init)));
  2737. }
  2738. /**************************************
  2739. * Returns the value of x rounded downward to the next integer
  2740. * (toward negative infinity).
  2741. */
  2742. real floor(real x) @trusted pure nothrow
  2743. {
  2744. version (Win64)
  2745. {
  2746. asm
  2747. {
  2748. naked ;
  2749. fld real ptr [RCX] ;
  2750. fstcw 8[RSP] ;
  2751. mov AL,9[RSP] ;
  2752. mov DL,AL ;
  2753. and AL,0xC3 ;
  2754. or AL,0x04 ; // round to -infinity
  2755. mov 9[RSP],AL ;
  2756. fldcw 8[RSP] ;
  2757. frndint ;
  2758. mov 9[RSP],DL ;
  2759. fldcw 8[RSP] ;
  2760. ret ;
  2761. }
  2762. }
  2763. else
  2764. {
  2765. // Bit clearing masks.
  2766. static immutable ushort[17] BMASK = [
  2767. 0xffff, 0xfffe, 0xfffc, 0xfff8,
  2768. 0xfff0, 0xffe0, 0xffc0, 0xff80,
  2769. 0xff00, 0xfe00, 0xfc00, 0xf800,
  2770. 0xf000, 0xe000, 0xc000, 0x8000,
  2771. 0x0000,
  2772. ];
  2773. // Special cases.
  2774. if (isNaN(x) || isInfinity(x) || x == 0.0)
  2775. return x;
  2776. alias floatTraits!(real) F;
  2777. auto vu = *cast(ushort[real.sizeof/2]*)(&x);
  2778. // Find the exponent (power of 2)
  2779. static if (real.mant_dig == 53)
  2780. {
  2781. int exp = ((vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
  2782. version (LittleEndian)
  2783. int pos = 0;
  2784. else
  2785. int pos = 3;
  2786. }
  2787. else static if (real.mant_dig == 64)
  2788. {
  2789. int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
  2790. version (LittleEndian)
  2791. int pos = 0;
  2792. else
  2793. int pos = 4;
  2794. }
  2795. else if (real.mant_dig == 113)
  2796. {
  2797. int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
  2798. version (LittleEndian)
  2799. int pos = 0;
  2800. else
  2801. int pos = 7;
  2802. }
  2803. else
  2804. static assert(false, "Only 64-bit, 80-bit, and 128-bit reals are supported by floor()");
  2805. if (exp < 0)
  2806. {
  2807. if (x < 0.0)
  2808. return -1.0;
  2809. else
  2810. return 0.0;
  2811. }
  2812. exp = (real.mant_dig - 1) - exp;
  2813. // Clean out 16 bits at a time.
  2814. while (exp >= 16)
  2815. {
  2816. version (LittleEndian)
  2817. vu[pos++] = 0;
  2818. else
  2819. vu[pos--] = 0;
  2820. exp -= 16;
  2821. }
  2822. // Clear the remaining bits.
  2823. if (exp > 0)
  2824. vu[pos] &= BMASK[exp];
  2825. real y = *cast(real*)(&vu);
  2826. if ((x < 0.0) && (x != y))
  2827. y -= 1.0;
  2828. return y;
  2829. }
  2830. }
  2831. unittest
  2832. {
  2833. assert(floor(+123.456) == +123);
  2834. assert(floor(-123.456) == -124);
  2835. assert(floor(-1.234) == -2);
  2836. assert(floor(-0.123) == -1);
  2837. assert(floor(0.0) == 0);
  2838. assert(floor(+0.123) == 0);
  2839. assert(floor(+1.234) == 1);
  2840. assert(floor(real.infinity) == real.infinity);
  2841. assert(isNaN(floor(real.nan)));
  2842. assert(isNaN(floor(real.init)));
  2843. }
  2844. /******************************************
  2845. * Rounds x to the nearest integer value, using the current rounding
  2846. * mode.
  2847. *
  2848. * Unlike the rint functions, nearbyint does not raise the
  2849. * FE_INEXACT exception.
  2850. */
  2851. real nearbyint(real x) @trusted nothrow
  2852. {
  2853. version (Win64)
  2854. {
  2855. assert(0); // not implemented in C library
  2856. }
  2857. else
  2858. return core.stdc.math.nearbyintl(x);
  2859. }
  2860. /**********************************
  2861. * Rounds x to the nearest integer value, using the current rounding
  2862. * mode.
  2863. * If the return value is not equal to x, the FE_INEXACT
  2864. * exception is raised.
  2865. * $(B nearbyint) performs
  2866. * the same operation, but does not set the FE_INEXACT exception.
  2867. */
  2868. real rint(real x) @safe pure nothrow; /* intrinsic */
  2869. /***************************************
  2870. * Rounds x to the nearest integer value, using the current rounding
  2871. * mode.
  2872. *
  2873. * This is generally the fastest method to convert a floating-point number
  2874. * to an integer. Note that the results from this function
  2875. * depend on the rounding mode, if the fractional part of x is exactly 0.5.
  2876. * If using the default rounding mode (ties round to even integers)
  2877. * lrint(4.5) == 4, lrint(5.5)==6.
  2878. */
  2879. long lrint(real x) @trusted pure nothrow
  2880. {
  2881. version(InlineAsm_X86_Any)
  2882. {
  2883. version (Win64)
  2884. {
  2885. asm
  2886. {
  2887. naked;
  2888. fld real ptr [RCX];
  2889. fistp 8[RSP];
  2890. mov RAX,8[RSP];
  2891. ret;
  2892. }
  2893. }
  2894. else
  2895. {
  2896. long n;
  2897. asm
  2898. {
  2899. fld x;
  2900. fistp n;
  2901. }
  2902. return n;
  2903. }
  2904. }
  2905. else
  2906. {
  2907. static if (real.mant_dig == 53)
  2908. {
  2909. long result;
  2910. // Rounding limit when casting from real(double) to ulong.
  2911. enum real OF = 4.50359962737049600000E15L;
  2912. uint* vi = cast(uint*)(&x);
  2913. // Find the exponent and sign
  2914. uint msb = vi[MANTISSA_MSB];
  2915. uint lsb = vi[MANTISSA_LSB];
  2916. int exp = ((msb >> 20) & 0x7ff) - 0x3ff;
  2917. int sign = msb >> 31;
  2918. msb &= 0xfffff;
  2919. msb |= 0x100000;
  2920. if (exp < 63)
  2921. {
  2922. if (exp >= 52)
  2923. result = (cast(long) msb << (exp - 20)) | (lsb << (exp - 52));
  2924. else
  2925. {
  2926. // Adjust x and check result.
  2927. real j = sign ? -OF : OF;
  2928. x = (j + x) - j;
  2929. msb = vi[MANTISSA_MSB];
  2930. lsb = vi[MANTISSA_LSB];
  2931. exp = ((msb >> 20) & 0x7ff) - 0x3ff;
  2932. msb &= 0xfffff;
  2933. msb |= 0x100000;
  2934. if (exp < 0)
  2935. result = 0;
  2936. else if (exp < 20)
  2937. result = cast(long) msb >> (20 - exp);
  2938. else if (exp == 20)
  2939. result = cast(long) msb;
  2940. else
  2941. result = (cast(long) msb << (exp - 20)) | (lsb >> (52 - exp));
  2942. }
  2943. }
  2944. else
  2945. {
  2946. // It is left implementation defined when the number is too large.
  2947. return cast(long) x;
  2948. }
  2949. return sign ? -result : result;
  2950. }
  2951. else static if (real.mant_dig == 64)
  2952. {
  2953. alias floatTraits!(real) F;
  2954. long result;
  2955. // Rounding limit when casting from real(80-bit) to ulong.
  2956. enum real OF = 9.22337203685477580800E18L;
  2957. ushort* vu = cast(ushort*)(&x);
  2958. uint* vi = cast(uint*)(&x);
  2959. // Find the exponent and sign
  2960. int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
  2961. int sign = (vu[F.EXPPOS_SHORT] >> 15) & 1;
  2962. if (exp < 63)
  2963. {
  2964. // Adjust x and check result.
  2965. real j = sign ? -OF : OF;
  2966. x = (j + x) - j;
  2967. exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
  2968. version (LittleEndian)
  2969. {
  2970. if (exp < 0)
  2971. result = 0;
  2972. else if (exp <= 31)
  2973. result = vi[1] >> (31 - exp);
  2974. else
  2975. result = (cast(long) vi[1] << (exp - 31)) | (vi[0] >> (63 - exp));
  2976. }
  2977. else
  2978. {
  2979. if (exp < 0)
  2980. result = 0;
  2981. else if (exp <= 31)
  2982. result = vi[1] >> (31 - exp);
  2983. else
  2984. result = (cast(long) vi[1] << (exp - 31)) | (vi[2] >> (63 - exp));
  2985. }
  2986. }
  2987. else
  2988. {
  2989. // It is left implementation defined when the number is too large
  2990. // to fit in a 64bit long.
  2991. return cast(long) x;
  2992. }
  2993. return sign ? -result : result;
  2994. }
  2995. else
  2996. {
  2997. static assert(false, "Only 64-bit and 80-bit reals are supported by lrint()");
  2998. }
  2999. }
  3000. }
  3001. unittest
  3002. {
  3003. assert(lrint(4.5) == 4);
  3004. assert(lrint(5.5) == 6);
  3005. assert(lrint(-4.5) == -4);
  3006. assert(lrint(-5.5) == -6);
  3007. assert(lrint(int.max - 0.5) == 2147483646L);
  3008. assert(lrint(int.max + 0.5) == 2147483648L);
  3009. assert(lrint(int.min - 0.5) == -2147483648L);
  3010. assert(lrint(int.min + 0.5) == -2147483648L);
  3011. }
  3012. /*******************************************
  3013. * Return the value of x rounded to the nearest integer.
  3014. * If the fractional part of x is exactly 0.5, the return value is rounded to
  3015. * the even integer.
  3016. */
  3017. real round(real x) @trusted nothrow
  3018. {
  3019. version (Win64)
  3020. {
  3021. auto old = FloatingPointControl.getControlState();
  3022. FloatingPointControl.setControlState((old & ~FloatingPointControl.ROUNDING_MASK) | FloatingPointControl.roundToZero);
  3023. x = rint((x >= 0) ? x + 0.5 : x - 0.5);
  3024. FloatingPointControl.setControlState(old);
  3025. return x;
  3026. }
  3027. else
  3028. return core.stdc.math.roundl(x);
  3029. }
  3030. /**********************************************
  3031. * Return the value of x rounded to the nearest integer.
  3032. *
  3033. * If the fractional part of x is exactly 0.5, the return value is rounded
  3034. * away from zero.
  3035. */
  3036. long lround(real x) @trusted nothrow
  3037. {
  3038. version (Posix)
  3039. return core.stdc.math.llroundl(x);
  3040. else
  3041. assert (0, "lround not implemented");
  3042. }
  3043. version(Posix)
  3044. {
  3045. unittest
  3046. {
  3047. assert(lround(0.49) == 0);
  3048. assert(lround(0.5) == 1);
  3049. assert(lround(1.5) == 2);
  3050. }
  3051. }
  3052. /****************************************************
  3053. * Returns the integer portion of x, dropping the fractional portion.
  3054. *
  3055. * This is also known as "chop" rounding.
  3056. */
  3057. real trunc(real x) @trusted nothrow
  3058. {
  3059. version (Win64)
  3060. {
  3061. asm
  3062. {
  3063. naked ;
  3064. fld real ptr [RCX] ;
  3065. fstcw 8[RSP] ;
  3066. mov AL,9[RSP] ;
  3067. mov DL,AL ;
  3068. and AL,0xC3 ;
  3069. or AL,0x0C ; // round to 0
  3070. mov 9[RSP],AL ;
  3071. fldcw 8[RSP] ;
  3072. frndint ;
  3073. mov 9[RSP],DL ;
  3074. fldcw 8[RSP] ;
  3075. ret ;
  3076. }
  3077. }
  3078. else
  3079. return core.stdc.math.truncl(x);
  3080. }
  3081. /****************************************************
  3082. * Calculate the remainder x REM y, following IEC 60559.
  3083. *
  3084. * REM is the value of x - y * n, where n is the integer nearest the exact
  3085. * value of x / y.
  3086. * If |n - x / y| == 0.5, n is even.
  3087. * If the result is zero, it has the same sign as x.
  3088. * Otherwise, the sign of the result is the sign of x / y.
  3089. * Precision mode has no effect on the remainder functions.
  3090. *
  3091. * remquo returns n in the parameter n.
  3092. *
  3093. * $(TABLE_SV
  3094. * $(TR $(TH x) $(TH y) $(TH remainder(x, y)) $(TH n) $(TH invalid?))
  3095. * $(TR $(TD $(PLUSMN)0.0) $(TD not 0.0) $(TD $(PLUSMN)0.0) $(TD 0.0) $(TD no))
  3096. * $(TR $(TD $(PLUSMNINF)) $(TD anything) $(TD $(NAN)) $(TD ?) $(TD yes))
  3097. * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD $(NAN)) $(TD ?) $(TD yes))
  3098. * $(TR $(TD != $(PLUSMNINF)) $(TD $(PLUSMNINF)) $(TD x) $(TD ?) $(TD no))
  3099. * )
  3100. *
  3101. * Note: remquo not supported on windows
  3102. */
  3103. real remainder(real x, real y) @trusted nothrow
  3104. {
  3105. version (Win64)
  3106. {
  3107. int n;
  3108. return remquo(x, y, n);
  3109. }
  3110. else
  3111. return core.stdc.math.remainderl(x, y);
  3112. }
  3113. real remquo(real x, real y, out int n) @trusted nothrow /// ditto
  3114. {
  3115. version (Posix)
  3116. return core.stdc.math.remquol(x, y, &n);
  3117. else
  3118. assert (0, "remquo not implemented");
  3119. }
  3120. /** IEEE exception status flags ('sticky bits')
  3121. These flags indicate that an exceptional floating-point condition has occurred.
  3122. They indicate that a NaN or an infinity has been generated, that a result
  3123. is inexact, or that a signalling NaN has been encountered. If floating-point
  3124. exceptions are enabled (unmasked), a hardware exception will be generated
  3125. instead of setting these flags.
  3126. Example:
  3127. ----
  3128. real a=3.5;
  3129. // Set all the flags to zero
  3130. resetIeeeFlags();
  3131. assert(!ieeeFlags.divByZero);
  3132. // Perform a division by zero.
  3133. a/=0.0L;
  3134. assert(a==real.infinity);
  3135. assert(ieeeFlags.divByZero);
  3136. // Create a NaN
  3137. a*=0.0L;
  3138. assert(ieeeFlags.invalid);
  3139. assert(isNaN(a));
  3140. // Check that calling func() has no effect on the
  3141. // status flags.
  3142. IeeeFlags f = ieeeFlags;
  3143. func();
  3144. assert(ieeeFlags == f);
  3145. ----
  3146. */
  3147. struct IeeeFlags
  3148. {
  3149. private:
  3150. // The x87 FPU status register is 16 bits.
  3151. // The Pentium SSE2 status register is 32 bits.
  3152. uint flags;
  3153. version (X86_Any)
  3154. {
  3155. // Applies to both x87 status word (16 bits) and SSE2 status word(32 bits).
  3156. enum : int
  3157. {
  3158. INEXACT_MASK = 0x20,
  3159. UNDERFLOW_MASK = 0x10,
  3160. OVERFLOW_MASK = 0x08,
  3161. DIVBYZERO_MASK = 0x04,
  3162. INVALID_MASK = 0x01
  3163. }
  3164. // Don't bother about subnormals, they are not supported on most CPUs.
  3165. // SUBNORMAL_MASK = 0x02;
  3166. }
  3167. else version (PPC)
  3168. {
  3169. // PowerPC FPSCR is a 32-bit register.
  3170. enum : int
  3171. {
  3172. INEXACT_MASK = 0x600,
  3173. UNDERFLOW_MASK = 0x010,
  3174. OVERFLOW_MASK = 0x008,
  3175. DIVBYZERO_MASK = 0x020,
  3176. INVALID_MASK = 0xF80 // PowerPC has five types of invalid exceptions.
  3177. }
  3178. }
  3179. else version (PPC64)
  3180. {
  3181. // PowerPC FPSCR is a 32-bit register.
  3182. enum : int
  3183. {
  3184. INEXACT_MASK = 0x600,
  3185. UNDERFLOW_MASK = 0x010,
  3186. OVERFLOW_MASK = 0x008,
  3187. DIVBYZERO_MASK = 0x020,
  3188. INVALID_MASK = 0xF80 // PowerPC has five types of invalid exceptions.
  3189. }
  3190. }
  3191. else version (ARM)
  3192. {
  3193. // TODO: Fill this in for VFP.
  3194. }
  3195. else version(SPARC)
  3196. {
  3197. // SPARC FSR is a 32bit register
  3198. //(64 bits for Sparc 7 & 8, but high 32 bits are uninteresting).
  3199. enum : int
  3200. {
  3201. INEXACT_MASK = 0x020,
  3202. UNDERFLOW_MASK = 0x080,
  3203. OVERFLOW_MASK = 0x100,
  3204. DIVBYZERO_MASK = 0x040,
  3205. INVALID_MASK = 0x200
  3206. }
  3207. }
  3208. else
  3209. static assert(0, "Not implemented");
  3210. private:
  3211. static uint getIeeeFlags()
  3212. {
  3213. version(D_InlineAsm_X86)
  3214. {
  3215. asm
  3216. {
  3217. fstsw AX;
  3218. // NOTE: If compiler supports SSE2, need to OR the result with
  3219. // the SSE2 status register.
  3220. // Clear all irrelevant bits
  3221. and EAX, 0x03D;
  3222. }
  3223. }
  3224. else version(D_InlineAsm_X86_64)
  3225. {
  3226. asm
  3227. {
  3228. fstsw AX;
  3229. // NOTE: If compiler supports SSE2, need to OR the result with
  3230. // the SSE2 status register.
  3231. // Clear all irrelevant bits
  3232. and RAX, 0x03D;
  3233. }
  3234. }
  3235. else version (SPARC)
  3236. {
  3237. /*
  3238. int retval;
  3239. asm { st %fsr, retval; }
  3240. return retval;
  3241. */
  3242. assert(0, "Not yet supported");
  3243. }
  3244. else version (ARM)
  3245. {
  3246. assert(false, "Not yet supported.");
  3247. }
  3248. else
  3249. assert(0, "Not yet supported");
  3250. }
  3251. static void resetIeeeFlags()
  3252. {
  3253. version(InlineAsm_X86_Any)
  3254. {
  3255. asm
  3256. {
  3257. fnclex;
  3258. }
  3259. }
  3260. else
  3261. {
  3262. /* SPARC:
  3263. int tmpval;
  3264. asm { st %fsr, tmpval; }
  3265. tmpval &=0xFFFF_FC00;
  3266. asm { ld tmpval, %fsr; }
  3267. */
  3268. assert(0, "Not yet supported");
  3269. }
  3270. }
  3271. public:
  3272. version (X86_Any) { // TODO: Lift this version condition when we support !x86.
  3273. /// The result cannot be represented exactly, so rounding occured.
  3274. /// (example: x = sin(0.1); )
  3275. @property bool inexact() { return (flags & INEXACT_MASK) != 0; }
  3276. /// A zero was generated by underflow (example: x = real.min*real.epsilon/2;)
  3277. @property bool underflow() { return (flags & UNDERFLOW_MASK) != 0; }
  3278. /// An infinity was generated by overflow (example: x = real.max*2;)
  3279. @property bool overflow() { return (flags & OVERFLOW_MASK) != 0; }
  3280. /// An infinity was generated by division by zero (example: x = 3/0.0; )
  3281. @property bool divByZero() { return (flags & DIVBYZERO_MASK) != 0; }
  3282. /// A machine NaN was generated. (example: x = real.infinity * 0.0; )
  3283. @property bool invalid() { return (flags & INVALID_MASK) != 0; }
  3284. }
  3285. }
  3286. /// Set all of the floating-point status flags to false.
  3287. void resetIeeeFlags() { IeeeFlags.resetIeeeFlags(); }
  3288. /// Return a snapshot of the current state of the floating-point status flags.
  3289. @property IeeeFlags ieeeFlags()
  3290. {
  3291. return IeeeFlags(IeeeFlags.getIeeeFlags());
  3292. }
  3293. /** Control the Floating point hardware
  3294. Change the IEEE754 floating-point rounding mode and the floating-point
  3295. hardware exceptions.
  3296. By default, the rounding mode is roundToNearest and all hardware exceptions
  3297. are disabled. For most applications, debugging is easier if the $(I division
  3298. by zero), $(I overflow), and $(I invalid operation) exceptions are enabled.
  3299. These three are combined into a $(I severeExceptions) value for convenience.
  3300. Note in particular that if $(I invalidException) is enabled, a hardware trap
  3301. will be generated whenever an uninitialized floating-point variable is used.
  3302. All changes are temporary. The previous state is restored at the
  3303. end of the scope.
  3304. Example:
  3305. ----
  3306. {
  3307. FloatingPointControl fpctrl;
  3308. // Enable hardware exceptions for division by zero, overflow to infinity,
  3309. // invalid operations, and uninitialized floating-point variables.
  3310. fpctrl.enableExceptions(FloatingPointControl.severeExceptions);
  3311. // This will generate a hardware exception, if x is a
  3312. // default-initialized floating point variable:
  3313. real x; // Add `= 0` or even `= real.nan` to not throw the exception.
  3314. real y = x * 3.0;
  3315. // The exception is only thrown for default-uninitialized NaN-s.
  3316. // NaN-s with other payload are valid:
  3317. real z = y * real.nan; // ok
  3318. // Changing the rounding mode:
  3319. fpctrl.rounding = FloatingPointControl.roundUp;
  3320. assert(rint(1.1) == 2);
  3321. // The set hardware exceptions will be disabled when leaving this scope.
  3322. // The original rounding mode will also be restored.
  3323. }
  3324. // Ensure previous values are returned:
  3325. assert(!FloatingPointControl.enabledExceptions);
  3326. assert(FloatingPointControl.rounding == FloatingPointControl.roundToNearest);
  3327. assert(rint(1.1) == 1);
  3328. ----
  3329. */
  3330. struct FloatingPointControl
  3331. {
  3332. alias uint RoundingMode;
  3333. /** IEEE rounding modes.
  3334. * The default mode is roundToNearest.
  3335. */
  3336. enum : RoundingMode
  3337. {
  3338. roundToNearest = 0x0000,
  3339. roundDown = 0x0400,
  3340. roundUp = 0x0800,
  3341. roundToZero = 0x0C00
  3342. }
  3343. /** IEEE hardware exceptions.
  3344. * By default, all exceptions are masked (disabled).
  3345. */
  3346. enum : uint
  3347. {
  3348. inexactException = 0x20,
  3349. underflowException = 0x10,
  3350. overflowException = 0x08,
  3351. divByZeroException = 0x04,
  3352. subnormalException = 0x02,
  3353. invalidException = 0x01,
  3354. /// Severe = The overflow, division by zero, and invalid exceptions.
  3355. severeExceptions = overflowException | divByZeroException
  3356. | invalidException,
  3357. allExceptions = severeExceptions | underflowException
  3358. | inexactException | subnormalException,
  3359. }
  3360. private:
  3361. enum ushort EXCEPTION_MASK = 0x3F;
  3362. enum ushort ROUNDING_MASK = 0xC00;
  3363. public:
  3364. /// Enable (unmask) specific hardware exceptions. Multiple exceptions may be ORed together.
  3365. void enableExceptions(uint exceptions)
  3366. {
  3367. initialize();
  3368. setControlState(getControlState() & ~(exceptions & EXCEPTION_MASK));
  3369. }
  3370. /// Disable (mask) specific hardware exceptions. Multiple exceptions may be ORed together.
  3371. void disableExceptions(uint exceptions)
  3372. {
  3373. initialize();
  3374. setControlState(getControlState() | (exceptions & EXCEPTION_MASK));
  3375. }
  3376. //// Change the floating-point hardware rounding mode
  3377. @property void rounding(RoundingMode newMode)
  3378. {
  3379. initialize();
  3380. setControlState((getControlState() & ~ROUNDING_MASK) | (newMode & ROUNDING_MASK));
  3381. }
  3382. /// Return the exceptions which are currently enabled (unmasked)
  3383. @property static uint enabledExceptions()
  3384. {
  3385. return (getControlState() & EXCEPTION_MASK) ^ EXCEPTION_MASK;
  3386. }
  3387. /// Return the currently active rounding mode
  3388. @property static RoundingMode rounding()
  3389. {
  3390. return cast(RoundingMode)(getControlState() & ROUNDING_MASK);
  3391. }
  3392. /// Clear all pending exceptions, then restore the original exception state and rounding mode.
  3393. ~this()
  3394. {
  3395. clearExceptions();
  3396. if (initialized)
  3397. setControlState(savedState);
  3398. }
  3399. private:
  3400. ushort savedState;
  3401. bool initialized = false;
  3402. void initialize()
  3403. {
  3404. // BUG: This works around the absence of this() constructors.
  3405. if (initialized) return;
  3406. clearExceptions();
  3407. savedState = getControlState();
  3408. initialized = true;
  3409. }
  3410. // Clear all pending exceptions
  3411. static void clearExceptions()
  3412. {
  3413. version (InlineAsm_X86_Any)
  3414. {
  3415. asm
  3416. {
  3417. fclex;
  3418. }
  3419. }
  3420. else
  3421. assert(0, "Not yet supported");
  3422. }
  3423. // Read from the control register
  3424. static ushort getControlState() @trusted nothrow
  3425. {
  3426. version (D_InlineAsm_X86)
  3427. {
  3428. short cont;
  3429. asm
  3430. {
  3431. xor EAX, EAX;
  3432. fstcw cont;
  3433. }
  3434. return cont;
  3435. }
  3436. else
  3437. version (D_InlineAsm_X86_64)
  3438. {
  3439. short cont;
  3440. asm
  3441. {
  3442. xor RAX, RAX;
  3443. fstcw cont;
  3444. }
  3445. return cont;
  3446. }
  3447. else
  3448. assert(0, "Not yet supported");
  3449. }
  3450. // Set the control register
  3451. static void setControlState(ushort newState) @trusted nothrow
  3452. {
  3453. version (InlineAsm_X86_Any)
  3454. {
  3455. version (Win64)
  3456. {
  3457. asm
  3458. {
  3459. naked;
  3460. mov 8[RSP],RCX;
  3461. fclex;
  3462. fldcw 8[RSP];
  3463. ret;
  3464. }
  3465. }
  3466. else
  3467. {
  3468. asm
  3469. {
  3470. fclex;
  3471. fldcw newState;
  3472. }
  3473. }
  3474. }
  3475. else
  3476. assert(0, "Not yet supported");
  3477. }
  3478. }
  3479. unittest
  3480. {
  3481. void ensureDefaults()
  3482. {
  3483. assert(FloatingPointControl.rounding
  3484. == FloatingPointControl.roundToNearest);
  3485. assert(FloatingPointControl.enabledExceptions == 0);
  3486. }
  3487. {
  3488. FloatingPointControl ctrl;
  3489. }
  3490. ensureDefaults();
  3491. {
  3492. FloatingPointControl ctrl;
  3493. ctrl.rounding = FloatingPointControl.roundDown;
  3494. assert(FloatingPointControl.rounding == FloatingPointControl.roundDown);
  3495. }
  3496. ensureDefaults();
  3497. {
  3498. FloatingPointControl ctrl;
  3499. ctrl.enableExceptions(FloatingPointControl.divByZeroException
  3500. | FloatingPointControl.overflowException);
  3501. assert(ctrl.enabledExceptions ==
  3502. (FloatingPointControl.divByZeroException
  3503. | FloatingPointControl.overflowException));
  3504. ctrl.rounding = FloatingPointControl.roundUp;
  3505. assert(FloatingPointControl.rounding == FloatingPointControl.roundUp);
  3506. }
  3507. ensureDefaults();
  3508. }
  3509. /*********************************
  3510. * Returns !=0 if e is a NaN.
  3511. */
  3512. bool isNaN(real x) @trusted pure nothrow
  3513. {
  3514. alias floatTraits!(real) F;
  3515. static if (real.mant_dig == 53) // double
  3516. {
  3517. ulong* p = cast(ulong *)&x;
  3518. return ((*p & 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000)
  3519. && *p & 0x000F_FFFF_FFFF_FFFF;
  3520. }
  3521. else static if (real.mant_dig == 64) // real80
  3522. {
  3523. ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
  3524. ulong* ps = cast(ulong *)&x;
  3525. return e == F.EXPMASK &&
  3526. *ps & 0x7FFF_FFFF_FFFF_FFFF; // not infinity
  3527. }
  3528. else static if (real.mant_dig == 113) // quadruple
  3529. {
  3530. ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
  3531. ulong* ps = cast(ulong *)&x;
  3532. return e == F.EXPMASK &&
  3533. (ps[MANTISSA_LSB] | (ps[MANTISSA_MSB]& 0x0000_FFFF_FFFF_FFFF))!=0;
  3534. }
  3535. else
  3536. {
  3537. return x!=x;
  3538. }
  3539. }
  3540. unittest
  3541. {
  3542. assert(isNaN(float.nan));
  3543. assert(isNaN(-double.nan));
  3544. assert(isNaN(real.nan));
  3545. assert(!isNaN(53.6));
  3546. assert(!isNaN(float.infinity));
  3547. }
  3548. /*********************************
  3549. * Returns !=0 if e is finite (not infinite or $(NAN)).
  3550. */
  3551. int isFinite(real e) @trusted pure nothrow
  3552. {
  3553. alias floatTraits!(real) F;
  3554. ushort* pe = cast(ushort *)&e;
  3555. return (pe[F.EXPPOS_SHORT] & F.EXPMASK) != F.EXPMASK;
  3556. }
  3557. unittest
  3558. {
  3559. assert(isFinite(1.23));
  3560. assert(!isFinite(double.infinity));
  3561. assert(!isFinite(float.nan));
  3562. }
  3563. /*********************************
  3564. * Returns !=0 if x is normalized (not zero, subnormal, infinite, or $(NAN)).
  3565. */
  3566. /* Need one for each format because subnormal floats might
  3567. * be converted to normal reals.
  3568. */
  3569. int isNormal(X)(X x) @trusted pure nothrow
  3570. {
  3571. alias floatTraits!(X) F;
  3572. static if(real.mant_dig == 106) // doubledouble
  3573. {
  3574. // doubledouble is normal if the least significant part is normal.
  3575. return isNormal((cast(double*)&x)[MANTISSA_LSB]);
  3576. }
  3577. else
  3578. {
  3579. ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
  3580. return (e != F.EXPMASK && e!=0);
  3581. }
  3582. }
  3583. unittest
  3584. {
  3585. float f = 3;
  3586. double d = 500;
  3587. real e = 10e+48;
  3588. assert(isNormal(f));
  3589. assert(isNormal(d));
  3590. assert(isNormal(e));
  3591. f = d = e = 0;
  3592. assert(!isNormal(f));
  3593. assert(!isNormal(d));
  3594. assert(!isNormal(e));
  3595. assert(!isNormal(real.infinity));
  3596. assert(isNormal(-real.max));
  3597. assert(!isNormal(real.min_normal/4));
  3598. }
  3599. /*********************************
  3600. * Is number subnormal? (Also called "denormal".)
  3601. * Subnormals have a 0 exponent and a 0 most significant mantissa bit.
  3602. */
  3603. /* Need one for each format because subnormal floats might
  3604. * be converted to normal reals.
  3605. */
  3606. int isSubnormal(float f) @trusted pure nothrow
  3607. {
  3608. uint *p = cast(uint *)&f;
  3609. return (*p & 0x7F80_0000) == 0 && *p & 0x007F_FFFF;
  3610. }
  3611. unittest
  3612. {
  3613. float f = 3.0;
  3614. for (f = 1.0; !isSubnormal(f); f /= 2)
  3615. assert(f != 0);
  3616. }
  3617. /// ditto
  3618. int isSubnormal(double d) @trusted pure nothrow
  3619. {
  3620. uint *p = cast(uint *)&d;
  3621. return (p[MANTISSA_MSB] & 0x7FF0_0000) == 0
  3622. && (p[MANTISSA_LSB] || p[MANTISSA_MSB] & 0x000F_FFFF);
  3623. }
  3624. unittest
  3625. {
  3626. double f;
  3627. for (f = 1; !isSubnormal(f); f /= 2)
  3628. assert(f != 0);
  3629. }
  3630. /// ditto
  3631. int isSubnormal(real x) @trusted pure nothrow
  3632. {
  3633. alias floatTraits!(real) F;
  3634. static if (real.mant_dig == 53)
  3635. {
  3636. // double
  3637. return isSubnormal(cast(double)x);
  3638. }
  3639. else static if (real.mant_dig == 113)
  3640. {
  3641. // quadruple
  3642. ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
  3643. long* ps = cast(long *)&x;
  3644. return (e == 0 &&
  3645. (((ps[MANTISSA_LSB]|(ps[MANTISSA_MSB]& 0x0000_FFFF_FFFF_FFFF))) !=0));
  3646. }
  3647. else static if (real.mant_dig==64)
  3648. {
  3649. // real80
  3650. ushort* pe = cast(ushort *)&x;
  3651. long* ps = cast(long *)&x;
  3652. return (pe[F.EXPPOS_SHORT] & F.EXPMASK) == 0 && *ps > 0;
  3653. }
  3654. else
  3655. {
  3656. // double double
  3657. return isSubnormal((cast(double*)&x)[MANTISSA_MSB]);
  3658. }
  3659. }
  3660. unittest
  3661. {
  3662. real f;
  3663. for (f = 1; !isSubnormal(f); f /= 2)
  3664. assert(f != 0);
  3665. }
  3666. /*********************************
  3667. * Return !=0 if e is $(PLUSMN)$(INFIN).
  3668. */
  3669. bool isInfinity(real x) @trusted pure nothrow
  3670. {
  3671. alias floatTraits!(real) F;
  3672. static if (real.mant_dig == 53)
  3673. {
  3674. // double
  3675. return ((*cast(ulong *)&x) & 0x7FFF_FFFF_FFFF_FFFF)
  3676. == 0x7FF8_0000_0000_0000;
  3677. }
  3678. else static if(real.mant_dig == 106)
  3679. {
  3680. //doubledouble
  3681. return (((cast(ulong *)&x)[MANTISSA_MSB]) & 0x7FFF_FFFF_FFFF_FFFF)
  3682. == 0x7FF8_0000_0000_0000;
  3683. }
  3684. else static if (real.mant_dig == 113)
  3685. {
  3686. // quadruple
  3687. long* ps = cast(long *)&x;
  3688. return (ps[MANTISSA_LSB] == 0)
  3689. && (ps[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_0000_0000_0000;
  3690. }
  3691. else
  3692. {
  3693. // real80
  3694. ushort e = cast(ushort)(F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT]);
  3695. ulong* ps = cast(ulong *)&x;
  3696. // On Motorola 68K, infinity can have hidden bit = 1 or 0. On x86, it is always 1.
  3697. return e == F.EXPMASK && (*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0;
  3698. }
  3699. }
  3700. unittest
  3701. {
  3702. assert(isInfinity(float.infinity));
  3703. assert(!isInfinity(float.nan));
  3704. assert(isInfinity(double.infinity));
  3705. assert(isInfinity(-real.infinity));
  3706. assert(isInfinity(-1.0 / 0.0));
  3707. }
  3708. /*********************************
  3709. * Is the binary representation of x identical to y?
  3710. *
  3711. * Same as ==, except that positive and negative zero are not identical,
  3712. * and two $(NAN)s are identical if they have the same 'payload'.
  3713. */
  3714. bool isIdentical(real x, real y) @trusted pure nothrow
  3715. {
  3716. // We're doing a bitwise comparison so the endianness is irrelevant.
  3717. long* pxs = cast(long *)&x;
  3718. long* pys = cast(long *)&y;
  3719. static if (real.mant_dig == 53)
  3720. {
  3721. //double
  3722. return pxs[0] == pys[0];
  3723. }
  3724. else static if (real.mant_dig == 113 || real.mant_dig==106)
  3725. {
  3726. // quadruple or doubledouble
  3727. return pxs[0] == pys[0] && pxs[1] == pys[1];
  3728. }
  3729. else
  3730. {
  3731. // real80
  3732. ushort* pxe = cast(ushort *)&x;
  3733. ushort* pye = cast(ushort *)&y;
  3734. return pxe[4] == pye[4] && pxs[0] == pys[0];
  3735. }
  3736. }
  3737. /*********************************
  3738. * Return 1 if sign bit of e is set, 0 if not.
  3739. */
  3740. int signbit(real x) @trusted pure nothrow
  3741. {
  3742. return ((cast(ubyte *)&x)[floatTraits!(real).SIGNPOS_BYTE] & 0x80) != 0;
  3743. }
  3744. unittest
  3745. {
  3746. debug (math) printf("math.signbit.unittest\n");
  3747. assert(!signbit(float.nan));
  3748. assert(signbit(-float.nan));
  3749. assert(!signbit(168.1234));
  3750. assert(signbit(-168.1234));
  3751. assert(!signbit(0.0));
  3752. assert(signbit(-0.0));
  3753. assert(signbit(-double.max));
  3754. assert(!signbit(double.max));
  3755. }
  3756. /*********************************
  3757. * Return a value composed of to with from's sign bit.
  3758. */
  3759. real copysign(real to, real from) @trusted pure nothrow
  3760. {
  3761. ubyte* pto = cast(ubyte *)&to;
  3762. const ubyte* pfrom = cast(ubyte *)&from;
  3763. alias floatTraits!(real) F;
  3764. pto[F.SIGNPOS_BYTE] &= 0x7F;
  3765. pto[F.SIGNPOS_BYTE] |= pfrom[F.SIGNPOS_BYTE] & 0x80;
  3766. return to;
  3767. }
  3768. unittest
  3769. {
  3770. real e;
  3771. e = copysign(21, 23.8);
  3772. assert(e == 21);
  3773. e = copysign(-21, 23.8);
  3774. assert(e == 21);
  3775. e = copysign(21, -23.8);
  3776. assert(e == -21);
  3777. e = copysign(-21, -23.8);
  3778. assert(e == -21);
  3779. e = copysign(real.nan, -23.8);
  3780. assert(isNaN(e) && signbit(e));
  3781. }
  3782. /*********************************
  3783. Returns $(D -1) if $(D x < 0), $(D x) if $(D x == 0), $(D 1) if
  3784. $(D x > 0), and $(NAN) if x==$(NAN).
  3785. */
  3786. F sgn(F)(F x) @safe pure nothrow
  3787. {
  3788. // @@@TODO@@@: make this faster
  3789. return x > 0 ? 1 : x < 0 ? -1 : x;
  3790. }
  3791. unittest
  3792. {
  3793. debug (math) printf("math.sgn.unittest\n");
  3794. assert(sgn(168.1234) == 1);
  3795. assert(sgn(-168.1234) == -1);
  3796. assert(sgn(0.0) == 0);
  3797. assert(sgn(-0.0) == 0);
  3798. }
  3799. // Functions for NaN payloads
  3800. /*
  3801. * A 'payload' can be stored in the significand of a $(NAN). One bit is required
  3802. * to distinguish between a quiet and a signalling $(NAN). This leaves 22 bits
  3803. * of payload for a float; 51 bits for a double; 62 bits for an 80-bit real;
  3804. * and 111 bits for a 128-bit quad.
  3805. */
  3806. /**
  3807. * Create a quiet $(NAN), storing an integer inside the payload.
  3808. *
  3809. * For floats, the largest possible payload is 0x3F_FFFF.
  3810. * For doubles, it is 0x3_FFFF_FFFF_FFFF.
  3811. * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
  3812. */
  3813. real NaN(ulong payload) @trusted pure nothrow
  3814. {
  3815. static if (real.mant_dig == 64)
  3816. {
  3817. //real80
  3818. ulong v = 3; // implied bit = 1, quiet bit = 1
  3819. }
  3820. else
  3821. {
  3822. ulong v = 2; // no implied bit. quiet bit = 1
  3823. }
  3824. ulong a = payload;
  3825. // 22 Float bits
  3826. ulong w = a & 0x3F_FFFF;
  3827. a -= w;
  3828. v <<=22;
  3829. v |= w;
  3830. a >>=22;
  3831. // 29 Double bits
  3832. v <<=29;
  3833. w = a & 0xFFF_FFFF;
  3834. v |= w;
  3835. a -= w;
  3836. a >>=29;
  3837. static if (real.mant_dig == 53)
  3838. {
  3839. // double
  3840. v |=0x7FF0_0000_0000_0000;
  3841. real x;
  3842. * cast(ulong *)(&x) = v;
  3843. return x;
  3844. }
  3845. else
  3846. {
  3847. v <<=11;
  3848. a &= 0x7FF;
  3849. v |= a;
  3850. real x = real.nan;
  3851. // Extended real bits
  3852. static if (real.mant_dig == 113)
  3853. {
  3854. //quadruple
  3855. v<<=1; // there's no implicit bit
  3856. version(LittleEndian)
  3857. {
  3858. *cast(ulong*)(6+cast(ubyte*)(&x)) = v;
  3859. }
  3860. else
  3861. {
  3862. *cast(ulong*)(2+cast(ubyte*)(&x)) = v;
  3863. }
  3864. }
  3865. else
  3866. {
  3867. // real80
  3868. * cast(ulong *)(&x) = v;
  3869. }
  3870. return x;
  3871. }
  3872. }
  3873. /**
  3874. * Extract an integral payload from a $(NAN).
  3875. *
  3876. * Returns:
  3877. * the integer payload as a ulong.
  3878. *
  3879. * For floats, the largest possible payload is 0x3F_FFFF.
  3880. * For doubles, it is 0x3_FFFF_FFFF_FFFF.
  3881. * For 80-bit or 128-bit reals, it is 0x3FFF_FFFF_FFFF_FFFF.
  3882. */
  3883. ulong getNaNPayload(real x) @trusted pure nothrow
  3884. {
  3885. // assert(isNaN(x));
  3886. static if (real.mant_dig == 53)
  3887. {
  3888. ulong m = *cast(ulong *)(&x);
  3889. // Make it look like an 80-bit significand.
  3890. // Skip exponent, and quiet bit
  3891. m &= 0x0007_FFFF_FFFF_FFFF;
  3892. m <<= 10;
  3893. }
  3894. else static if (real.mant_dig==113)
  3895. {
  3896. // quadruple
  3897. version(LittleEndian)
  3898. {
  3899. ulong m = *cast(ulong*)(6+cast(ubyte*)(&x));
  3900. }
  3901. else
  3902. {
  3903. ulong m = *cast(ulong*)(2+cast(ubyte*)(&x));
  3904. }
  3905. m >>= 1; // there's no implicit bit
  3906. }
  3907. else
  3908. {
  3909. ulong m = *cast(ulong *)(&x);
  3910. }
  3911. // ignore implicit bit and quiet bit
  3912. ulong f = m & 0x3FFF_FF00_0000_0000L;
  3913. ulong w = f >>> 40;
  3914. w |= (m & 0x00FF_FFFF_F800L) << (22 - 11);
  3915. w |= (m & 0x7FF) << 51;
  3916. return w;
  3917. }
  3918. debug(UnitTest)
  3919. {
  3920. unittest
  3921. {
  3922. real nan4 = NaN(0x789_ABCD_EF12_3456);
  3923. static if (real.mant_dig == 64 || real.mant_dig == 113)
  3924. {
  3925. assert (getNaNPayload(nan4) == 0x789_ABCD_EF12_3456);
  3926. }
  3927. else
  3928. {
  3929. assert (getNaNPayload(nan4) == 0x1_ABCD_EF12_3456);
  3930. }
  3931. double nan5 = nan4;
  3932. assert (getNaNPayload(nan5) == 0x1_ABCD_EF12_3456);
  3933. float nan6 = nan4;
  3934. assert (getNaNPayload(nan6) == 0x12_3456);
  3935. nan4 = NaN(0xFABCD);
  3936. assert (getNaNPayload(nan4) == 0xFABCD);
  3937. nan6 = nan4;
  3938. assert (getNaNPayload(nan6) == 0xFABCD);
  3939. nan5 = NaN(0x100_0000_0000_3456);
  3940. assert(getNaNPayload(nan5) == 0x0000_0000_3456);
  3941. }
  3942. }
  3943. /**
  3944. * Calculate the next largest floating point value after x.
  3945. *
  3946. * Return the least number greater than x that is representable as a real;
  3947. * thus, it gives the next point on the IEEE number line.
  3948. *
  3949. * $(TABLE_SV
  3950. * $(SVH x, nextUp(x) )
  3951. * $(SV -$(INFIN), -real.max )
  3952. * $(SV $(PLUSMN)0.0, real.min_normal*real.epsilon )
  3953. * $(SV real.max, $(INFIN) )
  3954. * $(SV $(INFIN), $(INFIN) )
  3955. * $(SV $(NAN), $(NAN) )
  3956. * )
  3957. */
  3958. real nextUp(real x) @trusted pure nothrow
  3959. {
  3960. alias floatTraits!(real) F;
  3961. static if (real.mant_dig == 53)
  3962. {
  3963. // double
  3964. return nextUp(cast(double)x);
  3965. }
  3966. else static if (real.mant_dig == 113)
  3967. {
  3968. // quadruple
  3969. ushort e = F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT];
  3970. if (e == F.EXPMASK)
  3971. {
  3972. // NaN or Infinity
  3973. if (x == -real.infinity) return -real.max;
  3974. return x; // +Inf and NaN are unchanged.
  3975. }
  3976. ulong* ps = cast(ulong *)&e;
  3977. if (ps[MANTISSA_LSB] & 0x8000_0000_0000_0000)
  3978. {
  3979. // Negative number
  3980. if (ps[MANTISSA_LSB] == 0
  3981. && ps[MANTISSA_MSB] == 0x8000_0000_0000_0000)
  3982. {
  3983. // it was negative zero, change to smallest subnormal
  3984. ps[MANTISSA_LSB] = 0x0000_0000_0000_0001;
  3985. ps[MANTISSA_MSB] = 0;
  3986. return x;
  3987. }
  3988. --*ps;
  3989. if (ps[MANTISSA_LSB]==0) --ps[MANTISSA_MSB];
  3990. }
  3991. else
  3992. {
  3993. // Positive number
  3994. ++ps[MANTISSA_LSB];
  3995. if (ps[MANTISSA_LSB]==0) ++ps[MANTISSA_MSB];
  3996. }
  3997. return x;
  3998. }
  3999. else static if(real.mant_dig==64) // real80
  4000. {
  4001. // For 80-bit reals, the "implied bit" is a nuisance...
  4002. ushort *pe = cast(ushort *)&x;
  4003. ulong *ps = cast(ulong *)&x;
  4004. if ((pe[F.EXPPOS_SHORT] & F.EXPMASK) == F.EXPMASK)
  4005. {
  4006. // First, deal with NANs and infinity
  4007. if (x == -real.infinity) return -real.max;
  4008. return x; // +Inf and NaN are unchanged.
  4009. }
  4010. if (pe[F.EXPPOS_SHORT] & 0x8000)
  4011. {
  4012. // Negative number -- need to decrease the significand
  4013. --*ps;
  4014. // Need to mask with 0x7FFF... so subnormals are treated correctly.
  4015. if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_FFFF_FFFF_FFFF)
  4016. {
  4017. if (pe[F.EXPPOS_SHORT] == 0x8000) // it was negative zero
  4018. {
  4019. *ps = 1;
  4020. pe[F.EXPPOS_SHORT] = 0; // smallest subnormal.
  4021. return x;
  4022. }
  4023. --pe[F.EXPPOS_SHORT];
  4024. if (pe[F.EXPPOS_SHORT] == 0x8000)
  4025. return x; // it's become a subnormal, implied bit stays low.
  4026. *ps = 0xFFFF_FFFF_FFFF_FFFF; // set the implied bit
  4027. return x;
  4028. }
  4029. return x;
  4030. }
  4031. else
  4032. {
  4033. // Positive number -- need to increase the significand.
  4034. // Works automatically for positive zero.
  4035. ++*ps;
  4036. if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0)
  4037. {
  4038. // change in exponent
  4039. ++pe[F.EXPPOS_SHORT];
  4040. *ps = 0x8000_0000_0000_0000; // set the high bit
  4041. }
  4042. }
  4043. return x;
  4044. }
  4045. else // static if (real.mant_dig==106) // real is doubledouble
  4046. {
  4047. assert (0, "nextUp not implemented");
  4048. }
  4049. }
  4050. /** ditto */
  4051. double nextUp(double x) @trusted pure nothrow
  4052. {
  4053. ulong *ps = cast(ulong *)&x;
  4054. if ((*ps & 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000)
  4055. {
  4056. // First, deal with NANs and infinity
  4057. if (x == -x.infinity) return -x.max;
  4058. return x; // +INF and NAN are unchanged.
  4059. }
  4060. if (*ps & 0x8000_0000_0000_0000) // Negative number
  4061. {
  4062. if (*ps == 0x8000_0000_0000_0000) // it was negative zero
  4063. {
  4064. *ps = 0x0000_0000_0000_0001; // change to smallest subnormal
  4065. return x;
  4066. }
  4067. --*ps;
  4068. }
  4069. else
  4070. { // Positive number
  4071. ++*ps;
  4072. }
  4073. return x;
  4074. }
  4075. /** ditto */
  4076. float nextUp(float x) @trusted pure nothrow
  4077. {
  4078. uint *ps = cast(uint *)&x;
  4079. if ((*ps & 0x7F80_0000) == 0x7F80_0000)
  4080. {
  4081. // First, deal with NANs and infinity
  4082. if (x == -x.infinity) return -x.max;
  4083. return x; // +INF and NAN are unchanged.
  4084. }
  4085. if (*ps & 0x8000_0000) // Negative number
  4086. {
  4087. if (*ps == 0x8000_0000) // it was negative zero
  4088. {
  4089. *ps = 0x0000_0001; // change to smallest subnormal
  4090. return x;
  4091. }
  4092. --*ps;
  4093. }
  4094. else
  4095. {
  4096. // Positive number
  4097. ++*ps;
  4098. }
  4099. return x;
  4100. }
  4101. /**
  4102. * Calculate the next smallest floating point value before x.
  4103. *
  4104. * Return the greatest number less than x that is representable as a real;
  4105. * thus, it gives the previous point on the IEEE number line.
  4106. *
  4107. * $(TABLE_SV
  4108. * $(SVH x, nextDown(x) )
  4109. * $(SV $(INFIN), real.max )
  4110. * $(SV $(PLUSMN)0.0, -real.min_normal*real.epsilon )
  4111. * $(SV -real.max, -$(INFIN) )
  4112. * $(SV -$(INFIN), -$(INFIN) )
  4113. * $(SV $(NAN), $(NAN) )
  4114. * )
  4115. */
  4116. real nextDown(real x) @safe pure nothrow
  4117. {
  4118. return -nextUp(-x);
  4119. }
  4120. /** ditto */
  4121. double nextDown(double x) @safe pure nothrow
  4122. {
  4123. return -nextUp(-x);
  4124. }
  4125. /** ditto */
  4126. float nextDown(float x) @safe pure nothrow
  4127. {
  4128. return -nextUp(-x);
  4129. }
  4130. unittest
  4131. {
  4132. assert( nextDown(1.0 + real.epsilon) == 1.0);
  4133. }
  4134. unittest
  4135. {
  4136. static if (real.mant_dig == 64)
  4137. {
  4138. // Tests for 80-bit reals
  4139. assert(isIdentical(nextUp(NaN(0xABC)), NaN(0xABC)));
  4140. // negative numbers
  4141. assert( nextUp(-real.infinity) == -real.max );
  4142. assert( nextUp(-1.0L-real.epsilon) == -1.0 );
  4143. assert( nextUp(-2.0L) == -2.0 + real.epsilon);
  4144. // subnormals and zero
  4145. assert( nextUp(-real.min_normal) == -real.min_normal*(1-real.epsilon) );
  4146. assert( nextUp(-real.min_normal*(1-real.epsilon)) == -real.min_normal*(1-2*real.epsilon) );
  4147. assert( isIdentical(-0.0L, nextUp(-real.min_normal*real.epsilon)) );
  4148. assert( nextUp(-0.0L) == real.min_normal*real.epsilon );
  4149. assert( nextUp(0.0L) == real.min_normal*real.epsilon );
  4150. assert( nextUp(real.min_normal*(1-real.epsilon)) == real.min_normal );
  4151. assert( nextUp(real.min_normal) == real.min_normal*(1+real.epsilon) );
  4152. // positive numbers
  4153. assert( nextUp(1.0L) == 1.0 + real.epsilon );
  4154. assert( nextUp(2.0L-real.epsilon) == 2.0 );
  4155. assert( nextUp(real.max) == real.infinity );
  4156. assert( nextUp(real.infinity)==real.infinity );
  4157. }
  4158. double n = NaN(0xABC);
  4159. assert(isIdentical(nextUp(n), n));
  4160. // negative numbers
  4161. assert( nextUp(-double.infinity) == -double.max );
  4162. assert( nextUp(-1-double.epsilon) == -1.0 );
  4163. assert( nextUp(-2.0) == -2.0 + double.epsilon);
  4164. // subnormals and zero
  4165. assert( nextUp(-double.min_normal) == -double.min_normal*(1-double.epsilon) );
  4166. assert( nextUp(-double.min_normal*(1-double.epsilon)) == -double.min_normal*(1-2*double.epsilon) );
  4167. assert( isIdentical(-0.0, nextUp(-double.min_normal*double.epsilon)) );
  4168. assert( nextUp(0.0) == double.min_normal*double.epsilon );
  4169. assert( nextUp(-0.0) == double.min_normal*double.epsilon );
  4170. assert( nextUp(double.min_normal*(1-double.epsilon)) == double.min_normal );
  4171. assert( nextUp(double.min_normal) == double.min_normal*(1+double.epsilon) );
  4172. // positive numbers
  4173. assert( nextUp(1.0) == 1.0 + double.epsilon );
  4174. assert( nextUp(2.0-double.epsilon) == 2.0 );
  4175. assert( nextUp(double.max) == double.infinity );
  4176. float fn = NaN(0xABC);
  4177. assert(isIdentical(nextUp(fn), fn));
  4178. float f = -float.min_normal*(1-float.epsilon);
  4179. float f1 = -float.min_normal;
  4180. assert( nextUp(f1) == f);
  4181. f = 1.0f+float.epsilon;
  4182. f1 = 1.0f;
  4183. assert( nextUp(f1) == f );
  4184. f1 = -0.0f;
  4185. assert( nextUp(f1) == float.min_normal*float.epsilon);
  4186. assert( nextUp(float.infinity)==float.infinity );
  4187. assert(nextDown(1.0L+real.epsilon)==1.0);
  4188. assert(nextDown(1.0+double.epsilon)==1.0);
  4189. f = 1.0f+float.epsilon;
  4190. assert(nextDown(f)==1.0);
  4191. assert(nextafter(1.0+real.epsilon, -real.infinity)==1.0);
  4192. }
  4193. /******************************************
  4194. * Calculates the next representable value after x in the direction of y.
  4195. *
  4196. * If y > x, the result will be the next largest floating-point value;
  4197. * if y < x, the result will be the next smallest value.
  4198. * If x == y, the result is y.
  4199. *
  4200. * Remarks:
  4201. * This function is not generally very useful; it's almost always better to use
  4202. * the faster functions nextUp() or nextDown() instead.
  4203. *
  4204. * The FE_INEXACT and FE_OVERFLOW exceptions will be raised if x is finite and
  4205. * the function result is infinite. The FE_INEXACT and FE_UNDERFLOW
  4206. * exceptions will be raised if the function value is subnormal, and x is
  4207. * not equal to y.
  4208. */
  4209. T nextafter(T)(T x, T y) @safe pure nothrow
  4210. {
  4211. if (x==y) return y;
  4212. return ((y>x) ? nextUp(x) : nextDown(x));
  4213. }
  4214. unittest
  4215. {
  4216. float a = 1;
  4217. assert(is(typeof(nextafter(a, a)) == float));
  4218. assert(nextafter(a, a.infinity) > a);
  4219. double b = 2;
  4220. assert(is(typeof(nextafter(b, b)) == double));
  4221. assert(nextafter(b, b.infinity) > b);
  4222. real c = 3;
  4223. assert(is(typeof(nextafter(c, c)) == real));
  4224. assert(nextafter(c, c.infinity) > c);
  4225. }
  4226. //real nexttoward(real x, real y) { return core.stdc.math.nexttowardl(x, y); }
  4227. /*******************************************
  4228. * Returns the positive difference between x and y.
  4229. * Returns:
  4230. * $(TABLE_SV
  4231. * $(TR $(TH x, y) $(TH fdim(x, y)))
  4232. * $(TR $(TD x $(GT) y) $(TD x - y))
  4233. * $(TR $(TD x $(LT)= y) $(TD +0.0))
  4234. * )
  4235. */
  4236. real fdim(real x, real y) @safe pure nothrow { return (x > y) ? x - y : +0.0; }
  4237. /****************************************
  4238. * Returns the larger of x and y.
  4239. */
  4240. real fmax(real x, real y) @safe pure nothrow { return x > y ? x : y; }
  4241. /****************************************
  4242. * Returns the smaller of x and y.
  4243. */
  4244. real fmin(real x, real y) @safe pure nothrow { return x < y ? x : y; }
  4245. /**************************************
  4246. * Returns (x * y) + z, rounding only once according to the
  4247. * current rounding mode.
  4248. *
  4249. * BUGS: Not currently implemented - rounds twice.
  4250. */
  4251. real fma(real x, real y, real z) @safe pure nothrow { return (x * y) + z; }
  4252. /*******************************************************************
  4253. * Compute the value of x $(SUP n), where n is an integer
  4254. */
  4255. Unqual!F pow(F, G)(F x, G n) @trusted pure nothrow
  4256. if (isFloatingPoint!(F) && isIntegral!(G))
  4257. {
  4258. real p = 1.0, v = void;
  4259. Unsigned!(Unqual!G) m = n;
  4260. if (n < 0)
  4261. {
  4262. switch (n)
  4263. {
  4264. case -1:
  4265. return 1 / x;
  4266. case -2:
  4267. return 1 / (x * x);
  4268. default:
  4269. }
  4270. m = -n;
  4271. v = p / x;
  4272. }
  4273. else
  4274. {
  4275. switch (n)
  4276. {
  4277. case 0:
  4278. return 1.0;
  4279. case 1:
  4280. return x;
  4281. case 2:
  4282. return x * x;
  4283. default:
  4284. }
  4285. v = x;
  4286. }
  4287. while (1)
  4288. {
  4289. if (m & 1)
  4290. p *= v;
  4291. m >>= 1;
  4292. if (!m)
  4293. break;
  4294. v *= v;
  4295. }
  4296. return p;
  4297. }
  4298. unittest
  4299. {
  4300. // Make sure it instantiates and works properly on immutable values and
  4301. // with various integer and float types.
  4302. immutable real x = 46;
  4303. immutable float xf = x;
  4304. immutable double xd = x;
  4305. immutable uint one = 1;
  4306. immutable ushort two = 2;
  4307. immutable ubyte three = 3;
  4308. immutable ulong eight = 8;
  4309. immutable int neg1 = -1;
  4310. immutable short neg2 = -2;
  4311. immutable byte neg3 = -3;
  4312. immutable long neg8 = -8;
  4313. assert(pow(x,0) == 1.0);
  4314. assert(pow(xd,one) == x);
  4315. assert(pow(xf,two) == x * x);
  4316. assert(pow(x,three) == x * x * x);
  4317. assert(pow(x,eight) == (x * x) * (x * x) * (x * x) * (x * x));
  4318. assert(pow(x, neg1) == 1 / x);
  4319. version(X86_64)
  4320. {
  4321. pragma(msg, "test disabled on x86_64, see bug 5628");
  4322. }
  4323. else
  4324. {
  4325. assert(pow(xd, neg2) == 1 / (x * x));
  4326. assert(pow(xf, neg8) == 1 / ((x * x) * (x * x) * (x * x) * (x * x)));
  4327. }
  4328. assert(pow(x, neg3) == 1 / (x * x * x));
  4329. }
  4330. unittest
  4331. {
  4332. assert(equalsDigit(pow(2.0L, 10.0L), 1024, 19));
  4333. }
  4334. /** Compute the value of an integer x, raised to the power of a positive
  4335. * integer n.
  4336. *
  4337. * If both x and n are 0, the result is 1.
  4338. * If n is negative, an integer divide error will occur at runtime,
  4339. * regardless of the value of x.
  4340. */
  4341. typeof(Unqual!(F).init * Unqual!(G).init) pow(F, G)(F x, G n) @trusted pure nothrow
  4342. if (isIntegral!(F) && isIntegral!(G))
  4343. {
  4344. if (n<0) return x/0; // Only support positive powers
  4345. typeof(return) p, v = void;
  4346. Unqual!G m = n;
  4347. switch (m)
  4348. {
  4349. case 0:
  4350. p = 1;
  4351. break;
  4352. case 1:
  4353. p = x;
  4354. break;
  4355. case 2:
  4356. p = x * x;
  4357. break;
  4358. default:
  4359. v = x;
  4360. p = 1;
  4361. while (1){
  4362. if (m & 1)
  4363. p *= v;
  4364. m >>= 1;
  4365. if (!m)
  4366. break;
  4367. v *= v;
  4368. }
  4369. break;
  4370. }
  4371. return p;
  4372. }
  4373. unittest
  4374. {
  4375. immutable int one = 1;
  4376. immutable byte two = 2;
  4377. immutable ubyte three = 3;
  4378. immutable short four = 4;
  4379. immutable long ten = 10;
  4380. assert(pow(two, three) == 8);
  4381. assert(pow(two, ten) == 1024);
  4382. assert(pow(one, ten) == 1);
  4383. assert(pow(ten, four) == 10_000);
  4384. assert(pow(four, 10) == 1_048_576);
  4385. assert(pow(three, four) == 81);
  4386. }
  4387. /**Computes integer to floating point powers.*/
  4388. real pow(I, F)(I x, F y) @trusted pure nothrow
  4389. if(isIntegral!I && isFloatingPoint!F)
  4390. {
  4391. return pow(cast(real) x, cast(Unqual!F) y);
  4392. }
  4393. /*********************************************
  4394. * Calculates x$(SUP y).
  4395. *
  4396. * $(TABLE_SV
  4397. * $(TR $(TH x) $(TH y) $(TH pow(x, y))
  4398. * $(TH div 0) $(TH invalid?))
  4399. * $(TR $(TD anything) $(TD $(PLUSMN)0.0) $(TD 1.0)
  4400. * $(TD no) $(TD no) )
  4401. * $(TR $(TD |x| $(GT) 1) $(TD +$(INFIN)) $(TD +$(INFIN))
  4402. * $(TD no) $(TD no) )
  4403. * $(TR $(TD |x| $(LT) 1) $(TD +$(INFIN)) $(TD +0.0)
  4404. * $(TD no) $(TD no) )
  4405. * $(TR $(TD |x| $(GT) 1) $(TD -$(INFIN)) $(TD +0.0)
  4406. * $(TD no) $(TD no) )
  4407. * $(TR $(TD |x| $(LT) 1) $(TD -$(INFIN)) $(TD +$(INFIN))
  4408. * $(TD no) $(TD no) )
  4409. * $(TR $(TD +$(INFIN)) $(TD $(GT) 0.0) $(TD +$(INFIN))
  4410. * $(TD no) $(TD no) )
  4411. * $(TR $(TD +$(INFIN)) $(TD $(LT) 0.0) $(TD +0.0)
  4412. * $(TD no) $(TD no) )
  4413. * $(TR $(TD -$(INFIN)) $(TD odd integer $(GT) 0.0) $(TD -$(INFIN))
  4414. * $(TD no) $(TD no) )
  4415. * $(TR $(TD -$(INFIN)) $(TD $(GT) 0.0, not odd integer) $(TD +$(INFIN))
  4416. * $(TD no) $(TD no))
  4417. * $(TR $(TD -$(INFIN)) $(TD odd integer $(LT) 0.0) $(TD -0.0)
  4418. * $(TD no) $(TD no) )
  4419. * $(TR $(TD -$(INFIN)) $(TD $(LT) 0.0, not odd integer) $(TD +0.0)
  4420. * $(TD no) $(TD no) )
  4421. * $(TR $(TD $(PLUSMN)1.0) $(TD $(PLUSMN)$(INFIN)) $(TD $(NAN))
  4422. * $(TD no) $(TD yes) )
  4423. * $(TR $(TD $(LT) 0.0) $(TD finite, nonintegral) $(TD $(NAN))
  4424. * $(TD no) $(TD yes))
  4425. * $(TR $(TD $(PLUSMN)0.0) $(TD odd integer $(LT) 0.0) $(TD $(PLUSMNINF))
  4426. * $(TD yes) $(TD no) )
  4427. * $(TR $(TD $(PLUSMN)0.0) $(TD $(LT) 0.0, not odd integer) $(TD +$(INFIN))
  4428. * $(TD yes) $(TD no))
  4429. * $(TR $(TD $(PLUSMN)0.0) $(TD odd integer $(GT) 0.0) $(TD $(PLUSMN)0.0)
  4430. * $(TD no) $(TD no) )
  4431. * $(TR $(TD $(PLUSMN)0.0) $(TD $(GT) 0.0, not odd integer) $(TD +0.0)
  4432. * $(TD no) $(TD no) )
  4433. * )
  4434. */
  4435. Unqual!(Largest!(F, G)) pow(F, G)(F x, G y) @trusted pure nothrow
  4436. if (isFloatingPoint!(F) && isFloatingPoint!(G))
  4437. {
  4438. alias typeof(return) Float;
  4439. static real impl(real x, real y) pure nothrow
  4440. {
  4441. // Special cases.
  4442. if (isNaN(y))
  4443. return y;
  4444. if (isNaN(x) && y != 0.0)
  4445. return x;
  4446. // Even if x is NaN.
  4447. if (y == 0.0)
  4448. return 1.0;
  4449. if (y == 1.0)
  4450. return x;
  4451. if (isInfinity(y))
  4452. {
  4453. if (fabs(x) > 1)
  4454. {
  4455. if (signbit(y))
  4456. return +0.0;
  4457. else
  4458. return F.infinity;
  4459. }
  4460. else if (fabs(x) == 1)
  4461. {
  4462. return y * 0; // generate NaN.
  4463. }
  4464. else // < 1
  4465. {
  4466. if (signbit(y))
  4467. return F.infinity;
  4468. else
  4469. return +0.0;
  4470. }
  4471. }
  4472. if (isInfinity(x))
  4473. {
  4474. if (signbit(x))
  4475. {
  4476. long i = cast(long)y;
  4477. if (y > 0.0)
  4478. {
  4479. if (i == y && i & 1)
  4480. return -F.infinity;
  4481. else
  4482. return F.infinity;
  4483. }
  4484. else if (y < 0.0)
  4485. {
  4486. if (i == y && i & 1)
  4487. return -0.0;
  4488. else
  4489. return +0.0;
  4490. }
  4491. }
  4492. else
  4493. {
  4494. if (y > 0.0)
  4495. return F.infinity;
  4496. else if (y < 0.0)
  4497. return +0.0;
  4498. }
  4499. }
  4500. if (x == 0.0)
  4501. {
  4502. if (signbit(x))
  4503. {
  4504. long i = cast(long)y;
  4505. if (y > 0.0)
  4506. {
  4507. if (i == y && i & 1)
  4508. return -0.0;
  4509. else
  4510. return +0.0;
  4511. }
  4512. else if (y < 0.0)
  4513. {
  4514. if (i == y && i & 1)
  4515. return -F.infinity;
  4516. else
  4517. return F.infinity;
  4518. }
  4519. }
  4520. else
  4521. {
  4522. if (y > 0.0)
  4523. return +0.0;
  4524. else if (y < 0.0)
  4525. return F.infinity;
  4526. }
  4527. }
  4528. if (x == 1.0)
  4529. return 1.0;
  4530. if (y >= F.max)
  4531. {
  4532. if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))
  4533. return 0.0;
  4534. if (x > 1.0 || x < -1.0)
  4535. return F.infinity;
  4536. }
  4537. if (y <= -F.max)
  4538. {
  4539. if ((x > 0.0 && x < 1.0) || (x > -1.0 && x < 0.0))
  4540. return F.infinity;
  4541. if (x > 1.0 || x < -1.0)
  4542. return 0.0;
  4543. }
  4544. if (x >= F.max)
  4545. {
  4546. if (y > 0.0)
  4547. return F.infinity;
  4548. else
  4549. return 0.0;
  4550. }
  4551. if (x <= -F.max)
  4552. {
  4553. long i = cast(long)y;
  4554. if (y > 0.0)
  4555. {
  4556. if (i == y && i & 1)
  4557. return -F.infinity;
  4558. else
  4559. return F.infinity;
  4560. }
  4561. else if (y < 0.0)
  4562. {
  4563. if (i == y && i & 1)
  4564. return -0.0;
  4565. else
  4566. return +0.0;
  4567. }
  4568. }
  4569. // Integer power of x.
  4570. long iy = cast(long)y;
  4571. if (iy == y && fabs(y) < 32768.0)
  4572. return pow(x, iy);
  4573. double sign = 1.0;
  4574. if (x < 0)
  4575. {
  4576. // Result is real only if y is an integer
  4577. // Check for a non-zero fractional part
  4578. if (y > -1.0 / real.epsilon && y < 1.0 / real.epsilon)
  4579. {
  4580. long w = cast(long)y;
  4581. if (w != y)
  4582. return sqrt(x); // Complex result -- create a NaN
  4583. if (w & 1) sign = -1.0;
  4584. }
  4585. x = -x;
  4586. }
  4587. version(INLINE_YL2X)
  4588. {
  4589. // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )
  4590. // TODO: This is not accurate in practice. A fast and accurate
  4591. // (though complicated) method is described in:
  4592. // "An efficient rounding boundary test for pow(x, y)
  4593. // in double precision", C.Q. Lauter and V. Lefèvre, INRIA (2007).
  4594. return sign * exp2( yl2x(x, y) );
  4595. }
  4596. else
  4597. {
  4598. // If x > 0, x ^^ y == 2 ^^ ( y * log2(x) )
  4599. // TODO: This is not accurate in practice. A fast and accurate
  4600. // (though complicated) method is described in:
  4601. // "An efficient rounding boundary test for pow(x, y)
  4602. // in double precision", C.Q. Lauter and V. Lefèvre, INRIA (2007).
  4603. Float w = exp2(y * log2(x));
  4604. return sign * w;
  4605. }
  4606. }
  4607. return impl(x, y);
  4608. }
  4609. unittest
  4610. {
  4611. // Test all the special values. These unittests can be run on Windows
  4612. // by temporarily changing the version(linux) to version(all).
  4613. immutable float zero = 0;
  4614. immutable real one = 1;
  4615. immutable double two = 2;
  4616. immutable float three = 3;
  4617. immutable float fnan = float.nan;
  4618. immutable double dnan = double.nan;
  4619. immutable real rnan = real.nan;
  4620. immutable dinf = double.infinity;
  4621. immutable rninf = -real.infinity;
  4622. assert(pow(fnan, zero) == 1);
  4623. assert(pow(dnan, zero) == 1);
  4624. assert(pow(rnan, zero) == 1);
  4625. assert(pow(two, dinf) == double.infinity);
  4626. assert(isIdentical(pow(0.2f, dinf), +0.0));
  4627. assert(pow(0.99999999L, rninf) == real.infinity);
  4628. assert(isIdentical(pow(1.000000001, rninf), +0.0));
  4629. assert(pow(dinf, 0.001) == dinf);
  4630. assert(isIdentical(pow(dinf, -0.001), +0.0));
  4631. assert(pow(rninf, 3.0L) == rninf);
  4632. assert(pow(rninf, 2.0L) == real.infinity);
  4633. assert(isIdentical(pow(rninf, -3.0), -0.0));
  4634. assert(isIdentical(pow(rninf, -2.0), +0.0));
  4635. // @@@BUG@@@ somewhere
  4636. version(OSX) {} else assert(isNaN(pow(one, dinf)));
  4637. version(OSX) {} else assert(isNaN(pow(-one, dinf)));
  4638. assert(isNaN(pow(-0.2, PI)));
  4639. // boundary cases. Note that epsilon == 2^^-n for some n,
  4640. // so 1/epsilon == 2^^n is always even.
  4641. assert(pow(-1.0L, 1/real.epsilon - 1.0L) == -1.0L);
  4642. assert(pow(-1.0L, 1/real.epsilon) == 1.0L);
  4643. assert(isNaN(pow(-1.0L, 1/real.epsilon-0.5L)));
  4644. assert(isNaN(pow(-1.0L, -1/real.epsilon+0.5L)));
  4645. assert(pow(0.0, -3.0) == double.infinity);
  4646. assert(pow(-0.0, -3.0) == -double.infinity);
  4647. assert(pow(0.0, -PI) == double.infinity);
  4648. assert(pow(-0.0, -PI) == double.infinity);
  4649. assert(isIdentical(pow(0.0, 5.0), 0.0));
  4650. assert(isIdentical(pow(-0.0, 5.0), -0.0));
  4651. assert(isIdentical(pow(0.0, 6.0), 0.0));
  4652. assert(isIdentical(pow(-0.0, 6.0), 0.0));
  4653. // Now, actual numbers.
  4654. assert(approxEqual(pow(two, three), 8.0));
  4655. assert(approxEqual(pow(two, -2.5), 0.1767767));
  4656. // Test integer to float power.
  4657. immutable uint twoI = 2;
  4658. assert(approxEqual(pow(twoI, three), 8.0));
  4659. }
  4660. /**************************************
  4661. * To what precision is x equal to y?
  4662. *
  4663. * Returns: the number of mantissa bits which are equal in x and y.
  4664. * eg, 0x1.F8p+60 and 0x1.F1p+60 are equal to 5 bits of precision.
  4665. *
  4666. * $(TABLE_SV
  4667. * $(TR $(TH x) $(TH y) $(TH feqrel(x, y)))
  4668. * $(TR $(TD x) $(TD x) $(TD real.mant_dig))
  4669. * $(TR $(TD x) $(TD $(GT)= 2*x) $(TD 0))
  4670. * $(TR $(TD x) $(TD $(LT)= x/2) $(TD 0))
  4671. * $(TR $(TD $(NAN)) $(TD any) $(TD 0))
  4672. * $(TR $(TD any) $(TD $(NAN)) $(TD 0))
  4673. * )
  4674. */
  4675. int feqrel(X)(X x, X y) @trusted pure nothrow
  4676. if (isFloatingPoint!(X))
  4677. {
  4678. /* Public Domain. Author: Don Clugston, 18 Aug 2005.
  4679. */
  4680. static if (X.mant_dig == 106) // doubledouble
  4681. {
  4682. if (cast(double*)(&x)[MANTISSA_MSB] == cast(double*)(&y)[MANTISSA_MSB])
  4683. {
  4684. return double.mant_dig
  4685. + feqrel(cast(double*)(&x)[MANTISSA_LSB],
  4686. cast(double*)(&y)[MANTISSA_LSB]);
  4687. }
  4688. else
  4689. {
  4690. return feqrel(cast(double*)(&x)[MANTISSA_MSB],
  4691. cast(double*)(&y)[MANTISSA_MSB]);
  4692. }
  4693. }
  4694. else
  4695. {
  4696. static assert( X.mant_dig == 64 || X.mant_dig == 113
  4697. || X.mant_dig == double.mant_dig || X.mant_dig == float.mant_dig);
  4698. if (x == y)
  4699. return X.mant_dig; // ensure diff!=0, cope with INF.
  4700. X diff = fabs(x - y);
  4701. ushort *pa = cast(ushort *)(&x);
  4702. ushort *pb = cast(ushort *)(&y);
  4703. ushort *pd = cast(ushort *)(&diff);
  4704. alias floatTraits!(X) F;
  4705. // The difference in abs(exponent) between x or y and abs(x-y)
  4706. // is equal to the number of significand bits of x which are
  4707. // equal to y. If negative, x and y have different exponents.
  4708. // If positive, x and y are equal to 'bitsdiff' bits.
  4709. // AND with 0x7FFF to form the absolute value.
  4710. // To avoid out-by-1 errors, we subtract 1 so it rounds down
  4711. // if the exponents were different. This means 'bitsdiff' is
  4712. // always 1 lower than we want, except that if bitsdiff==0,
  4713. // they could have 0 or 1 bits in common.
  4714. static if (X.mant_dig == 64 || X.mant_dig == 113)
  4715. { // real80 or quadruple
  4716. int bitsdiff = ( ((pa[F.EXPPOS_SHORT] & F.EXPMASK)
  4717. + (pb[F.EXPPOS_SHORT] & F.EXPMASK) - 1) >> 1)
  4718. - pd[F.EXPPOS_SHORT];
  4719. }
  4720. else static if (X.mant_dig == double.mant_dig)
  4721. { // double
  4722. int bitsdiff = (( ((pa[F.EXPPOS_SHORT]&0x7FF0)
  4723. + (pb[F.EXPPOS_SHORT]&0x7FF0)-0x10)>>1)
  4724. - (pd[F.EXPPOS_SHORT]&0x7FF0))>>4;
  4725. }
  4726. else static if (X.mant_dig == float.mant_dig)
  4727. { // float
  4728. int bitsdiff = (( ((pa[F.EXPPOS_SHORT]&0x7F80)
  4729. + (pb[F.EXPPOS_SHORT]&0x7F80)-0x80)>>1)
  4730. - (pd[F.EXPPOS_SHORT]&0x7F80))>>7;
  4731. }
  4732. if ( (pd[F.EXPPOS_SHORT] & F.EXPMASK) == 0)
  4733. { // Difference is subnormal
  4734. // For subnormals, we need to add the number of zeros that
  4735. // lie at the start of diff's significand.
  4736. // We do this by multiplying by 2^^real.mant_dig
  4737. diff *= F.RECIP_EPSILON;
  4738. return bitsdiff + X.mant_dig - pd[F.EXPPOS_SHORT];
  4739. }
  4740. if (bitsdiff > 0)
  4741. return bitsdiff + 1; // add the 1 we subtracted before
  4742. // Avoid out-by-1 errors when factor is almost 2.
  4743. static if (X.mant_dig == 64 || X.mant_dig == 113)
  4744. { // real80 or quadruple
  4745. return (bitsdiff == 0) ? (pa[F.EXPPOS_SHORT] == pb[F.EXPPOS_SHORT]) : 0;
  4746. }
  4747. else static if (X.mant_dig == double.mant_dig || X.mant_dig == float.mant_dig)
  4748. {
  4749. if (bitsdiff == 0
  4750. && !((pa[F.EXPPOS_SHORT] ^ pb[F.EXPPOS_SHORT]) & F.EXPMASK))
  4751. {
  4752. return 1;
  4753. } else return 0;
  4754. }
  4755. }
  4756. }
  4757. unittest
  4758. {
  4759. void testFeqrel(F)()
  4760. {
  4761. // Exact equality
  4762. assert(feqrel(F.max, F.max) == F.mant_dig);
  4763. assert(feqrel!(F)(0.0, 0.0) == F.mant_dig);
  4764. assert(feqrel(F.infinity, F.infinity) == F.mant_dig);
  4765. // a few bits away from exact equality
  4766. F w=1;
  4767. for (int i = 1; i < F.mant_dig - 1; ++i)
  4768. {
  4769. assert(feqrel!(F)(1.0 + w * F.epsilon, 1.0) == F.mant_dig-i);
  4770. assert(feqrel!(F)(1.0 - w * F.epsilon, 1.0) == F.mant_dig-i);
  4771. assert(feqrel!(F)(1.0, 1 + (w-1) * F.epsilon) == F.mant_dig - i + 1);
  4772. w*=2;
  4773. }
  4774. assert(feqrel!(F)(1.5+F.epsilon, 1.5) == F.mant_dig-1);
  4775. assert(feqrel!(F)(1.5-F.epsilon, 1.5) == F.mant_dig-1);
  4776. assert(feqrel!(F)(1.5-F.epsilon, 1.5+F.epsilon) == F.mant_dig-2);
  4777. // Numbers that are close
  4778. assert(feqrel!(F)(0x1.Bp+84, 0x1.B8p+84) == 5);
  4779. assert(feqrel!(F)(0x1.8p+10, 0x1.Cp+10) == 2);
  4780. assert(feqrel!(F)(1.5 * (1 - F.epsilon), 1.0L) == 2);
  4781. assert(feqrel!(F)(1.5, 1.0) == 1);
  4782. assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);
  4783. // Factors of 2
  4784. assert(feqrel(F.max, F.infinity) == 0);
  4785. assert(feqrel!(F)(2 * (1 - F.epsilon), 1.0L) == 1);
  4786. assert(feqrel!(F)(1.0, 2.0) == 0);
  4787. assert(feqrel!(F)(4.0, 1.0) == 0);
  4788. // Extreme inequality
  4789. assert(feqrel(F.nan, F.nan) == 0);
  4790. assert(feqrel!(F)(0.0L, -F.nan) == 0);
  4791. assert(feqrel(F.nan, F.infinity) == 0);
  4792. assert(feqrel(F.infinity, -F.infinity) == 0);
  4793. assert(feqrel(F.max, -F.max) == 0);
  4794. }
  4795. assert(feqrel(7.1824L, 7.1824L) == real.mant_dig);
  4796. assert(feqrel(real.min_normal / 8, real.min_normal / 17) == 3);
  4797. testFeqrel!(real)();
  4798. testFeqrel!(double)();
  4799. testFeqrel!(float)();
  4800. }
  4801. package: // Not public yet
  4802. /* Return the value that lies halfway between x and y on the IEEE number line.
  4803. *
  4804. * Formally, the result is the arithmetic mean of the binary significands of x
  4805. * and y, multiplied by the geometric mean of the binary exponents of x and y.
  4806. * x and y must have the same sign, and must not be NaN.
  4807. * Note: this function is useful for ensuring O(log n) behaviour in algorithms
  4808. * involving a 'binary chop'.
  4809. *
  4810. * Special cases:
  4811. * If x and y are within a factor of 2, (ie, feqrel(x, y) > 0), the return value
  4812. * is the arithmetic mean (x + y) / 2.
  4813. * If x and y are even powers of 2, the return value is the geometric mean,
  4814. * ieeeMean(x, y) = sqrt(x * y).
  4815. *
  4816. */
  4817. T ieeeMean(T)(T x, T y) @trusted pure nothrow
  4818. in
  4819. {
  4820. // both x and y must have the same sign, and must not be NaN.
  4821. assert(signbit(x) == signbit(y));
  4822. assert(x==x && y==y);
  4823. }
  4824. body
  4825. {
  4826. // Runtime behaviour for contract violation:
  4827. // If signs are opposite, or one is a NaN, return 0.
  4828. if (!((x>=0 && y>=0) || (x<=0 && y<=0))) return 0.0;
  4829. // The implementation is simple: cast x and y to integers,
  4830. // average them (avoiding overflow), and cast the result back to a floating-point number.
  4831. alias floatTraits!(real) F;
  4832. T u;
  4833. static if (T.mant_dig==64)
  4834. { // real80
  4835. // There's slight additional complexity because they are actually
  4836. // 79-bit reals...
  4837. ushort *ue = cast(ushort *)&u;
  4838. ulong *ul = cast(ulong *)&u;
  4839. ushort *xe = cast(ushort *)&x;
  4840. ulong *xl = cast(ulong *)&x;
  4841. ushort *ye = cast(ushort *)&y;
  4842. ulong *yl = cast(ulong *)&y;
  4843. // Ignore the useless implicit bit. (Bonus: this prevents overflows)
  4844. ulong m = ((*xl) & 0x7FFF_FFFF_FFFF_FFFFL) + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL);
  4845. // @@@ BUG? @@@
  4846. // Cast shouldn't be here
  4847. ushort e = cast(ushort) ((xe[F.EXPPOS_SHORT] & F.EXPMASK)
  4848. + (ye[F.EXPPOS_SHORT] & F.EXPMASK));
  4849. if (m & 0x8000_0000_0000_0000L)
  4850. {
  4851. ++e;
  4852. m &= 0x7FFF_FFFF_FFFF_FFFFL;
  4853. }
  4854. // Now do a multi-byte right shift
  4855. uint c = e & 1; // carry
  4856. e >>= 1;
  4857. m >>>= 1;
  4858. if (c)
  4859. m |= 0x4000_0000_0000_0000L; // shift carry into significand
  4860. if (e)
  4861. *ul = m | 0x8000_0000_0000_0000L; // set implicit bit...
  4862. else
  4863. *ul = m; // ... unless exponent is 0 (subnormal or zero).
  4864. ue[4]= e | (xe[F.EXPPOS_SHORT]& 0x8000); // restore sign bit
  4865. }
  4866. else static if(T.mant_dig == 113)
  4867. { //quadruple
  4868. // This would be trivial if 'ucent' were implemented...
  4869. ulong *ul = cast(ulong *)&u;
  4870. ulong *xl = cast(ulong *)&x;
  4871. ulong *yl = cast(ulong *)&y;
  4872. // Multi-byte add, then multi-byte right shift.
  4873. ulong mh = ((xl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL)
  4874. + (yl[MANTISSA_MSB] & 0x7FFF_FFFF_FFFF_FFFFL));
  4875. // Discard the lowest bit (to avoid overflow)
  4876. ulong ml = (xl[MANTISSA_LSB]>>>1) + (yl[MANTISSA_LSB]>>>1);
  4877. // add the lowest bit back in, if necessary.
  4878. if (xl[MANTISSA_LSB] & yl[MANTISSA_LSB] & 1)
  4879. {
  4880. ++ml;
  4881. if (ml==0) ++mh;
  4882. }
  4883. mh >>>=1;
  4884. ul[MANTISSA_MSB] = mh | (xl[MANTISSA_MSB] & 0x8000_0000_0000_0000);
  4885. ul[MANTISSA_LSB] = ml;
  4886. }
  4887. else static if (T.mant_dig == double.mant_dig)
  4888. {
  4889. ulong *ul = cast(ulong *)&u;
  4890. ulong *xl = cast(ulong *)&x;
  4891. ulong *yl = cast(ulong *)&y;
  4892. ulong m = (((*xl) & 0x7FFF_FFFF_FFFF_FFFFL)
  4893. + ((*yl) & 0x7FFF_FFFF_FFFF_FFFFL)) >>> 1;
  4894. m |= ((*xl) & 0x8000_0000_0000_0000L);
  4895. *ul = m;
  4896. }
  4897. else static if (T.mant_dig == float.mant_dig)
  4898. {
  4899. uint *ul = cast(uint *)&u;
  4900. uint *xl = cast(uint *)&x;
  4901. uint *yl = cast(uint *)&y;
  4902. uint m = (((*xl) & 0x7FFF_FFFF) + ((*yl) & 0x7FFF_FFFF)) >>> 1;
  4903. m |= ((*xl) & 0x8000_0000);
  4904. *ul = m;
  4905. }
  4906. else
  4907. {
  4908. assert(0, "Not implemented");
  4909. }
  4910. return u;
  4911. }
  4912. unittest
  4913. {
  4914. assert(ieeeMean(-0.0,-1e-20)<0);
  4915. assert(ieeeMean(0.0,1e-20)>0);
  4916. assert(ieeeMean(1.0L,4.0L)==2L);
  4917. assert(ieeeMean(2.0*1.013,8.0*1.013)==4*1.013);
  4918. assert(ieeeMean(-1.0L,-4.0L)==-2L);
  4919. assert(ieeeMean(-1.0,-4.0)==-2);
  4920. assert(ieeeMean(-1.0f,-4.0f)==-2f);
  4921. assert(ieeeMean(-1.0,-2.0)==-1.5);
  4922. assert(ieeeMean(-1*(1+8*real.epsilon),-2*(1+8*real.epsilon))
  4923. ==-1.5*(1+5*real.epsilon));
  4924. assert(ieeeMean(0x1p60,0x1p-10)==0x1p25);
  4925. static if (real.mant_dig == 64)
  4926. {
  4927. assert(ieeeMean(1.0L,real.infinity)==0x1p8192L);
  4928. assert(ieeeMean(0.0L,real.infinity)==1.5);
  4929. }
  4930. assert(ieeeMean(0.5*real.min_normal*(1-4*real.epsilon),0.5*real.min_normal)
  4931. == 0.5*real.min_normal*(1-2*real.epsilon));
  4932. }
  4933. public:
  4934. /***********************************
  4935. * Evaluate polynomial A(x) = $(SUB a, 0) + $(SUB a, 1)x + $(SUB a, 2)$(POWER x,2)
  4936. * + $(SUB a,3)$(POWER x,3); ...
  4937. *
  4938. * Uses Horner's rule A(x) = $(SUB a, 0) + x($(SUB a, 1) + x($(SUB a, 2)
  4939. * + x($(SUB a, 3) + ...)))
  4940. * Params:
  4941. * x = the value to evaluate.
  4942. * A = array of coefficients $(SUB a, 0), $(SUB a, 1), etc.
  4943. */
  4944. real poly(real x, const real[] A) @trusted pure nothrow
  4945. in
  4946. {
  4947. assert(A.length > 0);
  4948. }
  4949. body
  4950. {
  4951. version (D_InlineAsm_X86)
  4952. {
  4953. version (Windows)
  4954. {
  4955. // BUG: This code assumes a frame pointer in EBP.
  4956. asm // assembler by W. Bright
  4957. {
  4958. // EDX = (A.length - 1) * real.sizeof
  4959. mov ECX,A[EBP] ; // ECX = A.length
  4960. dec ECX ;
  4961. lea EDX,[ECX][ECX*8] ;
  4962. add EDX,ECX ;
  4963. add EDX,A+4[EBP] ;
  4964. fld real ptr [EDX] ; // ST0 = coeff[ECX]
  4965. jecxz return_ST ;
  4966. fld x[EBP] ; // ST0 = x
  4967. fxch ST(1) ; // ST1 = x, ST0 = r
  4968. align 4 ;
  4969. L2: fmul ST,ST(1) ; // r *= x
  4970. fld real ptr -10[EDX] ;
  4971. sub EDX,10 ; // deg--
  4972. faddp ST(1),ST ;
  4973. dec ECX ;
  4974. jne L2 ;
  4975. fxch ST(1) ; // ST1 = r, ST0 = x
  4976. fstp ST(0) ; // dump x
  4977. align 4 ;
  4978. return_ST: ;
  4979. ;
  4980. }
  4981. }
  4982. else version (linux)
  4983. {
  4984. asm // assembler by W. Bright
  4985. {
  4986. // EDX = (A.length - 1) * real.sizeof
  4987. mov ECX,A[EBP] ; // ECX = A.length
  4988. dec ECX ;
  4989. lea EDX,[ECX*8] ;
  4990. lea EDX,[EDX][ECX*4] ;
  4991. add EDX,A+4[EBP] ;
  4992. fld real ptr [EDX] ; // ST0 = coeff[ECX]
  4993. jecxz return_ST ;
  4994. fld x[EBP] ; // ST0 = x
  4995. fxch ST(1) ; // ST1 = x, ST0 = r
  4996. align 4 ;
  4997. L2: fmul ST,ST(1) ; // r *= x
  4998. fld real ptr -12[EDX] ;
  4999. sub EDX,12 ; // deg--
  5000. faddp ST(1),ST ;
  5001. dec ECX ;
  5002. jne L2 ;
  5003. fxch ST(1) ; // ST1 = r, ST0 = x
  5004. fstp ST(0) ; // dump x
  5005. align 4 ;
  5006. return_ST: ;
  5007. ;
  5008. }
  5009. }
  5010. else version (OSX)
  5011. {
  5012. asm // assembler by W. Bright
  5013. {
  5014. // EDX = (A.length - 1) * real.sizeof
  5015. mov ECX,A[EBP] ; // ECX = A.length
  5016. dec ECX ;
  5017. lea EDX,[ECX*8] ;
  5018. add EDX,EDX ;
  5019. add EDX,A+4[EBP] ;
  5020. fld real ptr [EDX] ; // ST0 = coeff[ECX]
  5021. jecxz return_ST ;
  5022. fld x[EBP] ; // ST0 = x
  5023. fxch ST(1) ; // ST1 = x, ST0 = r
  5024. align 4 ;
  5025. L2: fmul ST,ST(1) ; // r *= x
  5026. fld real ptr -16[EDX] ;
  5027. sub EDX,16 ; // deg--
  5028. faddp ST(1),ST ;
  5029. dec ECX ;
  5030. jne L2 ;
  5031. fxch ST(1) ; // ST1 = r, ST0 = x
  5032. fstp ST(0) ; // dump x
  5033. align 4 ;
  5034. return_ST: ;
  5035. ;
  5036. }
  5037. }
  5038. else version (FreeBSD)
  5039. {
  5040. asm // assembler by W. Bright
  5041. {
  5042. // EDX = (A.length - 1) * real.sizeof
  5043. mov ECX,A[EBP] ; // ECX = A.length
  5044. dec ECX ;
  5045. lea EDX,[ECX*8] ;
  5046. lea EDX,[EDX][ECX*4] ;
  5047. add EDX,A+4[EBP] ;
  5048. fld real ptr [EDX] ; // ST0 = coeff[ECX]
  5049. jecxz return_ST ;
  5050. fld x[EBP] ; // ST0 = x
  5051. fxch ST(1) ; // ST1 = x, ST0 = r
  5052. align 4 ;
  5053. L2: fmul ST,ST(1) ; // r *= x
  5054. fld real ptr -12[EDX] ;
  5055. sub EDX,12 ; // deg--
  5056. faddp ST(1),ST ;
  5057. dec ECX ;
  5058. jne L2 ;
  5059. fxch ST(1) ; // ST1 = r, ST0 = x
  5060. fstp ST(0) ; // dump x
  5061. align 4 ;
  5062. return_ST: ;
  5063. ;
  5064. }
  5065. }
  5066. else
  5067. {
  5068. static assert(0);
  5069. }
  5070. }
  5071. else
  5072. {
  5073. ptrdiff_t i = A.length - 1;
  5074. real r = A[i];
  5075. while (--i >= 0)
  5076. {
  5077. r *= x;
  5078. r += A[i];
  5079. }
  5080. return r;
  5081. }
  5082. }
  5083. unittest
  5084. {
  5085. debug (math) printf("math.poly.unittest\n");
  5086. real x = 3.1;
  5087. static real[] pp = [56.1, 32.7, 6];
  5088. assert( poly(x, pp) == (56.1L + (32.7L + 6L * x) * x) );
  5089. }
  5090. /**
  5091. Computes whether $(D lhs) is approximately equal to $(D rhs)
  5092. admitting a maximum relative difference $(D maxRelDiff) and a
  5093. maximum absolute difference $(D maxAbsDiff).
  5094. If the two inputs are ranges, $(D approxEqual) returns true if and
  5095. only if the ranges have the same number of elements and if $(D
  5096. approxEqual) evaluates to $(D true) for each pair of elements.
  5097. */
  5098. bool approxEqual(T, U, V)(T lhs, U rhs, V maxRelDiff, V maxAbsDiff = 1e-5)
  5099. {
  5100. import std.range;
  5101. static if (isInputRange!T)
  5102. {
  5103. static if (isInputRange!U)
  5104. {
  5105. // Two ranges
  5106. for (;; lhs.popFront(), rhs.popFront())
  5107. {
  5108. if (lhs.empty) return rhs.empty;
  5109. if (rhs.empty) return lhs.empty;
  5110. if (!approxEqual(lhs.front, rhs.front, maxRelDiff, maxAbsDiff))
  5111. return false;
  5112. }
  5113. }
  5114. else
  5115. {
  5116. // lhs is range, rhs is number
  5117. for (; !lhs.empty; lhs.popFront())
  5118. {
  5119. if (!approxEqual(lhs.front, rhs, maxRelDiff, maxAbsDiff))
  5120. return false;
  5121. }
  5122. return true;
  5123. }
  5124. }
  5125. else
  5126. {
  5127. static if (isInputRange!U)
  5128. {
  5129. // lhs is number, rhs is array
  5130. return approxEqual(rhs, lhs, maxRelDiff, maxAbsDiff);
  5131. }
  5132. else
  5133. {
  5134. // two numbers
  5135. //static assert(is(T : real) && is(U : real));
  5136. if (rhs == 0)
  5137. {
  5138. return fabs(lhs) <= maxAbsDiff;
  5139. }
  5140. static if (is(typeof(lhs.infinity)) && is(typeof(rhs.infinity)))
  5141. {
  5142. if (lhs == lhs.infinity && rhs == rhs.infinity ||
  5143. lhs == -lhs.infinity && rhs == -rhs.infinity) return true;
  5144. }
  5145. return fabs((lhs - rhs) / rhs) <= maxRelDiff
  5146. || maxAbsDiff != 0 && fabs(lhs - rhs) <= maxAbsDiff;
  5147. }
  5148. }
  5149. }
  5150. /**
  5151. Returns $(D approxEqual(lhs, rhs, 1e-2, 1e-5)).
  5152. */
  5153. bool approxEqual(T, U)(T lhs, U rhs)
  5154. {
  5155. return approxEqual(lhs, rhs, 1e-2, 1e-5);
  5156. }
  5157. unittest
  5158. {
  5159. assert(approxEqual(1.0, 1.0099));
  5160. assert(!approxEqual(1.0, 1.011));
  5161. float[] arr1 = [ 1.0, 2.0, 3.0 ];
  5162. double[] arr2 = [ 1.001, 1.999, 3 ];
  5163. assert(approxEqual(arr1, arr2));
  5164. real num = real.infinity;
  5165. assert(num == real.infinity); // Passes.
  5166. assert(approxEqual(num, real.infinity)); // Fails.
  5167. num = -real.infinity;
  5168. assert(num == -real.infinity); // Passes.
  5169. assert(approxEqual(num, -real.infinity)); // Fails.
  5170. }
  5171. // Included for backwards compatibility with Phobos1
  5172. alias isNaN isnan;
  5173. alias isFinite isfinite;
  5174. alias isNormal isnormal;
  5175. alias isSubnormal issubnormal;
  5176. alias isInfinity isinf;
  5177. /* **********************************
  5178. * Building block functions, they
  5179. * translate to a single x87 instruction.
  5180. */
  5181. real yl2x(real x, real y) @safe pure nothrow; // y * log2(x)
  5182. real yl2xp1(real x, real y) @safe pure nothrow; // y * log2(x + 1)
  5183. unittest
  5184. {
  5185. version (INLINE_YL2X)
  5186. {
  5187. assert(yl2x(1024, 1) == 10);
  5188. assert(yl2xp1(1023, 1) == 10);
  5189. }
  5190. }
  5191. unittest
  5192. {
  5193. real num = real.infinity;
  5194. assert(num == real.infinity); // Passes.
  5195. assert(approxEqual(num, real.infinity)); // Fails.
  5196. }
  5197. unittest
  5198. {
  5199. float f = sqrt(2.0f);
  5200. assert(fabs(f * f - 2.0f) < .00001);
  5201. double d = sqrt(2.0);
  5202. assert(fabs(d * d - 2.0) < .00001);
  5203. real r = sqrt(2.0L);
  5204. assert(fabs(r * r - 2.0) < .00001);
  5205. }
  5206. unittest
  5207. {
  5208. float f = fabs(-2.0f);
  5209. assert(f == 2);
  5210. double d = fabs(-2.0);
  5211. assert(d == 2);
  5212. real r = fabs(-2.0L);
  5213. assert(r == 2);
  5214. }
  5215. unittest
  5216. {
  5217. float f = sin(-2.0f);
  5218. assert(fabs(f - -0.909297f) < .00001);
  5219. double d = sin(-2.0);
  5220. assert(fabs(d - -0.909297f) < .00001);
  5221. real r = sin(-2.0L);
  5222. assert(fabs(r - -0.909297f) < .00001);
  5223. }
  5224. unittest
  5225. {
  5226. float f = cos(-2.0f);
  5227. assert(fabs(f - -0.416147f) < .00001);
  5228. double d = cos(-2.0);
  5229. assert(fabs(d - -0.416147f) < .00001);
  5230. real r = cos(-2.0L);
  5231. assert(fabs(r - -0.416147f) < .00001);
  5232. }
  5233. unittest
  5234. {
  5235. float f = tan(-2.0f);
  5236. assert(fabs(f - 2.18504f) < .00001);
  5237. double d = tan(-2.0);
  5238. assert(fabs(d - 2.18504f) < .00001);
  5239. real r = tan(-2.0L);
  5240. assert(fabs(r - 2.18504f) < .00001);
  5241. }
  5242. pure @safe nothrow unittest
  5243. {
  5244. // issue 6381: floor/ceil should be usable in pure function.
  5245. auto x = floor(1.2);
  5246. auto y = ceil(1.2);
  5247. }