Rob*_*ino 356 c# type-conversion
看看这个C#代码:
byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'
Run Code Online (Sandbox Code Playgroud)
对byte
(或short
)类型执行的任何数学运算的结果都隐式地转换回整数.解决方案是将结果显式地转换回一个字节:
byte z = (byte)(x + y); // this works
Run Code Online (Sandbox Code Playgroud)
我想知道的是为什么?它是建筑吗?哲学?
我们有:
int
+ int
=int
long
+ long
=long
float
+ float
=float
double
+ double
=double
那么为什么不呢:
byte
+ byte
=byte
short
+ short
= short
?一点背景:我正在对"小数字"(即<8)执行一长串计算,并将中间结果存储在一个大数组中.使用字节数组(而不是int数组)更快(因为缓存命中).但是通过代码传播的大量字节转换使得它更加难以理解.
azh*_*lov 220
代码段的第三行:
byte z = x + y;
Run Code Online (Sandbox Code Playgroud)
实际意味着
byte z = (int) x + (int) y;
Run Code Online (Sandbox Code Playgroud)
因此,对字节没有+操作,首先将字节转换为整数,并且添加两个整数的结果是(32位)整数.
Jon*_*eet 170
就"为什么会发生这种情况"而言,这是因为没有任何运算符由C#定义用于byte,sbyte,short或ushort的算术,就像其他人所说的那样.这个答案是为什么没有定义那些运营商.
我相信这基本上是为了表现.处理器具有本机操作,可以非常快速地使用32位进行算术运算.可以自动完成从结果到字节的转换,但在您实际上不需要该行为的情况下会导致性能损失.
我认为这是在一个带注释的C#标准中提到的.看着...
编辑:令人讨厌的是,我现在已经查看了带注释的ECMA C#2规范,带注释的MS C#3规范和注释CLI规范,据我所知,他们都没有提到这一点.我确定我已经看到了上面提到的原因,但如果我知道在哪里,我会被打击.道歉,参考粉丝:(
Mic*_*tta 67
我以为我以前见过这个.从这篇文章,旧的新事物:
假设我们生活在一个幻想世界中,'byte'上的操作导致'byte'.
byte b = 32;
byte c = 240;
int i = b + c; // what is i?
Run Code Online (Sandbox Code Playgroud)
在这个幻想世界中,我的价值将是16!为什么?因为+运算符的两个操作数都是字节,所以总和"b + c"被计算为一个字节,由于整数溢出导致16.(而且,正如我前面提到的,整数溢出是新的安全攻击向量.)
编辑:雷蒙德基本上是在捍卫C和C++最初采用的方法.在评论中,他以语言向后兼容性为由捍卫了C#采用相同方法的事实.
Alu*_*ord 57
ECMA-334声明添加仅在int + int,uint + uint,long + long和ulong + ulong(ECMA-334 14.7.4)上定义为合法.因此,这些是关于14.4.2要考虑的候选操作.因为存在从byte到int,uint,long和ulong的隐式转换,所有加法函数成员都是适用于14.4.2.1的函数成员.我们必须找到14.4.2.3中规则的最佳隐式转换:
铸造(C1)到int(T1)比铸造(C2)到uint(T2)或ulong(T2)要好,因为:
将(C1)转换为int(T1)比将(C2)转换为long(T2)更好,因为存在从int到long的隐式转换:
因此使用int + int函数,它返回一个int.
这是一个非常漫长的方式,它说它深深埋藏在C#规范中.
CLI仅对6种类型(int32,native int,int64,F,O和&)进行操作.(ECMA-335分区3部分1.5)
字节(int8)不是这些类型之一,并且在添加之前自动强制转换为int32.(ECMA-335分区3部分1.6)
Chr*_*her 26
表示添加字节并将结果截断回字节的低效率的答案是不正确的.x86处理器具有专门针对8位数量的整数运算而设计的指令.
实际上,对于x86/64处理器,由于必须解码的操作数前缀字节,执行32位或16位操作的效率低于64位或8位操作.在32位机器上,执行16位操作需要相同的惩罚,但仍有专用的操作码用于8位操作.
许多RISC架构具有类似的本机字/字节有效指令.那些通常没有存储和转换为某些位长度的符号值的那些.
换句话说,这个决定必须基于对字节类型的感知,而不是由于硬件的潜在低效率.
这是因为溢出和携带.
如果添加两个8位数字,它们可能会溢出到第9位.
例:
1111 1111
+ 0000 0001
-----------
1 0000 0000
Run Code Online (Sandbox Code Playgroud)
我不知道肯定,但我认为ints
,longs
和doubles
被赋予了更多的空间,因为他们是相当大的,因为它是.此外,它们是4的倍数,由于内部数据总线的宽度为4字节或32位(64位现在变得更普遍),因此它们对计算机来说更有效.字节和短字的效率要低一些,但它们可以节省空间.
归档时间: |
|
查看次数: |
60457 次 |
最近记录: |