INT和uint加成 [英] Addition of int and uint
问题描述
我在下面的示例中的C#编译器的行为感到惊讶:
I'm surprised by C# compiler behavior in the following example:
int i = 1024;
uint x = 2048;
x = x+i; // A error CS0266: Cannot implicitly convert type 'long' to 'uint' ...
这似乎为 INT + UINT
确定可以溢出。但是,如果 UINT
更改为 INT
,那么错误消失,如 INT + INT
不能给溢出:
It seems OK as int + uint
can overflow. However, if uint
is changed to int
, then error disappears, like int + int
cannot give overflow:
int i = 1024;
int x = 2048;
x = x+i; // OK, int
此外, UINT UINT + = UINT
:
uint i = 1024;
uint x = 2048;
x = x+i; // OK, uint
这似乎完全模糊。
It seems totally obscure.
为什么 INT + INT = INT
和 UINT + UINT = UINT
,但 INT + UINT =长
?
什么是这一决定的动机是什么?
What is the motivation for this decision?
推荐答案
简短的回答是因为标准说,这应是如此,它看到的信息的与教派;对14.2.5.2 ISO 23270.本的标准的与教派; 13.1.2。 (隐式数字转换)说:
The short answer is "because the Standard says that it shall be so", which see the informative §14.2.5.2 of ISO 23270. The normative §13.1.2. (Implicit numeric conversions) says:
隐式数字转换是:
...
- 从
INT
到长
,浮动
,双击
或小数
。 - 从
UINT
到长
,ULONG
,浮动
,双击
或小数
。
- From
int
tolong
,float
,double
, ordecimal
. - From
uint
tolong
,ulong
,float
,double
, ordecimal
.
...
从 INT
, UINT
,转换长
或 ULONG
到浮动
和长
或 ULONG
到双击
可引起precision的损失,但绝不会引起幅度的损失。
其他的隐式数值转换不会丢失任何信息。( EMPH。我的的)
Conversions from int
, uint
, long
or ulong
to float
and from long
or ulong
to double
can cause a loss of precision, but will never cause a loss of magnitude.
The other implicit numeric conversions never lose any information. (emph. mine)
在[稍微]更长的答案是,要添加两种不同的类型:一个32位有符号整数和32位无符号整数:
The [slightly] longer answer is that you are adding two different types: a 32-bit signed integer and a 32-bit unsigned integer:
- 一个符号的32位整数的域名-2,147,483,648(为0x80000000)MDASH; +2,147,483,647(0x7FFFFFFF的)。
- 一个32位无符号整数域为0(00000000)— 4294967295(0xFFFFFFFF的)。
因此,类型不compatable,因为一个 INT
不能包含任意 UINT
和 UINT
不能包含任意 INT
。他们是隐式转换(A 拉的转换,每与教派的要求; 13.1.2没有信息丢失)到下一个最大的类型可以同时包含:一个长
在这种情况下,一个符号的64位整数,它有域-9,223,372,036,854,775,808(0x8000000000000000)MDASH; +9,223,372,036,854,775,807(0x7FFFFFFFFFFFFFFF)。
So the types aren't compatable, since an int
can't contain any arbitrary uint
and a uint
can't contain any arbitrary int
. They are implicitly converted (a widening conversion, per the requirement of §13.1.2 that no information be lost) to the next largest type that can contain both: a long
in this case, a signed 64-bit integer, which has the domain -9,223,372,036,854,775,808 (0x8000000000000000) — +9,223,372,036,854,775,807 (0x7FFFFFFFFFFFFFFF).
编辑要注意:正如顺便说一句,执行此code:
Edited to note: Just as an aside, Executing this code:
var x = 1024 + 2048u ;
Console.WriteLine( "'x' is an instance of `{0}`" , x.GetType().FullName ) ;
不会产生一个长
作为原海报的例子。相反,生产什么是:
does not yield a long
as the original poster's example. Instead, what is produced is:
'x' is an instance of `System.UInt32`
这是因为常量折叠的的。在EX pression, 1024
的第一个元素没有后缀,因此是一个 INT
第二在EX pression元素 2048u
是 UINT
,根据规则:
This is because of constant folding. The first element in the expression, 1024
has no suffix and as such is an int
and the second element in the expression 2048u
is a uint
, according to the rules:
- 如果文字没有后缀,它的第一个这种类型,其中它的价值
可再presented:INT
,UINT
,长
,ULONG
。 - 如果文字是由
U
或U
后缀,它的第一个这种类型,其中它的价值可再presented:UINT
,ULONG
- If the literal has no suffix, it has the first of these types in which its value can be represented:
int
,uint
,long
,ulong
.- If the literal is suffixed by
U
oru
, it has the first of these types in which its value can be represented:uint
,ulong
.
和自优化知道什么值,总和pcomputed和评估为$ P $一个 UINT
。
And since the optimizer knows what the values are, the sum is precomputed and evaluated as a uint
.
一致性是小小的心灵的妖怪。
Consistency is the hobgoblin of little minds.
这篇关于INT和uint加成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!