diff --git a/std/math/algebraic.d b/std/math/algebraic.d index 47b0c8eac..f69033ef1 100644 --- a/std/math/algebraic.d +++ b/std/math/algebraic.d @@ -63,7 +63,7 @@ if ((is(immutable Num == immutable short) || is(immutable Num == immutable byte) /// ditto @safe pure nothrow @nogc unittest { - import std.math : isIdentical, isNaN; + import std.math.traits : isIdentical, isNaN; assert(isIdentical(abs(-0.0L), 0.0L)); assert(isNaN(abs(real.nan))); @@ -147,7 +147,7 @@ float fabs(float f) @trusted pure nothrow @nogc /// @safe unittest { - import std.math : isIdentical; + import std.math.traits : isIdentical; assert(isIdentical(fabs(0.0f), 0.0f)); assert(isIdentical(fabs(-0.0f), 0.0f)); @@ -204,7 +204,8 @@ real sqrt(real x) @nogc @safe pure nothrow { return core.math.sqrt(x); } /// @safe pure nothrow @nogc unittest { - import std.math : feqrel, isNaN; + import std.math.operations : feqrel; + import std.math.traits : isNaN; assert(sqrt(2.0).feqrel(1.4142) > 16); assert(sqrt(9.0).feqrel(3.0) > 16); @@ -255,7 +256,8 @@ real cbrt(real x) @trusted nothrow @nogc { version (CRuntime_Microsoft) { - import std.math : copysign, exp2; + import std.math.traits : copysign; + import std.math.exponential : exp2; version (INLINE_YL2X) return copysign(exp2(core.math.yl2x(fabs(x), 1.0L/3.0L)), x); @@ -269,7 +271,7 @@ real cbrt(real x) @trusted nothrow @nogc /// @safe unittest { - import std.math : feqrel; + import std.math.operations : feqrel; assert(cbrt(1.0).feqrel(1.0) > 16); assert(cbrt(27.0).feqrel(3.0) > 16); @@ -351,7 +353,7 @@ real hypot(real x, real y) @safe pure nothrow @nogc /// @safe unittest { - import std.math : feqrel; + import std.math.operations : feqrel; assert(hypot(1.0, 1.0).feqrel(1.4142) > 16); assert(hypot(3.0, 4.0).feqrel(5.0) > 16); @@ -361,7 +363,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc @safe unittest { - import std.math : feqrel, isIdentical; + import std.math.operations : feqrel; + import std.math.traits : isIdentical; static real[3][] vals = // x,y,hypot [ @@ -415,7 +418,7 @@ real hypot(real x, real y) @safe pure nothrow @nogc T hypot(T)(const T x, const T y, const T z) @safe pure nothrow @nogc if (isFloatingPoint!T) { - import std.math : fmax; + import std.math.operations : fmax; const absx = fabs(x); const absy = fabs(y); const absz = fabs(z); @@ -433,7 +436,7 @@ if (isFloatingPoint!T) /// @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(hypot(1.0, 2.0, 2.0), 3.0)); assert(isClose(hypot(2.0, 3.0, 6.0), 7.0)); @@ -443,7 +446,8 @@ if (isFloatingPoint!T) @safe unittest { import std.meta : AliasSeq; - import std.math : isIdentical, isClose; + import std.math.traits : isIdentical; + import std.math.operations : isClose; static foreach (T; AliasSeq!(float, double, real)) {{ static T[4][] vals = [ @@ -825,7 +829,7 @@ if (isFloatingPoint!T) @safe @nogc pure nothrow unittest { - import std.math : isNaN; + import std.math.traits : isNaN; import std.meta : AliasSeq; static foreach (T; AliasSeq!(float, double, real)) @@ -957,7 +961,7 @@ if (isFloatingPoint!T) @safe @nogc pure nothrow unittest { - import std.math : isNaN; + import std.math.traits : isNaN; import std.meta : AliasSeq; static foreach (T; AliasSeq!(float, double, real)) @@ -1005,7 +1009,8 @@ private T powIntegralImpl(PowType type, T)(T val) private T powFloatingPointImpl(PowType type, T)(T x) { - import std.math : copysign, frexp, isFinite, ldexp; + import std.math.traits : copysign, isFinite; + import std.math.exponential : frexp, ldexp; if (!x.isFinite) return x; diff --git a/std/math/exponential.d b/std/math/exponential.d index 45aa14bd6..ae7b1406f 100644 --- a/std/math/exponential.d +++ b/std/math/exponential.d @@ -64,7 +64,9 @@ version (D_HardFloat) Unqual!F pow(F, G)(F x, G n) @nogc @trusted pure nothrow if (isFloatingPoint!(F) && isIntegral!(G)) { - import std.math : abs, floor, isNaN, log2; + import std.math.algebraic : abs; + import std.math.rounding : floor; + import std.math.traits : isNaN; import std.traits : Unsigned; // NaN ^^ 0 is an exception defined by IEEE (yields 1 instead of NaN) @@ -174,7 +176,7 @@ if (isFloatingPoint!(F) && isIntegral!(G)) /// @safe pure nothrow @nogc unittest { - import std.math : feqrel; + import std.math.operations : feqrel; assert(pow(2.0, 5) == 32.0); assert(pow(1.5, 9).feqrel(38.4433) > 16); @@ -184,7 +186,7 @@ if (isFloatingPoint!(F) && isIntegral!(G)) @safe pure nothrow @nogc unittest { - import std.math : isClose, feqrel; + import std.math.operations : isClose, feqrel; // Make sure it instantiates and works properly on immutable values and // with various integer and float types. @@ -218,7 +220,7 @@ if (isFloatingPoint!(F) && isIntegral!(G)) @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(pow(2.0L, 10L), 1024, 1e-18)); } @@ -241,7 +243,8 @@ if (isFloatingPoint!(F) && isIntegral!(G)) @safe @nogc nothrow unittest { - import std.math : isClose, isInfinity; + import std.math.operations : isClose; + import std.math.traits : isInfinity; static float f1 = 19100.0f; static float f2 = 0.000012f; @@ -273,7 +276,7 @@ if (isFloatingPoint!(F) && isIntegral!(G)) @safe @nogc nothrow pure unittest { - import std.math : isClose; + import std.math.operations : isClose; enum f1 = 19100.0f; enum f2 = 0.000012f; @@ -487,7 +490,8 @@ if (isIntegral!I && isFloatingPoint!F) Unqual!(Largest!(F, G)) pow(F, G)(F x, G y) @nogc @trusted pure nothrow if (isFloatingPoint!(F) && isFloatingPoint!(G)) { - import std.math : exp2, fabs, isInfinity, isNaN, log2, signbit, sqrt; + import std.math.algebraic : fabs, sqrt; + import std.math.traits : isInfinity, isNaN, signbit; alias Float = typeof(return); @@ -701,7 +705,7 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) /// @safe pure nothrow @nogc unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(pow(2.0, 3.0), 8.0)); assert(isClose(pow(1.5, 10.0), 57.6650390625)); @@ -734,11 +738,11 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) /// @safe pure nothrow @nogc unittest { - import std.math : isClose; + import std.math.operations : isClose; // the result is a complex number // which cannot be represented as floating point number - import std.math : isNaN; + import std.math.traits : isNaN; assert(isNaN(pow(-2.5, -1.5))); // use the ^^-operator of std.complex instead @@ -753,7 +757,7 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(pow(1.5, real.infinity) == real.infinity); assert(pow(0.5, real.infinity) == 0.0); @@ -775,14 +779,16 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(pow(2.0L, 10.0L), 1024, 1e-18)); } @safe pure nothrow @nogc unittest { - import std.math : isClose, isIdentical, isNaN, PI; + import std.math.operations : isClose; + import std.math.traits : isIdentical, isNaN; + import std.math.constants : PI; // Test all the special values. These unittests can be run on Windows // by temporarily changing the version (linux) to version (all). @@ -852,7 +858,7 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) // https://issues.dlang.org/show_bug.cgi?id=20508 @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(isNaN(pow(-double.infinity, 0.5))); @@ -876,7 +882,7 @@ if (isFloatingPoint!(F) && isFloatingPoint!(G)) pragma(inline, true) real exp(real x) @trusted pure nothrow @nogc // TODO: @safe { - import std.math : LOG2E; + import std.math.constants : LOG2E; version (InlineAsm_X87) { @@ -900,7 +906,8 @@ float exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(ca /// @safe unittest { - import std.math : feqrel, E; + import std.math.operations : feqrel; + import std.math.constants : E; assert(exp(0.0) == 1.0); assert(exp(3.0).feqrel(E * E * E) > 16); @@ -908,7 +915,11 @@ float exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(ca private T expImpl(T)(T x) @safe pure nothrow @nogc { - import std.math : floatTraits, RealFormat, isNaN, floor, poly, LOG2E; + import std.math : floatTraits, RealFormat; + import std.math.traits : isNaN; + import std.math.rounding : floor; + import std.math.algebraic : poly; + import std.math.constants : LOG2E; alias F = floatTraits!T; static if (F.realFormat == RealFormat.ieeeSingle) @@ -1045,12 +1056,16 @@ private T expImpl(T)(T x) @safe pure nothrow @nogc @safe @nogc nothrow unittest { - import std.math : floatTraits, RealFormat, NaN, E, feqrel, isIdentical, abs, isClose; + import std.math : floatTraits, RealFormat; + import std.math.operations : NaN, feqrel, isClose; + import std.math.constants : E; + import std.math.traits : isIdentical; + import std.math.algebraic : abs; - version (IeeeFlagsSupport) import std.math : IeeeFlags, resetIeeeFlags, ieeeFlags; + version (IeeeFlagsSupport) import std.math.hardware : IeeeFlags, resetIeeeFlags, ieeeFlags; version (FloatingPointControlSupport) { - import std.math : FloatingPointControl; + import std.math.hardware : FloatingPointControl; FloatingPointControl ctrl; if (FloatingPointControl.hasExceptionTraps) @@ -1237,7 +1252,8 @@ float expm1(float x) @safe pure nothrow @nogc /// @safe unittest { - import std.math : isIdentical, feqrel; + import std.math.traits : isIdentical; + import std.math.operations : feqrel; assert(isIdentical(expm1(0.0), 0.0)); assert(expm1(1.0).feqrel(1.71828) > 16); @@ -1414,7 +1430,10 @@ L_largenegative: private T expm1Impl(T)(T x) @safe pure nothrow @nogc { - import std.math : floatTraits, RealFormat, floor, poly, LN2; + import std.math : floatTraits, RealFormat; + import std.math.rounding : floor; + import std.math.algebraic : poly; + import std.math.constants : LN2; // Coefficients for exp(x) - 1 and overflow/underflow limits. enum realFormat = floatTraits!T.realFormat; @@ -1533,7 +1552,8 @@ private T expm1Impl(T)(T x) @safe pure nothrow @nogc @safe @nogc nothrow unittest { - import std.math : isNaN, isClose, CommonDefaultFor; + import std.math.traits : isNaN; + import std.math.operations : isClose, CommonDefaultFor; static void testExpm1(T)() { @@ -1588,7 +1608,8 @@ float exp2(float x) @nogc @safe pure nothrow { return __ctfe ? cast(float) exp2( /// @safe unittest { - import std.math : isIdentical, feqrel; + import std.math.traits : isIdentical; + import std.math.operations : feqrel; assert(isIdentical(exp2(0.0), 1.0)); assert(exp2(2.0).feqrel(4.0) > 16); @@ -1801,7 +1822,10 @@ L_was_nan: private T exp2Impl(T)(T x) @nogc @safe pure nothrow { - import std.math : floatTraits, RealFormat, isNaN, floor, poly; + import std.math : floatTraits, RealFormat; + import std.math.traits : isNaN; + import std.math.rounding : floor; + import std.math.algebraic : poly; // Coefficients for exp2(x) enum realFormat = floatTraits!T.realFormat; @@ -1920,7 +1944,9 @@ private T exp2Impl(T)(T x) @nogc @safe pure nothrow @safe @nogc nothrow unittest { - import std.math : feqrel, NaN, isIdentical, SQRT2, isClose; + import std.math.operations : feqrel, NaN, isClose; + import std.math.traits : isIdentical; + import std.math.constants : SQRT2; assert(feqrel(exp2(0.5L), SQRT2) >= real.mant_dig -1); assert(exp2(8.0L) == 256.0); @@ -1985,7 +2011,8 @@ private T exp2Impl(T)(T x) @nogc @safe pure nothrow T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc if (isFloatingPoint!T) { - import std.math : isSubnormal, floatTraits, RealFormat; + import std.math : floatTraits, RealFormat; + import std.math.traits : isSubnormal; if (__ctfe) { @@ -2211,7 +2238,7 @@ if (isFloatingPoint!T) /// @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; int exp; real mantissa = frexp(123.456L, exp); @@ -2228,7 +2255,7 @@ if (isFloatingPoint!T) @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; int exp; real mantissa = frexp(123.456L, exp); @@ -2239,7 +2266,8 @@ if (isFloatingPoint!T) @safe unittest { - import std.math : isIdentical, floatTraits, RealFormat; + import std.math : floatTraits, RealFormat; + import std.math.traits : isIdentical; import std.meta : AliasSeq; import std.typecons : tuple, Tuple; @@ -2570,7 +2598,8 @@ alias FP_ILOGBNAN = core.stdc.math.FP_ILOGBNAN; @safe nothrow @nogc unittest { - import std.math : nextUp, floatTraits, RealFormat; + import std.math : floatTraits, RealFormat; + import std.math.operations : nextUp; import std.meta : AliasSeq; import std.typecons : Tuple; static foreach (F; AliasSeq!(float, double, real)) @@ -2720,7 +2749,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return core.math.ldex @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; static real[3][] vals = // value,exp,ldexp [ @@ -2861,7 +2890,9 @@ private */ real log(real x) @safe pure nothrow @nogc { - import std.math : LN2, LOG2, isInfinity, isNaN, signbit, SQRT1_2, poly; + import std.math.constants : LN2, LOG2, SQRT1_2; + import std.math.traits : isInfinity, isNaN, signbit; + import std.math.algebraic : poly; version (INLINE_YL2X) return core.math.yl2x(x, LN2); @@ -2941,7 +2972,8 @@ real log(real x) @safe pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : feqrel, E; + import std.math.operations : feqrel; + import std.math.constants : E; assert(feqrel(log(E), 1) >= real.mant_dig - 1); } @@ -2958,7 +2990,9 @@ real log(real x) @safe pure nothrow @nogc */ real log10(real x) @safe pure nothrow @nogc { - import std.math : LOG2, LN2, fabs, isNaN, isInfinity, signbit, SQRT1_2; + import std.math.constants : LOG2, LN2, SQRT1_2; + import std.math.algebraic : fabs; + import std.math.traits : isNaN, isInfinity, signbit; version (INLINE_YL2X) return core.math.yl2x(x, LOG2); @@ -3042,7 +3076,7 @@ real log10(real x) @safe pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : fabs; + import std.math.algebraic : fabs; assert(fabs(log10(1000) - 3) < .000001); } @@ -3063,7 +3097,9 @@ real log10(real x) @safe pure nothrow @nogc */ real log1p(real x) @safe pure nothrow @nogc { - import std.math : fabs, isNaN, isInfinity, signbit, LN2; + import std.math.algebraic : fabs; + import std.math.traits : isNaN, isInfinity, signbit; + import std.math.constants : LN2; version (INLINE_YL2X) { @@ -3090,7 +3126,8 @@ real log1p(real x) @safe pure nothrow @nogc /// @safe pure unittest { - import std.math : isIdentical, isNaN, feqrel; + import std.math.traits : isIdentical, isNaN; + import std.math.operations : feqrel; assert(isIdentical(log1p(0.0), 0.0)); assert(log1p(1.0).feqrel(0.69314) > 16); @@ -3115,7 +3152,9 @@ real log1p(real x) @safe pure nothrow @nogc */ real log2(real x) @safe pure nothrow @nogc { - import std.math : isNaN, isInfinity, signbit, SQRT1_2, poly; + import std.math.traits : isNaN, isInfinity, signbit; + import std.math.constants : SQRT1_2; + import std.math.algebraic : poly; version (INLINE_YL2X) return core.math.yl2x(x, 1.0L); @@ -3190,14 +3229,14 @@ real log2(real x) @safe pure nothrow @nogc /// @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(log2(1024.0L), 10)); } @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; // check if values are equal to 19 decimal digits of precision assert(isClose(log2(1024.0L), 10, 1e-18)); @@ -3292,7 +3331,7 @@ float scalbn(float x, int n) @safe pure nothrow @nogc { return _scalbn(x,n); } pragma(inline, true) private F _scalbn(F)(F x, int n) { - import std.math : isInfinity; + import std.math.traits : isInfinity; if (__ctfe) { diff --git a/std/math/hardware.d b/std/math/hardware.d index 4bb277cd2..7ca27e1e5 100644 --- a/std/math/hardware.d +++ b/std/math/hardware.d @@ -245,7 +245,7 @@ public: /// @safe unittest { - import std.math : isNaN; + import std.math.traits : isNaN; static void func() { int a = 10 * 10; @@ -350,7 +350,7 @@ void resetIeeeFlags() @trusted nothrow @nogc /// @safe nothrow unittest { - import std.math : isNaN; + import std.math.traits : isNaN; pragma(inline, false) static void blockopt(ref real x) {} resetIeeeFlags(); @@ -854,7 +854,7 @@ private: /// @safe unittest { - import std.math : lrint; + import std.math.rounding : lrint; FloatingPointControl fpctrl; diff --git a/std/math/operations.d b/std/math/operations.d index 45390044c..591174851 100644 --- a/std/math/operations.d +++ b/std/math/operations.d @@ -127,7 +127,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc /// @safe @nogc pure nothrow unittest { - import std.math : isNaN; + import std.math.traits : isNaN; real a = NaN(1_000_000); assert(isNaN(a)); @@ -212,7 +212,7 @@ ulong getNaNPayload(real x) @trusted pure nothrow @nogc /// @safe @nogc pure nothrow unittest { - import std.math : isNaN; + import std.math.traits : isNaN; real a = NaN(1_000_000); assert(isNaN(a)); @@ -221,7 +221,7 @@ ulong getNaNPayload(real x) @trusted pure nothrow @nogc @safe @nogc pure nothrow unittest { - import std.math : isIdentical, isNaN; + import std.math.traits : isIdentical, isNaN; enum real a = NaN(1_000_000); static assert(isNaN(a)); @@ -522,7 +522,8 @@ float nextDown(float x) @safe pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : floatTraits, RealFormat, isIdentical; + import std.math : floatTraits, RealFormat; + import std.math.traits : isIdentical; static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended || floatTraits!(real).realFormat == RealFormat.ieeeDouble || @@ -662,7 +663,7 @@ float nextDown(float x) @safe pure nothrow @nogc */ T nextafter(T)(const T x, const T y) @safe pure nothrow @nogc { - import std.math : isNaN; + import std.math.traits : isNaN; if (x == y || isNaN(y)) { @@ -680,7 +681,7 @@ T nextafter(T)(const T x, const T y) @safe pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; float a = 1; assert(is(typeof(nextafter(a, a)) == float)); @@ -703,7 +704,7 @@ T nextafter(T)(const T x, const T y) @safe pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : isNaN, signbit; + import std.math.traits : isNaN, signbit; // CTFE enum float a = 1; @@ -753,7 +754,7 @@ real fdim(real x, real y) @safe pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(fdim(2.0, 0.0) == 2.0); assert(fdim(-2.0, 0.0) == 0.0); @@ -773,7 +774,7 @@ real fdim(real x, real y) @safe pure nothrow @nogc F fmax(F)(const F x, const F y) @safe pure nothrow @nogc if (__traits(isFloating, F)) { - import std.math : isNaN; + import std.math.traits : isNaN; // Do the more predictable test first. Generates 0 branches with ldc and 1 branch with gdc. // See https://godbolt.org/z/erxrW9 @@ -805,7 +806,7 @@ if (__traits(isFloating, F)) F fmin(F)(const F x, const F y) @safe pure nothrow @nogc if (__traits(isFloating, F)) { - import std.math : isNaN; + import std.math.traits : isNaN; // Do the more predictable test first. Generates 0 branches with ldc and 1 branch with gdc. // See https://godbolt.org/z/erxrW9 @@ -864,7 +865,8 @@ real fma(real x, real y, real z) @safe pure nothrow @nogc { return (x * y) + z; int feqrel(X)(const X x, const X y) @trusted pure nothrow @nogc if (isFloatingPoint!(X)) { - import std.math : floatTraits, RealFormat, fabs; + import std.math : floatTraits, RealFormat; + import std.math.algebraic : fabs; /* Public Domain. Author: Don Clugston, 18 Aug 2005. */ @@ -1033,7 +1035,7 @@ if (isFloatingPoint!(X)) deprecated("approxEqual will be removed in 2.106.0. Please use isClose instead.") bool approxEqual(T, U, V)(T value, U reference, V maxRelDiff = 1e-2, V maxAbsDiff = 1e-5) { - import std.math : fabs; + import std.math.algebraic : fabs; import std.range.primitives : empty, front, isInputRange, popFront; static if (isInputRange!T) { @@ -1287,7 +1289,7 @@ bool isClose(T, U, V = CommonType!(FloatingPointBaseType!T,FloatingPointBaseType lhs == -lhs.infinity || rhs == -rhs.infinity) return false; } - import std.math : abs; + import std.math.algebraic : abs; auto diff = abs(lhs - rhs); @@ -1594,7 +1596,7 @@ if (isFloatingPoint!T) // IBM Extended doubledouble does not follow the general // sign-exponent-significand layout, so has to be handled generically - import std.math : signbit, isNaN, getNaNPayload; + import std.math.traits : signbit, isNaN; const int xSign = signbit(x), ySign = signbit(y); diff --git a/std/math/remainder.d b/std/math/remainder.d index 7eeafd333..876671391 100644 --- a/std/math/remainder.d +++ b/std/math/remainder.d @@ -51,7 +51,8 @@ real fmod(real x, real y) @trusted nothrow @nogc /// @safe unittest { - import std.math : feqrel, isIdentical, isNaN; + import std.math.operations : feqrel; + import std.math.traits : isIdentical, isNaN; assert(isIdentical(fmod(0.0, 1.0), 0.0)); assert(fmod(5.0, 3.0).feqrel(2.0) > 16); @@ -73,7 +74,8 @@ real modf(real x, ref real i) @trusted nothrow @nogc { version (CRuntime_Microsoft) { - import std.math : copysign, isInfinity, trunc; + import std.math.traits : copysign, isInfinity; + import std.math.rounding : trunc; i = trunc(x); return copysign(isInfinity(x) ? 0.0 : x - i, x); @@ -85,7 +87,7 @@ real modf(real x, ref real i) @trusted nothrow @nogc /// @safe unittest { - import std.math : feqrel; + import std.math.operations : feqrel; real frac; real intpart; @@ -129,7 +131,8 @@ real remquo(real x, real y, out int n) @trusted nothrow @nogc /// ditto /// @safe @nogc nothrow unittest { - import std.math : feqrel, isNaN; + import std.math.operations : feqrel; + import std.math.traits : isNaN; assert(remainder(5.1, 3.0).feqrel(-0.9) > 16); assert(remainder(-5.1, 3.0).feqrel(0.9) > 16); @@ -142,7 +145,7 @@ real remquo(real x, real y, out int n) @trusted nothrow @nogc /// ditto /// @safe @nogc nothrow unittest { - import std.math : feqrel; + import std.math.operations : feqrel; int n; diff --git a/std/math/rounding.d b/std/math/rounding.d index 9f077c727..39396958c 100644 --- a/std/math/rounding.d +++ b/std/math/rounding.d @@ -83,7 +83,7 @@ real ceil(real x) @trusted pure nothrow @nogc } else { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) @@ -100,7 +100,7 @@ real ceil(real x) @trusted pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(ceil(+123.456L) == +124); assert(ceil(-123.456L) == -123); @@ -117,7 +117,7 @@ real ceil(real x) @trusted pure nothrow @nogc /// ditto double ceil(double x) @trusted pure nothrow @nogc { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) @@ -132,7 +132,7 @@ double ceil(double x) @trusted pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(ceil(+123.456) == +124); assert(ceil(-123.456) == -123); @@ -149,7 +149,7 @@ double ceil(double x) @trusted pure nothrow @nogc /// ditto float ceil(float x) @trusted pure nothrow @nogc { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x)) @@ -164,7 +164,7 @@ float ceil(float x) @trusted pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(ceil(+123.456f) == +124); assert(ceil(-123.456f) == -123); @@ -226,7 +226,7 @@ real floor(real x) @trusted pure nothrow @nogc } else { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) @@ -239,7 +239,7 @@ real floor(real x) @trusted pure nothrow @nogc /// @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(floor(+123.456L) == +123); assert(floor(-123.456L) == -124); @@ -258,7 +258,7 @@ real floor(real x) @trusted pure nothrow @nogc /// ditto double floor(double x) @trusted pure nothrow @nogc { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) @@ -269,7 +269,7 @@ double floor(double x) @trusted pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(floor(+123.456) == +123); assert(floor(-123.456) == -124); @@ -288,7 +288,7 @@ double floor(double x) @trusted pure nothrow @nogc /// ditto float floor(float x) @trusted pure nothrow @nogc { - import std.math : isInfinity, isNaN; + import std.math.traits : isInfinity, isNaN; // Special cases. if (isNaN(x) || isInfinity(x) || x == 0.0) @@ -299,7 +299,7 @@ float floor(float x) @trusted pure nothrow @nogc @safe pure nothrow @nogc unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(floor(+123.456f) == +123); assert(floor(-123.456f) == -124); @@ -331,7 +331,7 @@ float floor(float x) @trusted pure nothrow @nogc Unqual!F quantize(alias rfunc = rint, F)(const F val, const F unit) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) { - import std.math : isInfinity; + import std.math.traits : isInfinity; typeof(return) ret = val; if (unit != 0) @@ -346,7 +346,7 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) /// @safe pure nothrow @nogc unittest { - import std.math : floor, isClose; + import std.math.operations : isClose; assert(isClose(12345.6789L.quantize(0.01L), 12345.68L)); assert(isClose(12345.6789L.quantize!floor(0.01L), 12345.67L)); @@ -356,7 +356,8 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) /// @safe pure nothrow @nogc unittest { - import std.math : isClose, isNaN; + import std.math.operations : isClose; + import std.math.traits : isNaN; assert(isClose(12345.6789L.quantize(0), 12345.6789L)); assert(12345.6789L.quantize(real.infinity).isNaN); @@ -376,7 +377,7 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) Unqual!F quantize(real base, alias rfunc = rint, F, E)(const F val, const E exp) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E) { - import std.math : pow; + import std.math.exponential : pow; // TODO: Compile-time optimization for power-of-two bases? return quantize!rfunc(val, pow(cast(F) base, exp)); @@ -386,7 +387,7 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F && isIntegral!E) Unqual!F quantize(real base, long exp = 1, alias rfunc = rint, F)(const F val) if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) { - import std.math : pow; + import std.math.exponential : pow; enum unit = cast(F) pow(base, exp); return quantize!rfunc(val, unit); @@ -395,7 +396,7 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) /// @safe pure nothrow @nogc unittest { - import std.math : floor, isClose; + import std.math.operations : isClose; assert(isClose(12345.6789L.quantize!10(-2), 12345.68L)); assert(isClose(12345.6789L.quantize!(10, -2), 12345.68L)); @@ -408,7 +409,8 @@ if (is(typeof(rfunc(F.init)) : F) && isFloatingPoint!F) @safe pure nothrow @nogc unittest { - import std.math : floor, log10, pow, isClose; + import std.math.exponential : log10, pow; + import std.math.operations : isClose; import std.meta : AliasSeq; static foreach (F; AliasSeq!(real, double, float)) @@ -443,7 +445,7 @@ real nearbyint(real x) @safe pure nothrow @nogc /// @safe pure unittest { - import std.math : isNaN; + import std.math.traits : isNaN; assert(nearbyint(0.4) == 0); assert(nearbyint(0.5) == 0); @@ -486,7 +488,7 @@ float rint(float x) @safe pure nothrow @nogc /// @safe unittest { - import std.math : isNaN; + import std.math.traits : isNaN; version (IeeeFlagsSupport) resetIeeeFlags(); assert(rint(0.4) == 0); @@ -731,7 +733,7 @@ auto round(real x) @trusted nothrow @nogc { version (CRuntime_Microsoft) { - import std.math : FloatingPointControl; + import std.math.hardware : FloatingPointControl; auto old = FloatingPointControl.getControlState(); FloatingPointControl.setControlState( diff --git a/std/math/traits.d b/std/math/traits.d index a89ddb359..c15e8f203 100644 --- a/std/math/traits.d +++ b/std/math/traits.d @@ -722,7 +722,7 @@ Returns: bool isPowerOf2(X)(const X x) pure @safe nothrow @nogc if (isNumeric!X) { - import std.math : frexp; + import std.math.exponential : frexp; static if (isFloatingPoint!X) { @@ -748,7 +748,7 @@ if (isNumeric!X) /// @safe unittest { - import std.math : pow; + import std.math.exponential : pow; assert( isPowerOf2(1.0L)); assert( isPowerOf2(2.0L)); @@ -779,7 +779,7 @@ if (isNumeric!X) @safe unittest { - import std.math : pow; + import std.math.exponential : pow; import std.meta : AliasSeq; enum smallP2 = pow(2.0L, -62); diff --git a/std/math/trigonometry.d b/std/math/trigonometry.d index 5833b61ef..2d99552f6 100644 --- a/std/math/trigonometry.d +++ b/std/math/trigonometry.d @@ -75,7 +75,7 @@ float cos(float x) @safe pure nothrow @nogc { return core.math.cos(x); } /// @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(cos(0.0) == 1.0); assert(cos(1.0).isClose(0.5403023059)); @@ -90,7 +90,7 @@ float cos(float x) @safe pure nothrow @nogc { return core.math.cos(x); } @safe pure nothrow @nogc unittest { - import std.math : fabs; + import std.math.algebraic : fabs; float f = cos(-2.0f); assert(fabs(f - -0.416147f) < .00001); @@ -133,7 +133,7 @@ float sin(float x) @safe pure nothrow @nogc { return core.math.sin(x); } /// @safe unittest { - import std.math : sin, PI; + import std.math.constants : PI; import std.stdio : writefln; void someFunc() @@ -152,7 +152,7 @@ float sin(float x) @safe pure nothrow @nogc { return core.math.sin(x); } @safe pure nothrow @nogc unittest { - import std.math : fabs; + import std.math.algebraic : fabs; float f = sin(-2.0f); assert(fabs(f - -0.909297f) < .00001); @@ -196,7 +196,10 @@ float tan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) tan(ca /// @safe unittest { - import std.math : isClose, isIdentical, PI, sqrt; + import std.math.operations : isClose; + import std.math.traits : isIdentical; + import std.math.constants : PI; + import std.math.algebraic : sqrt; assert(isIdentical(tan(0.0), 0.0)); assert(tan(PI).isClose(0, 0.0, 1e-10)); @@ -300,7 +303,11 @@ Lret: {} private T tanImpl(T)(T x) @safe pure nothrow @nogc { - import std.math : floatTraits, floor, isInfinity, isNaN, poly, PI, PI_4, RealFormat, signbit; + import std.math : floatTraits, RealFormat; + import std.math.constants : PI, PI_4; + import std.math.rounding : floor; + import std.math.algebraic : poly; + import std.math.traits : isInfinity, isNaN, signbit; // Coefficients for tan(x) and PI/4 split into three parts. enum realFormat = floatTraits!T.realFormat; @@ -437,7 +444,9 @@ private T tanImpl(T)(T x) @safe pure nothrow @nogc { static void testTan(T)() { - import std.math : CommonDefaultFor, isClose, isIdentical, isNaN, NaN, PI, PI_4; + import std.math.operations : CommonDefaultFor, isClose, NaN; + import std.math.traits : isIdentical, isNaN; + import std.math.constants : PI, PI_4; // ±0 const T zero = 0.0; @@ -501,13 +510,16 @@ private T tanImpl(T)(T x) @safe pure nothrow @nogc foreach (T; AliasSeq!(real, double, float)) testTan!T(); - import std.math : isClose, PI, sqrt; + import std.math.operations : isClose; + import std.math.constants : PI; + import std.math.algebraic : sqrt; assert(isClose(tan(PI / 3), sqrt(3.0L), real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @safe pure nothrow @nogc unittest { - import std.math : fabs, isNaN; + import std.math.algebraic : fabs; + import std.math.traits : isNaN; float f = tan(-2.0f); assert(fabs(f - 2.18504f) < .00001); @@ -541,7 +553,7 @@ private T tanImpl(T)(T x) @safe pure nothrow @nogc */ real acos(real x) @safe pure nothrow @nogc { - import std.math : sqrt; + import std.math.algebraic : sqrt; return atan2(sqrt(1-x*x), x); } @@ -555,7 +567,9 @@ float acos(float x) @safe pure nothrow @nogc { return acos(cast(real) x); } /// @safe unittest { - import std.math : isClose, isNaN, PI; + import std.math.operations : isClose; + import std.math.traits : isNaN; + import std.math.constants : PI; assert(acos(0.0).isClose(1.570796327)); assert(acos(0.5).isClose(PI / 3)); @@ -564,7 +578,8 @@ float acos(float x) @safe pure nothrow @nogc { return acos(cast(real) x); } @safe @nogc nothrow unittest { - import std.math : isClose, PI; + import std.math.operations : isClose; + import std.math.constants : PI; assert(isClose(acos(0.5), PI / 3, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -582,7 +597,7 @@ float acos(float x) @safe pure nothrow @nogc { return acos(cast(real) x); } */ real asin(real x) @safe pure nothrow @nogc { - import std.math : sqrt; + import std.math.algebraic : sqrt; return atan2(x, sqrt(1-x*x)); } @@ -596,7 +611,9 @@ float asin(float x) @safe pure nothrow @nogc { return asin(cast(real) x); } /// @safe unittest { - import std.math : isClose, isIdentical, isNaN, PI; + import std.math.operations : isClose; + import std.math.traits : isIdentical, isNaN; + import std.math.constants : PI; assert(isIdentical(asin(0.0), 0.0)); assert(asin(0.5).isClose(PI / 6)); @@ -605,7 +622,8 @@ float asin(float x) @safe pure nothrow @nogc { return asin(cast(real) x); } @safe @nogc nothrow unittest { - import std.math : isClose, PI; + import std.math.operations : isClose; + import std.math.constants : PI; assert(isClose(asin(0.5), PI / 6, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -642,7 +660,10 @@ float atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan( /// @safe unittest { - import std.math : isClose, isIdentical, PI, sqrt; + import std.math.operations : isClose; + import std.math.traits : isIdentical; + import std.math.constants : PI; + import std.math.algebraic : sqrt; assert(isIdentical(atan(0.0), 0.0)); assert(atan(sqrt(3.0)).isClose(PI / 3)); @@ -650,7 +671,10 @@ float atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan( private T atanImpl(T)(T x) @safe pure nothrow @nogc { - import std.math : copysign, floatTraits, isInfinity, PI_2, PI_4, poly, RealFormat, signbit; + import std.math : floatTraits, RealFormat; + import std.math.traits : copysign, isInfinity, signbit; + import std.math.constants : PI_2, PI_4; + import std.math.algebraic : poly; // Coefficients for atan(x) enum realFormat = floatTraits!T.realFormat; @@ -810,7 +834,9 @@ private T atanImpl(T)(T x) @safe pure nothrow @nogc { static void testAtan(T)() { - import std.math : CommonDefaultFor, isClose, isIdentical, NaN, PI_2, PI_4; + import std.math.operations : CommonDefaultFor, isClose, NaN; + import std.math.traits : isIdentical; + import std.math.constants : PI_2, PI_4; // ±0 const T zero = 0.0; @@ -855,7 +881,9 @@ private T atanImpl(T)(T x) @safe pure nothrow @nogc foreach (T; AliasSeq!(real, double, float)) testAtan!T(); - import std.math : isClose, sqrt, PI; + import std.math.operations : isClose; + import std.math.algebraic : sqrt; + import std.math.constants : PI; assert(isClose(atan(sqrt(3.0L)), PI / 3, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -908,7 +936,9 @@ float atan2(float y, float x) @safe pure nothrow @nogc /// @safe unittest { - import std.math : isClose, PI, sqrt; + import std.math.operations : isClose; + import std.math.constants : PI; + import std.math.algebraic : sqrt; assert(atan2(1.0, sqrt(3.0)).isClose(PI / 6)); } @@ -938,7 +968,8 @@ private real atan2Asm(real y, real x) @trusted pure nothrow @nogc private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc { - import std.math : copysign, isInfinity, isNaN, PI, PI_2, PI_4, signbit; + import std.math.traits : copysign, isInfinity, isNaN, signbit; + import std.math.constants : PI, PI_2, PI_4; // Special cases. if (isNaN(x) || isNaN(y)) @@ -993,7 +1024,9 @@ private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc { static void testAtan2(T)() { - import std.math : isClose, isIdentical, isNaN, PI, PI_2, PI_4; + import std.math.operations : isClose; + import std.math.traits : isIdentical, isNaN; + import std.math.constants : PI, PI_2, PI_4; // NaN const T nan = T.nan; @@ -1063,7 +1096,9 @@ private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc foreach (T; AliasSeq!(real, double, float)) testAtan2!T(); - import std.math : isClose, sqrt, PI; + import std.math.operations : isClose; + import std.math.algebraic : sqrt; + import std.math.constants : PI; assert(isClose(atan2(1.0L, sqrt(3.0L)), PI / 6, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1077,7 +1112,7 @@ private T atan2Impl(T)(T y, T x) @safe pure nothrow @nogc */ real cosh(real x) @safe pure nothrow @nogc { - import std.math : exp; + import std.math.exponential : exp; // cosh = (exp(x)+exp(-x))/2. // The naive implementation works correctly. @@ -1094,7 +1129,8 @@ float cosh(float x) @safe pure nothrow @nogc { return cosh(cast(real) x); } /// @safe unittest { - import std.math : E, isClose; + import std.math.constants : E; + import std.math.operations : isClose; assert(cosh(0.0) == 1.0); assert(cosh(1.0).isClose((E + 1.0 / E) / 2)); @@ -1102,7 +1138,8 @@ float cosh(float x) @safe pure nothrow @nogc { return cosh(cast(real) x); } @safe @nogc nothrow unittest { - import std.math : isClose, E; + import std.math.constants : E; + import std.math.operations : isClose; assert(isClose(cosh(1.0), (E + 1.0 / E) / 2, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1127,7 +1164,9 @@ float sinh(float x) @safe pure nothrow @nogc { return _sinh(x); } /// @safe unittest { - import std.math : E, isClose, isIdentical; + import std.math.constants : E; + import std.math.operations : isClose; + import std.math.traits : isIdentical; enum sinh1 = (E - 1.0 / E) / 2; import std.meta : AliasSeq; @@ -1140,7 +1179,10 @@ float sinh(float x) @safe pure nothrow @nogc { return _sinh(x); } private F _sinh(F)(F x) { - import std.math : copysign, exp, expm1, fabs, LN2; + import std.math.traits : copysign; + import std.math.exponential : exp, expm1; + import std.math.algebraic : fabs; + import std.math.constants : LN2; // sinh(x) = (exp(x)-exp(-x))/2; // Very large arguments could cause an overflow, but @@ -1157,7 +1199,8 @@ private F _sinh(F)(F x) @safe @nogc nothrow unittest { - import std.math : isClose, E; + import std.math.constants : E; + import std.math.operations : isClose; assert(isClose(sinh(1.0L), real((E - 1.0 / E) / 2), real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1181,7 +1224,8 @@ float tanh(float x) @safe pure nothrow @nogc { return _tanh(x); } /// @safe unittest { - import std.math : isClose, isIdentical; + import std.math.operations : isClose; + import std.math.traits : isIdentical; assert(isIdentical(tanh(0.0), 0.0)); assert(tanh(1.0).isClose(sinh(1.0) / cosh(1.0))); @@ -1189,7 +1233,10 @@ float tanh(float x) @safe pure nothrow @nogc { return _tanh(x); } private F _tanh(F)(F x) { - import std.math : copysign, expm1, fabs, LN2; + import std.math.traits : copysign; + import std.math.exponential : expm1; + import std.math.algebraic : fabs; + import std.math.constants : LN2; // tanh(x) = (exp(x) - exp(-x))/(exp(x)+exp(-x)) if (fabs(x) > F.mant_dig * F(LN2)) @@ -1203,7 +1250,7 @@ private F _tanh(F)(F x) @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(tanh(1.0L), sinh(1.0L) / cosh(1.0L), real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1237,7 +1284,7 @@ float acosh(float x) @safe pure nothrow @nogc { return _acosh(x); } /// @safe @nogc nothrow unittest { - import std.math : isIdentical, isNaN; + import std.math.traits : isIdentical, isNaN; assert(isNaN(acosh(0.9))); assert(isNaN(acosh(real.nan))); @@ -1248,7 +1295,9 @@ float acosh(float x) @safe pure nothrow @nogc { return _acosh(x); } private F _acosh(F)(F x) @safe pure nothrow @nogc { - import std.math : LN2, log, sqrt; + import std.math.constants : LN2; + import std.math.exponential : log; + import std.math.algebraic : sqrt; if (x > 1/F.epsilon) return F(LN2) + log(x); @@ -1258,7 +1307,7 @@ private F _acosh(F)(F x) @safe pure nothrow @nogc @safe @nogc nothrow unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(acosh(cosh(3.0L)), 3.0L, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1290,7 +1339,7 @@ float asinh(float x) @safe pure nothrow @nogc { return _asinh(x); } /// @safe @nogc nothrow unittest { - import std.math : isIdentical, isNaN; + import std.math.traits : isIdentical, isNaN; assert(isIdentical(asinh(0.0), 0.0)); assert(isIdentical(asinh(-0.0), -0.0)); @@ -1301,7 +1350,10 @@ float asinh(float x) @safe pure nothrow @nogc { return _asinh(x); } private F _asinh(F)(F x) { - import std.math : copysign, fabs, log, log1p, LN2, sqrt; + import std.math.traits : copysign; + import std.math.algebraic : fabs, sqrt; + import std.math.exponential : log, log1p; + import std.math.constants : LN2; return (fabs(x) > 1 / F.epsilon) // beyond this point, x*x + 1 == x*x @@ -1312,7 +1364,7 @@ private F _asinh(F)(F x) @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(asinh(sinh(3.0L)), 3.0L, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); } @@ -1337,7 +1389,7 @@ private F _asinh(F)(F x) */ real atanh(real x) @safe pure nothrow @nogc { - import std.math : log1p; + import std.math.exponential : log1p; // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) ) return 0.5 * log1p( 2 * x / (1 - x) ); @@ -1352,7 +1404,7 @@ float atanh(float x) @safe pure nothrow @nogc { return atanh(cast(real) x); } /// @safe @nogc nothrow unittest { - import std.math : isIdentical, isNaN; + import std.math.traits : isIdentical, isNaN; assert(isIdentical(atanh(0.0), 0.0)); assert(isIdentical(atanh(-0.0),-0.0)); @@ -1363,7 +1415,7 @@ float atanh(float x) @safe pure nothrow @nogc { return atanh(cast(real) x); } @safe unittest { - import std.math : isClose; + import std.math.operations : isClose; assert(isClose(atanh(tanh(0.5L)), 0.5, real.sizeof > double.sizeof ? 1e-15 : 1e-14)); }