Skip to content

Commit 11031c4

Browse files
kzrnmdanmoseley
andauthored
Avoid an allocation in BigInteger.Parse("-2147483648") (#104666)
Co-authored-by: Dan Moseley <[email protected]>
1 parent 8672edd commit 11031c4

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -511,16 +511,23 @@ internal BigInteger(ReadOnlySpan<uint> value, bool negative)
511511
{
512512
this = default;
513513
}
514-
else if (value.Length == 1 && value[0] < kuMaskHighBit)
514+
else if (value.Length == 1)
515515
{
516-
// Values like (Int32.MaxValue+1) are stored as "0x80000000" and as such cannot be packed into _sign
517-
_sign = negative ? -(int)value[0] : (int)value[0];
518-
_bits = null;
519-
if (_sign == int.MinValue)
516+
if (value[0] < kuMaskHighBit)
517+
{
518+
_sign = negative ? -(int)value[0] : (int)value[0];
519+
_bits = null;
520+
}
521+
else if (negative && value[0] == kuMaskHighBit)
520522
{
521523
// Although Int32.MinValue fits in _sign, we represent this case differently for negate
522524
this = s_bnMinInt;
523525
}
526+
else
527+
{
528+
_sign = negative ? -1 : +1;
529+
_bits = [value[0]];
530+
}
524531
}
525532
else
526533
{

src/libraries/System.Runtime.Numerics/tests/BigInteger/parse.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,23 @@ private static void VerifyDefaultParse(Random random)
233233
// BasicTests
234234
VerifyFailParseToString(null, typeof(ArgumentNullException));
235235
VerifyFailParseToString(string.Empty, typeof(FormatException));
236-
VerifyParseToString("0");
237-
VerifyParseToString("000");
238-
VerifyParseToString("1");
239-
VerifyParseToString("001");
236+
237+
foreach (var value in new string[]
238+
{
239+
"0",
240+
"000",
241+
"1",
242+
"001",
243+
int.MaxValue.ToString(),
244+
int.MinValue.ToString(),
245+
long.MaxValue.ToString(),
246+
long.MinValue.ToString(),
247+
Int128.MaxValue.ToString(),
248+
Int128.MinValue.ToString(),
249+
})
250+
{
251+
VerifyParseToString(value);
252+
}
240253

241254
// SimpleNumbers - Small
242255
for (int i = 0; i < s_samples; i++)

0 commit comments

Comments
 (0)