-1

假设我有以下内容:

double f;
double c = 5;

Console.WriteLine("{0} | {1}", c, f = 9 / 5 * c + 32);

这将给出输出:5 | 37

同时:

double f;
double c = 5;

Console.WriteLine("{0} | {1}", c, f = 9.0 / 5.0 * c + 32);

将给出正确的输出:(5 | 41表示华氏5摄氏度是多少)

我知道我正在与一个替身合作,但我缺乏洞察力,为什么这两个结果彼此不等价?

4

2 回答 2

2

当您使用整数语法(9 而不是 9.0)时,每个操作都被四舍五入,没有小数

于 2013-09-20T21:32:50.117 回答
1

因为 C 语言 [本质上] 被设计为与硬件无关的汇编语言。因此,除法,除非涉及浮点值,否则是整数除法,CPU 将在一条指令中完成。这意味着像这样的表达式:

int x = 9 ;
int y = 5 ;
int z = x / y ;

这通常会编译成一条机器指令(可能与其他人一起将值加载/存储到寄存器中/从寄存器中存储值,其最终结果是商和余数。因此,上面int z = x / y将解析为1,剩下的4留在表(请注意,如果您想要余数,请使用%运算符:int z = x % y产生预期的4.

如果操作数之一是浮点值,则使用浮点除法(从计算上讲非常昂贵)。

由于 C# 继承自该遗产,因此它的行为方式相同。因此,标准的§14.7.2 说

14.7.2 除法运算符

对于形式为 的操作x / y,应用二元运算符重载决议(第 14.2.4 节)来选择特定的运算符实现。操作数转换为所选运算符的参数类型,结果的类型为运算符的返回类型。

下面列出了预定义的除法运算符。x运算符都计算和的商y

  • 整数除法:

    int   operator /( int   x, int   y );
    uint  operator /( uint  x, uint  y );
    long  operator /( long  x, long  y );
    ulong operator /( ulong x, ulong y );
    void  operator /( long  x, ulong y );
    void  operator /( ulong x, long  y );
    

具有void返回类型的运算符总是会产生编译时错误。因此,一个操作数是 typelong而另一个是type 是错误的ulong

如果右操作数的值为零,System.DivideByZeroException则抛出 a。

除法将结果向零舍入,结果的绝对值是小于两个操作数的商的绝对值的最大可能整数。当两个操作数具有相同符号时,结果为零或正,当两个操作数具有相反符号时,结果为零或负。

如果左操作数是最小值intlong值(分别为 -2 31或 -2 63)并且右操作数是–1,则发生溢出。在checked上下文中,这会导致System.ArithmeticException抛出一个(或其子类)。在unchecked 上下文中,实现定义是否System.ArithmeticException抛出 a(或其子类)或溢出未报告,结果值为左操作数的值。

[省略了浮点和十进制除法的讨论]

这就是为什么。

于 2013-09-20T22:25:13.580 回答