因为我需要查看 中的一些方法BigInteger
,所以我 DotPeeked 进入了程序集。然后我发现了一些相当奇怪的东西:
internal int _sign;
为什么要使用 anint
作为数字的符号?是没有原因,还是我缺少什么。我的意思是,他们可以使用 aBitArray
或 abool
或 a byte
。为什么一个int
?
因为我需要查看 中的一些方法BigInteger
,所以我 DotPeeked 进入了程序集。然后我发现了一些相当奇怪的东西:
internal int _sign;
为什么要使用 anint
作为数字的符号?是没有原因,还是我缺少什么。我的意思是,他们可以使用 aBitArray
或 abool
或 a byte
。为什么一个int
?
如果你看一下_sign
反编译代码中字段的一些用法,你可能会发现这样的事情:
if ((this._sign ^ other._sign) < 0)
return this._sign >= 0 ? 1 : -1;
基本上int
类型允许使用乘法比较两个值的符号。显然既不允许byte
,也bool
不允许这样做。
仍然有一个问题:为什么不Int16
这样,因为它会消耗更少的内存?这可能与对齐有关。
将符号存储为 int 允许您简单地乘以符号以将其应用于计算结果。这在转换为更简单的类型时会派上用场。
一个布尔值只能有 2 个状态。int 的优点是现在跟踪特殊值也很简单:0
public bool get_IsZero()
{
return (this._sign == 0);
}
当您阅读其余代码时,还有更多类似的快捷方式。
任何类对象的大小都将四舍五入到 32 位(四个字节),因此“节省”三个字节不会买任何东西。可以通过从保存数值的单词之一中窃取一个位来将典型 BigInteger 的大小减少四个字节,但这种使用所需的额外处理将超过浪费 32 位整数的成本。
一个更有趣的可能性可能是BigInteger
具有派生类PositiveBigInteger
和NegativeBigInteger
. 由于每个类对象都会有一个词来说明它是什么类,因此这种方法将为每个创建的 BigInteger 节省 32 位。以这种方式使用抽象类会为每个函数调用添加一个额外的虚拟成员调度,但可能会为它们中的大多数保存一个“if”测试(因为 eg 的方法NegativeBigInteger
会根据它们被调用的事实而知道)那this
是负面的,他们不必测试它)。如果TinyBigInteger
(aBigInteger
的值可以放入单个Integer
) 和SmallBigInteger
(aBigInteger
的值可以放入Long
)。我不知道微软是否考虑过这样的设计,也不知道会有什么取舍。
获取一个数字,该数字指示当前 System.Numerics.BigInteger 对象的符号(负数、正数或零)。
-1 此对象的值为负数。0 此对象的值为 0(零)。1 此对象的值为正。
这意味着
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);
}
}
}
不要使用 byte 或其他 uint、sbyte、ushort、short 因为存在 CLS 和 CLS 不支持它们