为什么在乘以双精度时会有不同的输出?

时间:2013-09-20 21:28:20

标签: c# double

假设我有以下内容:

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度摄氏度)

我知道我正在使用双倍,但我不清楚为什么两种结果彼此不相同?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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节)   选择特定的运营商实施。操作数将转换为参数类型   所选运算符的类型,结果的类型是运算符的返回类型。

     

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

     
      
  • 整数除法:

    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返回类型的运算符始终产生编译时错误。所以,   如果一个操作数的类型为long而另一个操作数的类型为ulong则为错误。

     

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

     

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

     

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

     

[关于浮点和小数除法的讨论]

这就是原因。