【问题标题】:Why is the result of a subtraction of an Int16 parameter from an Int16 variable an Int32? [duplicate]为什么从 Int16 变量中减去 Int16 参数的结果是 Int32? [复制]
【发布时间】:2010-11-08 06:03:35
【问题描述】:

可能重复:
byte + byte = int… why?

我有这样的方法:

 void Method(short parameter)
 {
     short localVariable = 0;
     var result = localVariable - parameter;
 }

为什么结果是Int32 而不是Int16

【问题讨论】:

  • 顺便说一句:哪个是正确的不定冠词? “一个”还是“一个”?
  • 任何类型 T 的两个值的加法和减法都可能得到不适合类型 T 的结果。另请参阅此问题:stackoverflow.com/questions/927391/…
  • 这实际上与stackoverflow.com/questions/941584 相同,只是类型不同,运算符不同。
  • 我猜它是一个,因为 Int32 以“I”开头,但我不是以英语为母语的人......

标签: c# .net variables


【解决方案1】:

这不仅仅是减法,根本不存在短(或字节/字节)算术。

short a = 2, b = 3;
short c = a + b;

会报无法将int(a+b)转换为short(c)的错误。

几乎从不使用 short 的另一个原因。

附加:在任何计算中,short 和 sbyte 将始终“扩展”为 int、ushort 和 byte 到 uint。这种行为可以追溯到 K&R C(而且可能比这更早)。

造成这种情况的(旧)原因是处理 char 时的效率和溢出问题。最后一个原因不再适用于 C#,其中 char 是 16 位并且不能隐式转换为 int。但很庆幸的是,C#数值表达式与C和C++的兼容程度很高。

【讨论】:

  • 需要注意的是,这是C#/CLI标准的一部分。
【解决方案2】:

所有小于 Int32 的整数运算默认在计算前扩展为 32 位。结果是 Int32 的原因只是在计算后保持原样。如果检查 MSIL 算术操作码,它们操作的唯一整数类型是 Int32 和 Int64。这是“设计使然”。

如果您希望返回 Int16 格式的结果,则在代码中执行强制转换是无关紧要的,或者编译器(假设地)“在后台”发出转换。

另外,上面的例子可以很容易地用强制转换解决

short a = 2, b = 3;

short c = (short) (a + b);

这两个数字将扩展为 32 位,相减,然后截断回 16 位,这正是 MS 的预期。

使用短(或字节)的优势主要是在您拥有大量数据(图形数据、流媒体等)的情况下进行存储

附:哦,文章是“a”表示发音以辅音开头的单词,“an”表示发音形式以元音开头的单词。一个数字,一个整数。 ;)

【讨论】:

  • +1 不错的答案。 (并且应该为您对不定冠词的回答加分。;-))
  • 优秀,Kek444。您应该将您的答案添加到这个相关问题 (stackoverflow.com/questions/941584/byte-byte-int-why)。我肯定会赞成。
  • 感谢积极的 cmets,会的。
  • 小挑剔,它们是“加宽”而不是“四舍五入”。整数不需要四舍五入来获得更大的尺寸,浮点数就可以。
  • 是的,谢谢,你是对的,我的意思是位数被四舍五入,而数字本身被扩大了。我会清理的。
【解决方案3】:

此线程中给出的其他答案以及此处给出的讨论具有指导意义:

(1)Why is a cast required for byte subtraction in C#?

(2)byte + byte = int… why?

(3)Why is a cast required for byte subtraction in C#?

但只是再添一个问题,它可能取决于您使用的运算符。递增 (++) 和递减 (--) 运算符以及加法赋值 (+=) 和减法赋值 (-=) 运算符针对各种数值类型进行了重载,它们执行转换结果的额外步骤返回结果时返回操作数的类型。

例如,使用短:

short s = 0;

s++;                // <-- Ok
s += 1;             // <-- Ok
s = s + 1;          // <-- Compile time error!
s = s + s;          // <-- Compile time error!

使用字节:

byte b = 0;

b++;                // <-- Ok
b += 1;             // <-- Ok
b = b + 1;          // <-- Compile time error!
b = b + b;          // <-- Compile time error!

如果他们不这样做,使用增量运算符 (++) 的调用将是不可能的,并且对加法赋值运算符的调用充其量也很尴尬,例如:

short s
s += (short)1;

无论如何,这只是整个讨论的另一个方面......

【讨论】:

    【解决方案4】:

    我认为它自动完成以避免溢出,

    假设你做了这样的事情。

    Short result = Short.MaxValue + Short.MaxValue; 
    

    结果显然不适合。

    我不明白的一件事是为什么不为 int32 也这样做,它会自动转换为 long ???

    【讨论】:

    • 这不是为了防止溢出,更多的是为了阻止低效的代码。并且继承自C/C++
    【解决方案5】:

    你看到的效果...

    short - short = int
    

    ...在这个 Stack Overflow 问题中广泛讨论byte + byte = int… why?

    有很多好信息和一些有趣的讨论来说明为什么会这样。

    这是一个投票率很高的答案:

    我相信这基本上是为了 的表现。 (就“为什么 完全发生”这是因为那里 不是 C# 定义的任何运算符 字节、sbyte、short 或 ushort,就像其他人所说的那样。这 答案是关于为什么那些运营商 没有定义。)

    处理器具有本地操作 非常用 32 位做算术 迅速地。进行转换 从结果到一个字节 可以自动完成,但会 导致性能处罚 你实际上并不想要的情况 这种行为。

    -- 乔恩·斯基特

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      相关资源
      最近更新 更多