Reputation: 22804
Because I needed to look at some methods in BigInteger
, I DotPeeked into the assembly. And then I found something rather odd:
internal int _sign;
Why would you use an int
for the sign of a number? Is there no reason, or is there something I'm missing. I mean, they could use a BitArray
, or a bool
, or a byte
. Why an int
?
Upvotes: 2
Views: 117
Reputation: 1
Gets a number that indicates the sign (negative, positive, or zero) of the current System.Numerics.BigInteger object.
-1 The value of this object is negative. 0 The value of this object is 0 (zero). 1 The value of this object is positive.
That means
class Program
{
static void Main(string[] args)
{
BigInteger bInt1 = BigInteger.Parse("0");
BigInteger bInt2 = BigInteger.Parse("-5");
BigInteger bInt3 = BigInteger.Parse("5");
division10(bInt1);//it is Impossible
division10(bInt2);//it is Possible : -2
division10(bInt3);//it is Possible : 2
}
static void division10(BigInteger bInt)
{
double d = 10;
if (bInt.IsZero)
{
Console.WriteLine("it is Impossible");
}
else
{
Console.WriteLine("it is Possible : {0}", d / (int)bInt);
}
}
}
don't use byte or another uint, sbyte, ushort, short because exist CLS and CLS don't support their
Upvotes: 0
Reputation: 81247
The size of any class object is going to be rounded up to 32 bits (four bytes), so "saving" three bytes won't buy anything. One might be able to shave four bytes off the size of a typical BigInteger by stealing a bit from one of the words that holds the numeric value, but the extra processing required for such usage would outweigh the cost of wasting a 32-bit integer.
A more interesting possibility might be to have BigInteger
be an abstract class, with derived classes PositiveBigInteger
and NegativeBigInteger
. Since every class object is going to have a word that says what class it is, such an approach would save 32 bits for each BigInteger that's created. Use of an abstract class in such fashion would add an extra virtual member dispatch to each function call, but would likely save an "if" test on most of them (since the methods of e.g. NegativeBigInteger
would know by virtue of the fact that they are invoked that this
is negative, they wouldn't have to test it). Such a design could also improve efficiency if there were classes for TinyBigInteger
(a BigInteger
whose value could fit in a single Integer
) and SmallBigInteger
(a BigInteger
whose value could fit in a Long
). I have no idea if Microsoft considered such a design, or what the trade-offs would have been.
Upvotes: 0
Reputation: 1659
If you look at some of the usages of _sign
field in the decompiled code, you may find things like this:
if ((this._sign ^ other._sign) < 0)
return this._sign >= 0 ? 1 : -1;
Basically int
type allows to compare signs of two values using multiplication. Obviously neither byte
, nor bool
would allow this.
Still there is a question: why not Int16
then, as it would consume less memory? This is perhaps connected with alignment.
Upvotes: 2
Reputation: 942080
A bool can have only 2 states. The advantage of an int is that it now also is simple to keep track of the special value: 0
public bool get_IsZero()
{
return (this._sign == 0);
}
And several more shortcuts like that when you read the rest of the code.
Upvotes: 1
Reputation: 6089
Storing the sign as an int allows you to simply multiply by the sign to apply it to the result of a calculation. This could come in handy when converting to simpler types.
Upvotes: 1