Skip to content

Commit

Permalink
Merge pull request #4268 from JackStouffer/issue15973
Browse files Browse the repository at this point in the history
[Issue 15973]: nextPow2 and truncPow2 rely on processor specific …
  • Loading branch information
rainers committed May 2, 2016
2 parents 44cf51e + 6d8f0b8 commit aa8cf86
Showing 1 changed file with 27 additions and 26 deletions.
53 changes: 27 additions & 26 deletions std/math.d
Original file line number Diff line number Diff line change
Expand Up @@ -7333,28 +7333,17 @@ private T powIntegralImpl(PowType type, T)(T val)
{
import core.bitop : bsr;

Unqual!T x = val;

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);
if (val == 0 || (type == PowType.ceil && (val > T.max / 2 || val == T.min)))
return 0;
else
x = cast(Unqual!T) (Unqual!T(1) << bsr(x));

static if (isSigned!T)
if (val < 0)
return -x;

return x;
{
static if (isSigned!T)
return cast(Unqual!T) (val < 0 ? -(T(1) << bsr(-val) + type) : T(1) << bsr(val) + type);
else
return cast(Unqual!T) (T(1) << bsr(val) + type);
}
}

pragma(inline, true)
private T powFloatingPointImpl(PowType type, T)(T x)
{
if (!x.isFinite)
Expand All @@ -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.
*
* If the operation would lead to an over/underflow, this function will
* return `0`.
*
* Params:
* val = any number
*
Expand Down Expand Up @@ -7410,15 +7402,15 @@ T nextPow2(T)(const T val) if (isFloatingPoint!T)
assert(nextPow2(-2) == -4);
assert(nextPow2(-10) == -16);

assert(nextPow2(uint.max) == 1);
assert(nextPow2(uint.max) == 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(int.max) == int.min);
assert(nextPow2(int.min) == -1);
assert(nextPow2(long.max) == long.min);
assert(nextPow2(long.min) == -1);
assert(nextPow2(int.max) == 0);
assert(nextPow2(int.min) == 0);
assert(nextPow2(long.max) == 0);
assert(nextPow2(long.min) == 0);
}

///
Expand Down Expand Up @@ -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
* numerical type.
Expand Down

0 comments on commit aa8cf86

Please sign in to comment.