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

派对

我正在研究 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

我的期望是(int)a == (int)b因为左值是integer.

这个结果有什么原因吗?


  • 这是我的猜测:int->floatfloat->int
一般

这实际上与速度无关(如您所建议的),更多与隐式转换有关,您可以C# 规范中数字促销主题下找到定义的相关信息

12.4.7 数字促销

数字提升包括自动执行预定义的一元二元数字运算符操作数某些隐式转换数字提升不是一种独特的机制,而是将重载解析应用于预定义运算符的效果数值提升特别不会影响用户定义的运算符的评估,尽管可以实现用户定义的运算符以表现出类似的效果。

作为数字提升的示例,请考虑二元 *运算符的预定义实现

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);

重载决策规则(§12.6.4)施加到该组的运营商该效果是选择第一的运营商针对隐式转换从存在操作数类型。

此外

二进制数值提升时为操作数的预定义的+*/%&|^==!=><>=,和<=二元运算符。二进制数字提升将两个操作数隐式转换为公共类型,在非关系运算符的情况下,该类型也成为操作的结果类型。二进制数字提升包括应用以下规则,按照它们在此处出现的顺序:

  • 如果任一操作数的类型为十进制,则另一个操作数将转换为十进制类型,或者如果另一个操作数的类型为 float 或 double,则会发生绑定时间错误。
  • 否则,如果任一操作数的类型为 double,则另一个操作数将转换为 double 类型。
  • 否则,如果任一操作数的类型为 float,则另一个操作数将转换为 float 类型。
  • 否则,如果任一操作数的类型为 ulong,则另一个操作数将转换为 ulong 类型,或者如果另一个操作数的类型为 sbyte、short、int 或 long,则会发生绑定时错误。
  • 否则,如果任一操作数的类型为 long,则另一个操作数将转换为 long 类型。
  • 否则,如果任一操作数的类型为 uint 而另一个操作数的类型为 sbyte、short 或 int,则两个操作数都将转换为 long 类型。
  • 否则,如果任一操作数的类型为 uint,则另一个操作数将转换为 uint 类型。
  • 否则,两个操作数都被转换为 int 类型。

你可以通过他们展示的例子来感受一下

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Cast float to int, or int to float?

来自分类Dev

Datetime int float,为什么我们可以去float但不能去int

来自分类Dev

如果((float)(int_one && int_two)==(float)int_one &&(float)int_two)总是评估为“ false”

来自分类Dev

为什么在添加之前将float转换为int?

来自分类Dev

为什么Go中有int而不是float?

来自分类Dev

为什么float参数适合int函数参数?

来自分类Dev

为什么 int plus float 显示我奇怪的数字?

来自分类Dev

使用FParsec解析float或int * float

来自分类Dev

从'float'转换为'int'?

来自分类Dev

format()int为float

来自分类Dev

整个float与int OverflowError

来自分类Dev

基于int生成float

来自分类Dev

Python float to int, and int to str

来自分类Dev

为什么float **无法用float(*)[5]初始化?

来自分类Dev

为什么float('Inf')是float('Inf')在Python中返回false?

来自分类Dev

什么是tensorflow float ref?

来自分类Dev

在float和int上>>的TypeError

来自分类Dev

(发布)Int vs float性能

来自分类Dev

将Float转换为Int

来自分类Dev

使用FParsec解析int或float

来自分类Dev

在C中将float与int相乘

来自分类Dev

在float和int上>>的TypeError

来自分类Dev

将float转换为int

来自分类Dev

(发布)Int vs float的性能

来自分类Dev

float(int)const的类型特征

来自分类Dev

使用int计算并输出float?

来自分类Dev

int float 与 double 的转换偏好

来自分类Dev

MIT Scheme Int VS Float

来自分类Dev

为什么float.Epsilon而不是零?