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

标签 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

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

问候, 塞巴斯蒂安

最佳答案

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

需要说明的是,尽管我认为您在最初的问题中没有感到困惑,但您分配结果的变量类型对除法运算符重载的确定方式没有影响。

您的顶级案例只是利用隐式转换,它具有与此等效的显式转换。

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

您将它分配给 double 这一事实不会影响 1/1234 的计算结果,如您所见,0,因为该转换发生在除法之后。如果我们在这里在时空上切开一个洞,这个例子将落在本文底部列表的最后一个案例中,其中两个整数相除。因此,根据规范的第 7.8.2 节,这将返回商的底数,或 0


此行为在 C# 5 规范的第 7.3.6 节中进行了描述(我承认,它花了一些时间),重点是我的。

7.3.6 Numeric promotions

...

When overload resolution rules (§7.5.3) are applied to this set of operators, the effect is to select the first of the operators for which implicit conversions exist from the operand types. For example, for the operation b * s, where b is a byte and s is a short, overload resolution selects operator *(int, int) as the best operator. Thus, the effect is that b and s are converted to int, and the type of the result is int. Likewise, for the operation i * d, where i is an int and d is a double, overload resolution selects operator *(double, double) as the best operator.

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

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

• If either operand is of type decimal, the other operand is converted to type decimal, or a binding-time error occurs if the other operand is of type float or double.
Otherwise, if either operand is of type double, the other operand is converted to type double.
• Otherwise, if either operand is of type float, the other operand is converted to type float.
• Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
• Otherwise, if either operand is of type long, the other operand is converted to type long.
• Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
• Otherwise, if either operand is of type uint, the other operand is converted to type uint.
• Otherwise, both operands are converted to type int.

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

关于c# - 在 C# 中需要转换基值类型时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26313394/

相关文章:

c - 严格别名和强制转换 union 指针

C# 正则表达式 : How to extract $1, $2 个来自匹配的变量

c# - 在 C# 中使用 Linq 进行线性化

java - C# 多维数组与 Java 多维数组

c++ - 从 Const 引用接口(interface)向上转换到派生类

c - int to time_t* 打印类型

iphone - MonoTouch 是否需要 Mac 才能发布到 iPhone/iPod Touch?

c# - 使用查询填充组合框时输出错误

c# - 如何在调用 Process.start 方法后向 '.exe' 文件提供第二个输入?

c# - 命名参数与可选参数