我已经观察了一段时间C#程序员倾向于在任何地方使用int,并且很少使用uint.但我从来没有找到一个令人满意的答案为什么.
如果您的目标是互操作性,则uint不应出现在公共API中,因为并非所有CLI语言都支持无符号整数.但这并不能解释为什么int如此普遍,即使在内部课程中也是如此.我怀疑这是因为在BCL中谨慎使用uint的原因.
在C++中,如果你有一个负值没有意义的整数,你选择一个无符号整数.
这清楚地表明不允许或不期望负数,编译器会为您做一些检查.我还怀疑在数组索引的情况下,JIT可以轻松地删除下限检查.
但是,在混合int和单位类型时,需要额外的护理和演员表.
是否应该使用更多?为什么?
我总是使用unsigned int来表示永远不应该是负数的值.但是今天我在代码中发现了这种情况:
void CreateRequestHeader( unsigned bitsAvailable, unsigned mandatoryDataSize,
unsigned optionalDataSize )
{
If ( bitsAvailable – mandatoryDataSize >= optionalDataSize ) {
// Optional data fits, so add it to the header.
}
// BUG! The above includes the optional part even if
// mandatoryDataSize > bitsAvailable.
}
Run Code Online (Sandbox Code Playgroud)
我应该开始使用int而不是unsigned int来表示数字,即使它们不能为负数吗?
为什么Double.MaxValue转换为整数类型会产生负值,即该类型的最小值?
double maxDouble = double.MaxValue; // 1.7976931348623157E+308
long maxDoubleLong = (long) maxDouble; // -9223372036854775808
Run Code Online (Sandbox Code Playgroud)
我理解编译器错误,如果它太大或OverflowException在运行时或者如果我使用unchecked转换可能不会抛出异常,但结果变得不确定和不正确(负).
同样奇怪的是,价值是long.MinValue:
bool sameAsLongMin = maxDoubleLong == long.MinValue; // true
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果我把它投射到同样的情况int:
int maxDoubleInt = (int)maxDouble; // -2147483648
bool sameAsIntMin = maxDoubleInt == int.MinValue; // true
Run Code Online (Sandbox Code Playgroud)
如果它试图将它转换为decimal我OverflowException在运行时获得
decimal maxDoubleDec = (decimal)maxDouble; // nope
Run Code Online (Sandbox Code Playgroud)
更新:似乎迈克尔和巴雷的答案在头上钉了一针,如果我checked明确使用我得到一个OverflowException:
checked
{
double maxDouble = double.MaxValue; // 1.7976931348623157E+308
long maxDoubleLong = (long) maxDouble; // …Run Code Online (Sandbox Code Playgroud) 所以我正在研究这个问题,普遍的共识是uint cast版本比0的范围检查更有效.由于代码也在MS的List实现中,我认为它是一个真正的优化.但是,我无法生成代码示例,从而为uint版本带来更好的性能.我尝试了不同的测试,但是我的代码中缺少某些东西,或者我的代码的其他部分使检查的时间相形见绌.我的最后一次尝试是这样的:
class TestType
{
public TestType(int size)
{
MaxSize = size;
Random rand = new Random(100);
for (int i = 0; i < MaxIterations; i++)
{
indexes[i] = rand.Next(0, MaxSize);
}
}
public const int MaxIterations = 10000000;
private int MaxSize;
private int[] indexes = new int[MaxIterations];
public void Test()
{
var timer = new Stopwatch();
int inRange = 0;
int outOfRange = 0;
timer.Start();
for (int i = 0; i < MaxIterations; i++)
{
int x …Run Code Online (Sandbox Code Playgroud)