8 位和 16 位整数的算术运算

Posted

技术标签:

【中文标题】8 位和 16 位整数的算术运算【英文标题】:Arithmetic operations with 8 and 16 bit integers 【发布时间】:2014-09-15 20:57:37 【问题描述】:

我明白为什么这会产生编译时错误:

short x = 1;
short y = 2;
short z = x + y; // compile-time error

我已经理解了为什么它运行时没有任何问题:

short x = 1;
short y = 2;
x += y; // all right, because of c# specs section 7.17.2

但我不知道为什么这也有效:

short x = (short)1 + (short)2;

我希望得到与第一个示例相同的编译时错误,但它运行成功...为什么?

【问题讨论】:

可能是因为在您的上一个示例中,编译器检测到一个常量值? 这实际上不是链接帖子的副本 - OP 特别指出了该帖子中的行为......(***.com/questions/4343624/…) + 运算符将返回(右/左??)上的任何类型 @Radiospace 这不一定是真的。在 C# 中,short + short 返回一个 int。 实际上恰恰相反。它需要一个演员,因为表达式很容易以一种无法察觉的方式溢出,并希望你承认你考虑过这个问题。他们想不出一个体面的语法来强制 += 强制转换。这些转换在 VB.NET 中不是必需的,但默认情况下会检查溢出。哪个“更好”,但非常昂贵。不是 C# 方式。 【参考方案1】:

由于您使用的是常量值,编译器可以检测到它是允许的,在编译时对其进行评估,然后让它执行。生成的 IL 计算结果与键入 short x = 3; 相同。

请注意以下内容也有效(出于相同的原因):

const short x = 1;
const short y = 2;
short z = x + y; 

但这失败了:

const short x = 32000;
const short y = 32001;
short z = x + y;

请注意,这在 C# 语言规范 6.1.9 隐式常量表达式转换中有所涉及:

如果常量表达式的值在目标类型的范围内,则可以将 int 类型的常量表达式(第 7.19 节)转换为 sbyte、byte、short、ushort、uint 或 ulong 类型。

【讨论】:

【参考方案2】:

你的最后一个 sn-p 只是编译成常量 3。编译器不需要调用int 中的任何运算符,它只是在编译时计算并存储值。

short x = 3;一样

这是生成的IL

IL_0001:  ldc.i4.3    //Load the constant 3 into evaluation stack
IL_0002:  stloc.0     // stores the value in stack to x

【讨论】:

【参考方案3】:

我不知道为什么这也有效:

short x = (short)1 + (short)2;

编译器在编译时对 rhs 表达式求值,可以证明结果在界限内。

【讨论】:

short x = 1 + 2; 怎么样?仍应输出一个int,可以在编译时证明它适合short @BenVoigt 可以正常工作,前提是您使用文字(常量)

以上是关于8 位和 16 位整数的算术运算的主要内容,如果未能解决你的问题,请参考以下文章

"Coding Interview Guide" -- 只用位运算不用算术运算实现整数的加减乘除运算

MYSQL04_算术逻辑位运算符运算符对应的习题

PHP中任意大整数的算术运算

python 算术运算

C 指针的算术运算

C 指针的算术运算