C# 为什么(int)==(float)总是编译为(float)==(float)

C# 为什么(int)==(float)总是编译为(float)==(float),c#,.net,cil,system.reflection,C#,.net,Cil,System.reflection,我正在研究C编译器并试图理解数学运算规则 我在两个不同的基元类型之间发现了==运算符的不可理解行为 int a = 1; float b = 1.0f; Console.WriteLine(a == b); 这实际上编译为 .locals init ( [0] int32, [1] float32 ) IL_0000: nop IL_0001: ldc.i4.1 IL_0002: stloc.0 IL_0003: ldc.r4 1 IL_0008: stloc

我正在研究C编译器并试图理解数学运算规则

我在两个不同的基元类型之间发现了==运算符的不可理解行为

int a = 1;
float b = 1.0f;        
Console.WriteLine(a == b);
这实际上编译为

.locals init (
    [0] int32,
    [1] float32
)

IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: ldc.r4 1
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: conv.r4
IL_000b: ldloc.1
IL_000c: ceq
也就是说

(float)a == (float)b
我的期望值是inta==intb,因为左值是一个整数

这一结果的原因是什么

我猜:int->float比float->int快
这实际上与您建议的速度无关,更与隐式转换有关,您可以在中找到数字促销主题下定义的相关信息

12.4.7数字促销

数字升级包括自动执行某些 预定义的一元和二元操作数的隐式转换 二进制数字运算符。数字升级不是一种独特的方式 机制,而是对 预定义的运算符。数字促销不会特别影响 评估用户定义的运算符,尽管是用户定义的运算符 可以实现以显示类似的效果

作为数值提升的一个例子,考虑预定义 二进制*运算符的实现:

当过载解决规则§12.6.4适用于这组运算符时,其效果是选择第一个运算符进行处理 操作数类型中存在哪些隐式转换

更进一步

对预定义的+的操作数进行二进制数字升级,
–, *, /, %, &, |, ^, ==, !=, >, =, 这实际上与您建议的速度无关,更与隐式转换有关,您可以在

12.4.7数字促销

数字升级包括自动执行某些 预定义的一元和二元操作数的隐式转换 二进制数字运算符。数字升级不是一种独特的方式 机制,而是对 预定义的运算符。数字促销不会特别影响 评估用户定义的运算符,尽管是用户定义的运算符 可以实现以显示类似的效果

作为数值提升的一个例子,考虑预定义 二进制*运算符的实现:

当过载解决规则§12.6.4适用于这组运算符时,其效果是选择第一个运算符进行处理 操作数类型中存在哪些隐式转换

更进一步

对预定义的+的操作数进行二进制数字升级,
–, *, /, %, &, |, ^, ==, !=, >, =, 当两者都转换为float时,0!=0.4. 如果两者都转换为int,0==0.4,因为浮点的非整数部分将被丢弃,对吗?事实上,如果两者都转换为int,则0(包括)和1(排除)之间的任何值都将被视为等于0。不存在到int的隐式转换浮点。当两者都转换为浮点时,0!=0.4. 如果两者都转换为int,0==0.4,因为浮点的非整数部分将被丢弃,对吗?事实上,如果两者都转换为int,则0(包括)和1(排除)之间的任何值都将被视为等于0。不存在到int的隐式转换浮点。
int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);
byte b = 1;
short a = 2;
WriteLine((int)b==(int)s); // promotes both to int

int i = 1;
double d = 2;
WriteLine((double)i==d); // promotes i to double
int a = 1;
float b = 1.0f; 
WriteLine((float)a==b); // promotes a to float