HOWTO · Csharp

在 C# 中通过将两个整数相除来获得双精度值

本教程介绍了两个整数的除法。在 C# 编程中,商取决于操作数的类型。在本文中,我们讨论的主要关注点都是关于两个整数的除法以及将结果作为双精度数据类型。

本页内容

在 C# 中,两个整数相除的结果仍是整数。若要保留商的小数部分,必须在除法发生前先将至少一个操作数转换为 double。当表达式要赋值给浮点变量时,这一点尤其重要:赋值发生在除法之后,无法恢复整数运算已经舍弃的数位。

为什么整数操作数的 30 / 7 结果是 4

/ 运算符会根据操作数的类型选择算术运算。当两个操作数都是 int 时,C# 执行整数除法。对于正数,运算会舍弃小数部分,因此 30 / 7 的结果是 4,而不是 4.285714...。对于带符号的整数,截断方向是趋向零,而不是四舍五入到最接近的整数。

即使目标变量的类型是 double,规则也一样。在 double quotient = 30 / 7; 中,先执行整数除法并得到 4,然后才将这个整数转换为 4.0 并赋值。对已完成的表达式进行转换,例如 (double)(30 / 7),也有同样的限制。整数运算一旦舍弃了小数部分,这两种写法都无法将其恢复。

在除法前转换操作数以得到 double 结果

在使用 / 之前转换一个操作数。强制转换 (double)n1 会改变该操作数的类型,因此除法会使用浮点运算并返回 double。另一个操作数也会在运算时转换。n1 和 n2 保持整数类型没有问题;只需让表达式中的一个操作数是浮点类型。

使用示例中给出的两个整数输入运行这段示例:

本节中的代码以及显示的标签或输出仍为英文。

using System;

public class DivisionExample
{
    public static void Main()
    {
        int n1 = 30;
        int n2 = 7;

        int integerQuotient = n1 / n2;
        double castQuotient = (double)n1 / n2;
        decimal decimalQuotient = (decimal)n1 / n2;
        double convertedQuotient = decimal.ToDouble(decimalQuotient);

        Console.WriteLine($"Integer division: {integerQuotient}");
        Console.WriteLine($"Cast before division: {castQuotient}");
        Console.WriteLine($"Convert decimal quotient: {convertedQuotient}");
    }
}
Integer division: 4
Cast before division: 4.28571428571429
Convert decimal quotient: 4.28571428571429

第一行展示了经过截断的整数商。强制转换和 decimal 两种路径都会保留商的小数部分。对于 int 输入且希望得到 double 结果的情况,直接强制转换最简单:在除法前转换任一操作数,而不是在除法后转换商。若计算过程必须使用特定类型,应将结果声明为相应类型,这样后续运算也会遵循预期的算术规则。

何时使用 decimal.ToDouble

decimal.ToDouble 会将一个已经是 decimal 类型的值转换为 double。如果较早的计算或输入使用 decimal 类型,而后续 API 要求 double,这种转换就很有用。它不能直接转换 int;如示例所示,应先将整数操作数转换为 decimal 并执行 decimal 除法,再将所得的 decimal 商传给 decimal.ToDouble。

如果两个输入都是整数,目标只是得到带小数的商,这种方式会多出一次转换,通常没有必要。此时优先使用 (double)n1 / n2。只有当 decimal 的十进制表示方式和取值范围符合应用需求时,才选择 decimal 运算;它不能保证所有数值或计算都精确。double 的精度也有限,因此许多小数值只能近似表示。应根据计算所需的精度和范围选择数值类型,也不要以为只更改结果变量的类型,就会改变表达式所采用的算术运算。