While reflecting with ILSpy i found this line of code in the Queue<T>.Enqueue(T item)
-method:
if (this._size == this._array.Length)
{
int num = (int)((long)this._array.Length * 200L / 100L);
if (num < this._array.Length + 4)
{
num = this._array.Length + 4;
}
this.SetCapacity(num);
}
I'm just wondering why somebody would do this? I think it's some kind of a integer overflow check, but why multiply first with 200L
and then divide by 100L
?
Might this have been a issue with earlier compilers?
Usually things first multiplied then divided by 100 are percentage calculations - Perhaps there was some const XxxPercentage = 200
or something like that in the original code. The compiler does not seem to optimize the * 200 / 100
to * 2
.
This code sets the capacity to twice its size - but if twice its size would be smaller than the original size + 4, use that instead.
The reason it is converted to long probably is because if you multiply an integer by the "200 percent" it would overflow.
Below are all the same and will generate the same result:
int size = (int)((length * 200L) / 100L);
int size = length << 1;
int size = length * 2;
The reason for choosing the first option over the other is to show your intend clearly:
const long TotalArraySize = 200L;
const long BytesPerElement = 100L;
return (length * TotalArraySize) / BytesPerElement;
Some details about performance implications are given here: Doubling a number - shift left vs. multiplication
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With