假设我有以下内容:
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度摄氏度)
我知道我正在使用双倍,但我不清楚为什么两种结果彼此不相同?
答案 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节) 选择特定的运营商实施。操作数将转换为参数类型 所选运算符的类型,结果的类型是运算符的返回类型。下面列出了预定义的除法运算符。 运算符都计算
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
返回类型的运算符始终产生编译时错误。所以, 如果一个操作数的类型为long
而另一个操作数的类型为ulong
则为错误。如果右操作数的值为零,则抛出
System.DivideByZeroException
。除法将结果舍入为零,结果的绝对值为 最大可能的整数,小于商的绝对值 两个操作数。当两个操作数具有相同的结果时,结果为零或正 当两个操作数具有相反的符号时,符号和零或负。
如果左操作数是最小的
int
或long
值(-2 31 或-2 63 , 分别)和右操作数是–1
,发生溢出。在checked
上下文中,这个 导致抛出System.ArithmeticException
(或其子类)。在unchecked
上下文,它是实现定义的System.ArithmeticException
(或者是{。} 抛出其子类或溢出未报告,结果值为 左操作数。[关于浮点和小数除法的讨论]
这就是原因。