mirror of
https://github.com/dlang/phobos.git
synced 2025-05-01 15:40:36 +03:00
Merge pull request #4268 from JackStouffer/issue15973
[Issue 15973]: nextPow2 and truncPow2 rely on processor specific …
This commit is contained in:
commit
aa8cf8646f
1 changed files with 27 additions and 26 deletions
51
std/math.d
51
std/math.d
|
@ -7333,28 +7333,17 @@ private T powIntegralImpl(PowType type, T)(T val)
|
||||||
{
|
{
|
||||||
import core.bitop : bsr;
|
import core.bitop : bsr;
|
||||||
|
|
||||||
Unqual!T x = val;
|
if (val == 0 || (type == PowType.ceil && (val > T.max / 2 || val == T.min)))
|
||||||
|
return 0;
|
||||||
static if (isSigned!T)
|
|
||||||
if (x < 0)
|
|
||||||
x = abs(x);
|
|
||||||
|
|
||||||
if (x == 0)
|
|
||||||
return x;
|
|
||||||
|
|
||||||
static if (type == PowType.ceil)
|
|
||||||
x = cast(Unqual!T) (Unqual!T(1) << bsr(x) + 1);
|
|
||||||
else
|
else
|
||||||
x = cast(Unqual!T) (Unqual!T(1) << bsr(x));
|
{
|
||||||
|
|
||||||
static if (isSigned!T)
|
static if (isSigned!T)
|
||||||
if (val < 0)
|
return cast(Unqual!T) (val < 0 ? -(T(1) << bsr(-val) + type) : T(1) << bsr(val) + type);
|
||||||
return -x;
|
else
|
||||||
|
return cast(Unqual!T) (T(1) << bsr(val) + type);
|
||||||
return x;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline, true)
|
|
||||||
private T powFloatingPointImpl(PowType type, T)(T x)
|
private T powFloatingPointImpl(PowType type, T)(T x)
|
||||||
{
|
{
|
||||||
if (!x.isFinite)
|
if (!x.isFinite)
|
||||||
|
@ -7380,9 +7369,12 @@ private T powFloatingPointImpl(PowType type, T)(T x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives the next power of two after $(D val). $(T) can be any built-in
|
* Gives the next power of two after $(D val). `T` can be any built-in
|
||||||
* numerical type.
|
* numerical type.
|
||||||
*
|
*
|
||||||
|
* If the operation would lead to an over/underflow, this function will
|
||||||
|
* return `0`.
|
||||||
|
*
|
||||||
* Params:
|
* Params:
|
||||||
* val = any number
|
* val = any number
|
||||||
*
|
*
|
||||||
|
@ -7410,15 +7402,15 @@ T nextPow2(T)(const T val) if (isFloatingPoint!T)
|
||||||
assert(nextPow2(-2) == -4);
|
assert(nextPow2(-2) == -4);
|
||||||
assert(nextPow2(-10) == -16);
|
assert(nextPow2(-10) == -16);
|
||||||
|
|
||||||
assert(nextPow2(uint.max) == 1);
|
assert(nextPow2(uint.max) == 0);
|
||||||
assert(nextPow2(uint.min) == 0);
|
assert(nextPow2(uint.min) == 0);
|
||||||
assert(nextPow2(size_t.max) == 1);
|
assert(nextPow2(size_t.max) == 0);
|
||||||
assert(nextPow2(size_t.min) == 0);
|
assert(nextPow2(size_t.min) == 0);
|
||||||
|
|
||||||
assert(nextPow2(int.max) == int.min);
|
assert(nextPow2(int.max) == 0);
|
||||||
assert(nextPow2(int.min) == -1);
|
assert(nextPow2(int.min) == 0);
|
||||||
assert(nextPow2(long.max) == long.min);
|
assert(nextPow2(long.max) == 0);
|
||||||
assert(nextPow2(long.min) == -1);
|
assert(nextPow2(long.min) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -7493,6 +7485,15 @@ T nextPow2(T)(const T val) if (isFloatingPoint!T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@safe @nogc pure nothrow unittest // Issue 15973
|
||||||
|
{
|
||||||
|
assert(nextPow2(uint.max / 2) == uint.max / 2 + 1);
|
||||||
|
assert(nextPow2(uint.max / 2 + 2) == 0);
|
||||||
|
assert(nextPow2(int.max / 2) == int.max / 2 + 1);
|
||||||
|
assert(nextPow2(int.max / 2 + 2) == 0);
|
||||||
|
assert(nextPow2(int.min + 1) == int.min);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives the last power of two before $(D val). $(T) can be any built-in
|
* Gives the last power of two before $(D val). $(T) can be any built-in
|
||||||
* numerical type.
|
* numerical type.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue