C# 字节 + 字节 = 整数...为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/941584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
byte + byte = int... why?
提问by Robert Cartaino
Looking at this C# code:
看看这个 C# 代码:
byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'
The result of any math performed on byte
(or short
) types is implicitly cast back to an integer. The solution is to explicitly cast the result back to a byte:
对byte
(or short
) 类型执行的任何数学运算的结果都隐式转换回整数。解决方案是将结果显式转换回一个字节:
byte z = (byte)(x + y); // this works
What I am wondering is why? Is it architectural? Philosophical?
我想知道的是为什么?是建筑学吗?哲学的?
We have:
我们有:
int
+int
=int
long
+long
=long
float
+float
=float
double
+double
=double
int
+int
=int
long
+long
=long
float
+float
=float
double
+double
=double
So why not:
那么为什么不:
byte
+byte
=byte
short
+short
=short
?
byte
+byte
=byte
short
+short
=short
?
A bit of background: I am performing a long list of calculations on "small numbers" (i.e. < 8) and storing the intermediate results in a large array. Using a byte array(instead of an int array) is faster(because of cache hits). But the extensive byte-casts spread through the code make it that much more unreadable.
一点背景知识:我正在对“小数”(即 < 8)执行一长串计算,并将中间结果存储在一个大数组中。使用字节数组(而不是 int 数组)更快(因为缓存命中)。但是通过代码传播的大量字节转换使它变得更加不可读。
回答by samoz
This is because of overflow and carries.
这是因为溢出和进位。
If you add two 8 bit numbers, they might overflow into the 9th bit.
如果将两个 8 位数字相加,它们可能会溢出到第 9 位。
Example:
例子:
1111 1111
+ 0000 0001
-----------
1 0000 0000
I don't know for sure, but I assume that ints
, longs
, anddoubles
are given more space because they are pretty large as it is. Also, they are multiples of 4, which are more efficient for computers to handle, due to the width of the internal data bus being 4 bytes or 32 bits (64 bits is getting more prevalent now) wide. Byte and short are a little more inefficient, but they can save space.
我不确定,但我认为ints
, longs
, 和doubles
获得了更多空间,因为它们确实很大。此外,它们是 4 的倍数,这对计算机处理更有效,因为内部数据总线的宽度为 4 字节或 32 位(现在 64 位越来越普遍)。Byte 和 short 效率低一些,但它们可以节省空间。
回答by Michael Petrotta
I thoughtI had seen this somewhere before. From this article, The Old New Thing:
我以为我以前在什么地方见过这个。从这篇文章,旧的新事物:
Suppose we lived in a fantasy world where operations on 'byte' resulted in 'byte'.
假设我们生活在一个幻想世界中,对“字节”的操作会产生“字节”。
byte b = 32;
byte c = 240;
int i = b + c; // what is i?
In this fantasy world, the value of i would be 16! Why? Because the two operands to the + operator are both bytes, so the sum "b+c" is computed as a byte, which results in 16 due to integer overflow. (And, as I noted earlier, integer overflow is the new security attack vector.)
在这个奇幻世界里,我的价值是16!为什么?因为 + 运算符的两个操作数都是字节,所以总和 "b+c" 被计算为一个字节,由于整数溢出导致 16。(而且,正如我之前提到的,整数溢出是新的安全攻击向量。)
EDIT: Raymond is defending, essentially, the approach C and C++ took originally. In the comments, he defends the fact that C# takes the same approach, on the grounds of language backward compatibility.
编辑:Raymond 本质上是在捍卫 C 和 C++ 最初采用的方法。在评论中,他以语言向后兼容性为由为 C# 采取相同方法的事实辩护。
回答by fortran
I think it's a design decission about which operation was more common... If byte+byte = byte maybe much more people will be bothered by having to cast to int when an int is required as result.
我认为这是关于哪种操作更常见的设计决定......如果 byte+byte = byte 可能会有更多的人因为在需要 int 时不得不强制转换为 int 而感到困扰。
回答by mqp
My suspicion is that C# is actually calling the operator+
defined on int
(which returns an int
unless you are in a checked
block), and implicitly casting both of your bytes
/shorts
to ints
. That's why the behavior appears inconsistent.
我怀疑 C# 实际上是调用了operator+
定义的 on int
(int
除非您在checked
块中,否则它会返回 an ),并将您的bytes
/隐式转换shorts
为ints
. 这就是行为看起来不一致的原因。
回答by BFree
I remember once reading something from Jon Skeet (can't find it now, I'll keep looking) about how byte doesn't actually overload the + operator. In fact, when adding two bytes like in your sample, each byte is actually being implicitly converted to an int. The result of that is obviously an int. Now as to WHY this was designed this way, I'll wait for Jon Skeet himself to post :)
我记得有一次从 Jon Skeet(现在找不到,我会继续寻找)中读到关于字节实际上如何不重载 + 运算符的内容。事实上,当像您的示例中那样添加两个字节时,每个字节实际上都被隐式转换为 int。结果显然是一个整数。现在至于为什么这样设计,我将等待 Jon Skeet 自己发布:)
EDIT:Found it! Great info about this very topic here.
编辑:找到了!关于这个主题的重要信息在这里。
回答by Jim C
Addition is not defined for bytes. So they are cast to int for the addition. This true for most math operations and bytes. (note this is how it used to be in older languages, I am assuming that it hold true today).
没有为字节定义加法。因此,它们被强制转换为 int 以进行添加。对于大多数数学运算和字节都是如此。(请注意,这在以前的语言中是这样的,我假设它今天仍然适用)。
回答by PeterAllenWebb
This was probably a practical decision on the part of the language designers. After all, an int is an Int32, a 32-bit signed integer. Whenever you do an integer operation on a type smaller than int, it's going to be converted to a 32 bit signed int by most any 32 bit CPU anyway. That, combined with the likelihood of overflowing small integers, probably sealed the deal. It saves you from the chore of continuously checking for over/under-flow, and when the final result of an expression on bytes would be in range, despite the fact that at some intermediate stage it would be out of range, you get a correct result.
这可能是语言设计者的一个实际决定。毕竟,一个 int 是一个 Int32,一个 32 位有符号整数。每当您对小于 int 的类型执行整数运算时,无论如何,大多数 32 位 CPU 都会将其转换为 32 位有符号 int。再加上小整数溢出的可能性,很可能达成协议。它使您免于连续检查溢出/下溢的麻烦,并且当字节表达式的最终结果在范围内时,尽管在某些中间阶段它会超出范围,但您会得到正确的结果。
Another thought: The over/under-flow on these types would have to be simulated, since it wouldn't occur naturally on the most likely target CPUs. Why bother?
另一个想法:必须模拟这些类型的上溢/下溢,因为它不会在最有可能的目标 CPU 上自然发生。何苦?
回答by Jon Skeet
In terms of "why it happens at all" it's because there aren't any operators defined by C# for arithmetic with byte, sbyte, short or ushort, just as others have said. This answer is about whythose operators aren't defined.
就“为什么会发生这种情况”而言,这是因为 C# 没有像其他人所说的那样为带有 byte、sbyte、short 或 ushort 的算术定义任何运算符。这个答案是关于为什么没有定义这些运算符。
I believe it's basically for the sake of performance. Processors have native operations to do arithmetic with 32 bits very quickly. Doing the conversion back from the result to a byte automatically couldbe done, but would result in performance penalties in the case where you don't actually want that behaviour.
我相信这基本上是为了性能。处理器具有本地操作,可以非常快速地进行 32 位算术运算。可以自动完成从结果到字节的转换,但在您实际上不想要这种行为的情况下会导致性能下降。
I thinkthis is mentioned in one of the annotated C# standards. Looking...
我认为在其中一个带注释的 C# 标准中提到了这一点。看着...
EDIT: Annoyingly, I've now looked through the annotated ECMA C# 2 spec, the annotated MS C# 3 spec and the annotation CLI spec, and noneof them mention this as far as I can see. I'm sureI've seen the reason given above, but I'm blowed if I know where. Apologies, reference fans :(
编辑:恼人的是,我现在已经浏览了带注释的 ECMA C# 2 规范、带注释的 MS C# 3 规范和注释 CLI 规范,据我所知,他们都没有提到这一点。我确定我已经看到了上面给出的原因,但如果我知道在哪里,我会感到震惊。抱歉,参考粉丝:(
回答by Ryan
From the C# language spec 1.6.7.5 7.2.6.2 Binary numeric promotions it converts both operands to int if it can't fit it into several other categories. My guess is they didn't overload the + operator to take byte as a parameter but want it to act somewhat normally so they just use the int data type.
从 C# 语言规范 1.6.7.5 7.2.6.2 二进制数字提升,如果它不能适合其他几个类别,它会将两个操作数转换为 int。我的猜测是他们没有重载 + 运算符以将字节作为参数,而是希望它正常运行,因此他们只使用 int 数据类型。
回答by azheglov
The third line of your code snippet:
代码片段的第三行:
byte z = x + y;
actually means
实际上是指
byte z = (int) x + (int) y;
So, there is no + operation on bytes, bytes are first cast to integers and the result of addition of two integers is a (32-bit) integer.
因此,字节上没有 + 操作,字节首先转换为整数,两个整数相加的结果是(32 位)整数。