Skip to content

Commit fd06bc1

Browse files
author
The Dlang Bot
authored
Merge pull request #7182 from crocopaw/abs
Fix issue 20205 - std.math: Wrong result for abs(int.min) merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents ee30e07 + e6b5c68 commit fd06bc1

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

std/math.d

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static import core.math;
131131
static import core.stdc.math;
132132
static import core.stdc.fenv;
133133
import std.traits : CommonType, isFloatingPoint, isIntegral, isNumeric,
134-
isSigned, isUnsigned, Largest, Unqual;
134+
isSigned, isUnsigned, Largest, Unqual, Unsigned;
135135

136136
version (LDC)
137137
{
@@ -590,21 +590,23 @@ template isDeprecatedComplex(T)
590590
* the return type will be the same as the input;
591591
*/
592592
auto abs(Num)(Num x)
593+
// first line is needed until transition due to issue 16997 ended
593594
if ((is(Unqual!Num == short) || is(Unqual!Num == byte)) ||
594595
(is(typeof(Num.init >= 0)) && is(typeof(-Num.init))))
595596
{
596-
static if (isFloatingPoint!(Num))
597+
static if (isFloatingPoint!Num)
597598
return fabs(x);
598-
else
599+
else static if (isIntegral!Num)
599600
{
600-
static if (is(Unqual!Num == short) || is(Unqual!Num == byte))
601-
return x >= 0 ? x : cast(Num) -int(x);
602-
else
603-
return x >= 0 ? x : -x;
601+
// (0 - x) is a workaround until transition due to issue 16997 ended
602+
static if (isSigned!Num) if (x < 0) return cast(Unsigned!Num)(0 - x);
603+
return x;
604604
}
605+
else
606+
return x >= 0 ? x : -x;
605607
}
606608

607-
/// ditto
609+
///
608610
@safe pure nothrow @nogc unittest
609611
{
610612
assert(isIdentical(abs(-0.0L), 0.0L));
@@ -614,6 +616,18 @@ if ((is(Unqual!Num == short) || is(Unqual!Num == byte)) ||
614616
assert(abs(2321312L) == 2321312L);
615617
}
616618

619+
@safe pure nothrow @nogc unittest
620+
{
621+
assert(abs(byte.min)==128U);
622+
assert(abs(short.min)==32768U);
623+
assert(abs(int.min)==2147483648U);
624+
assert(abs(long.min)==9223372036854775808UL);
625+
assert(abs(byte.max)==127U);
626+
assert(abs(short.max)==32767U);
627+
assert(abs(int.max)==2147483647U);
628+
assert(abs(long.max)==9223372036854775807UL);
629+
}
630+
617631
version (TestComplex)
618632
deprecated
619633
@safe pure nothrow @nogc unittest

0 commit comments

Comments
 (0)