在C#中需要转换基值类型时

时间:2014-10-11 09:56:45

标签: c# casting mono double

当使用数学运算时,我有一个关于在基值类型之间进行转换的一般问题。 Microsoft C#规范中是否有任何书面规则?我找不到他们。在Mono中它的功能是否相同?

示例:

double a = 1 / 1234;                    //Result is 0
double b = 1.0 / 1234;                  //Result is 0,000810372771474878
double c = 1.0 / (double)1234;          //Result is 0,000810372771474878
double d = (double)1 / (double)1234;    //Result is 0,000810372771474878
double e = 1 / 1234.0;                  //Result is 0,000810372771474878

我可以假设当被除数或除数是双倍时结果总是加倍吗? 或者出于某种原因,确保两者都是双打更好(参见案例d - 我见过很多这样的代码实际上让我问这个问题)

此致 塞巴斯蒂安

2 个答案:

答案 0 :(得分:4)

长话短说,是的,可以安全地假设当二进制操作的至少一侧被输入时,编译器将假设double。你不需要明确(尽管从可读性的角度来看,有时候它可能是有用的,这并不是真正相关的,但值得一提)。

而且要清楚,虽然我不认为你在原始问题中有这种困惑,但你分配结果的变量类型对如何确定除法运算符重载没有影响。 / p>

你的大写只是利用一个隐式转换,它具有明确的等价。

double a = (double)(1 / 1234);

您将其分配给double的事实不会影响1 / 1234评估的事实,正如您所发现的那样0,因为该演员事后发生在0分裂。如果我们在这里的时空中挖一个洞,这个例子将落到这篇文章底部列表的最后一个案例中,其中两个整数被划分。因此,根据规范的第7.8.2节,这将返回商的最低限度,或double


这种行为在C#5规范的7.3.6节中有所描述(我承认,这需要一些看法),重点是我的。

  

7.3.6数字促销

     

...

     

当重载决策规则(第7.5.3节)应用于这组运算符时,效果是从操作数类型中选择存在隐式转换的第一个运算符。例如,对于操作b * s,其中b是一个字节而s是short,重载决策选择operator *(int,int)作为最佳运算符。因此,效果是b和s转换为int,结果的类型为int。 同样,对于操作i * d,其中i是int且d是double,重载分辨率选择operator *(double,double)作为最佳运算符。

当然,这不仅适用于其示例所示的乘法,而且适用于任何二元运算。

为了好的衡量,层次结构如下,取自7.3.6.2,重点仍然是我的。

  

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

实际上,编译器实际上通过将非double操作数转换为{{1}}类型来为您执行该转换。

答案 1 :(得分:1)

当你除以两个整数时,你得到一个整数结果。由于int无法保留0,000810372771474878,结果将被截断为0,然后0(int)将转换为double并获得0.0 } 结果。

为了获得浮点结果,其中一个操作数应该是浮点类型。在这种情况下,整数操作数将转换为double / floatdecimal,具体取决于关于你的号码类型。

C# Specification 7.7.2 Division operator

中有关于除法运算符的详细信息