mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Remove slow array copy from math.floor()
This commit is contained in:
parent
2278751883
commit
df5dab4a7a
1 changed files with 18 additions and 12 deletions
30
std/math.d
30
std/math.d
|
@ -3079,12 +3079,20 @@ real floor(real x) @trusted pure nothrow @nogc
|
|||
return x;
|
||||
|
||||
alias F = floatTraits!(real);
|
||||
auto vu = *cast(ushort[real.sizeof/2]*)(&x);
|
||||
// Take care not to trigger library calls from the compiler,
|
||||
// while ensuring that we don't get defeated by some optimizers.
|
||||
union realBits
|
||||
{
|
||||
real rv;
|
||||
ushort[real.sizeof/2] vu;
|
||||
}
|
||||
realBits y = void;
|
||||
y.rv = x;
|
||||
|
||||
// Find the exponent (power of 2)
|
||||
static if (real.mant_dig == 53)
|
||||
{
|
||||
int exp = ((vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
|
||||
int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
|
||||
|
||||
version (LittleEndian)
|
||||
int pos = 0;
|
||||
|
@ -3093,7 +3101,7 @@ real floor(real x) @trusted pure nothrow @nogc
|
|||
}
|
||||
else static if (real.mant_dig == 64)
|
||||
{
|
||||
int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
|
||||
int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
|
||||
|
||||
version (LittleEndian)
|
||||
int pos = 0;
|
||||
|
@ -3102,7 +3110,7 @@ real floor(real x) @trusted pure nothrow @nogc
|
|||
}
|
||||
else if (real.mant_dig == 113)
|
||||
{
|
||||
int exp = (vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
|
||||
int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
|
||||
|
||||
version (LittleEndian)
|
||||
int pos = 0;
|
||||
|
@ -3126,22 +3134,20 @@ real floor(real x) @trusted pure nothrow @nogc
|
|||
while (exp >= 16)
|
||||
{
|
||||
version (LittleEndian)
|
||||
vu[pos++] = 0;
|
||||
y.vu[pos++] = 0;
|
||||
else
|
||||
vu[pos--] = 0;
|
||||
y.vu[pos--] = 0;
|
||||
exp -= 16;
|
||||
}
|
||||
|
||||
// Clear the remaining bits.
|
||||
if (exp > 0)
|
||||
vu[pos] &= BMASK[exp];
|
||||
y.vu[pos] &= BMASK[exp];
|
||||
|
||||
real y = *cast(real*)(&vu);
|
||||
if ((x < 0.0) && (x != y.rv))
|
||||
y.rv -= 1.0;
|
||||
|
||||
if ((x < 0.0) && (x != y))
|
||||
y -= 1.0;
|
||||
|
||||
return y;
|
||||
return y.rv;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue