我的回收站

技术文章、随笔、文摘及其它
posts - 92, comments - 689, trackbacks - 1, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

关于.NET中的整数除法

Posted on 2005-12-13 15:51 被遗弃的小指 阅读(2200) 评论(17)  编辑 收藏 网摘 所属分类: .NET技术

今天看到群里面有人在问:

double tempf = 20 / 230; tempf = ??

有人回答: 0.086956521739130434782608695652174  这显然是用计算器算出来的。
但是在.NET中,结果是0.0

但是为什么呢?其实一点儿不奇怪,在.NET中,对整数除法定义如下:

  • 整数除法:
    int operator /(int x, int y);
    uint operator /(uint x, uint y);
    long operator /(long x, long y);
    ulong operator /(ulong x, ulong y);

如果右操作数的值为零,则引发 System.DivideByZeroException

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

如果左操作数为最小可表示 intlong 值,右操作数为 -1,则发生溢出。无论操作是在 checked 还是在 unchecked 上下文中发生,此时总是引发 System.OverflowException

所以,20/230得到的结果应该是0,0赋给一个double型的值,就变成了0.0了

 

呵呵,其实我们公司的面试题里面就有一道题是这样子的:

double expectedValue = 1/2; if ( expectedValue > 0 ) { expectedValue = expectedValue + 0.5; } Console.WriteLine(expectedValue);

问最终输出什么,相信大家经过我上面的解释应该可以得出正确的答案了。

Feedback

#1楼   回复  引用  查看    

2005-12-13 16:00 by 蛙蛙池塘      
最近首页帖子更新的可真快。

#2楼   回复  引用  查看    

2005-12-13 17:47 by 楚潇      
if ( expectedValue > 0 )//double类型不推荐这样比较吧
{
expectedValue = expectedValue + 0.5;
}

#3楼   回复  引用  查看    

2005-12-13 18:24 by 双鱼座      
楼主把一个编译器的东西移到.net平台上实属偷换概念。
double tempf = 20 / 230;
编译后运行时其实是
double tempf = 0;
与.net对除法的定义没有任何关系。
如果你写成 20 / 0,根本就不能通过编译。

所有的常量表达式都是编译器直接计算出来。按照最简的原则,没有注明的常量都是整数。所以,20 / 230 与 20.0 / 230 或 20f /230 并不是一个概念。

不过你可以这样写就比较严密了:
int x = 20;
double y = x / 230;
y = ?

#4楼   回复  引用    

2005-12-13 18:35 by efun[未注册用户]
double expectedValue = (double)1/(double)2;

#5楼   回复  引用    

2005-12-13 19:04 by divide[未注册用户]
概念错误 ,这个跟.net的除法没什么关系。

---
群里面
---
这也算是中国的一个特点吧,一般经常用qq的程序员 水平不太高

#6楼   回复  引用    

2005-12-13 19:05 by divide[未注册用户]
efun
只要一个就可以了。

#7楼   回复  引用    

2005-12-13 20:43 by giogio[未注册用户]
嗯,那天做一个递归,结果老是不对,后来才发现是隐式类型转换的问题。

其实如果没有int到double的隐式转换,就很容易发现这个问题。

#8楼[楼主]   回复  引用  查看    

2005-12-13 22:34 by 被遗弃的小指      
to 双鱼座:

谢谢你的提醒,我当然也知道编译器会把它直接计算出来,也许是我上面没有写清楚这个过程,但是编译器就不是按照这个规范来计算出0的么?



to divide:
尽管也许我是一个“水平不太高的程序员”,但是还是没有兴趣和你探讨IM软件的取舍问题。
btw:经常使用QQ的“高水平的程序员”我也认识不少。

#9楼   回复  引用  查看    

2005-12-14 11:08 by 双鱼座      
呵呵,编译器按什么规范计算那是编译器的事情,与.net没有什么关系,这是个概念问题。不重视概念问题就是不严谨。事实上,从你的这篇文章我不仅没有发现你对.net的类型了解得很清晰了,反而非常的模糊。
1.C#中的常量 vs CLR中的常量
2.C#中的类型 vs CLR中的类型

#10楼   回复  引用    

2005-12-14 11:29 by giogio[未注册用户]
-_-b
我说,如果你要反驳divide的话,高水平程序员似乎不要加引号……

to divide
那你说用啥呢?我找不到C#的比较好的IRC频道啊。telnet形式的bbs有哪里?
再说了,.NET是微软的玩意,用QQ挺合适的,嘿嘿嘿。

#11楼[楼主]   回复  引用  查看    

2005-12-14 12:06 by 被遗弃的小指      
to 双鱼座:
编译器按什么规范计算那是编译器的事情,与.net没有什么关系
-------------------------------------------------------------------
不要告诉我你不管采用什么C#也好,VB.NET也罢,VC++.NET也罢你都采用同一个编译器来编译。。。。。
btw:纠正我自己的一个错误,在文中提到的那个整数除法的定义是C#语言的规范,而不是原来提到的"在.NET中,对整数除法定义".

#12楼   回复  引用  查看    

2005-12-14 18:17 by 装配脑袋      
是的,如果在VB.NET里,Dim a As Double = 1 / 2是会得到0.5的

#13楼   回复  引用  查看    

2005-12-14 18:38 by 双鱼座      
我晕......还真有这么不谦虚的人。我什么时候和你讨论过编译器的事情了?显而易见,
《关于.net的整数除法》,而例子却是有关C#编译器的,与.net的整数除法没有任何关系,并且很多人会忽略这种区别。而这种区别却不是可有可无的。
本来你文不对题,我才好心建议你将其中一个常量改为变量,立即就成了C#语法的问题了,就比较切题了,最后的结果是你根本没有接受。居然说出“.net中对整数除法的定义”这种可笑的命题。
OK。我就来告诉你编译器是怎么回事。
在C#里整数常量就是整数。而CLR中所有的常量都必须指定类型。而浮点类型的常量必须是通过显式的浮点数或者用f后缀标识。
在borland delphi.net中,C#中的常量后缀是不能接受的。同时在delphi中也不必区分整数除法或者浮点数除法。/操作符就是浮点除法,div操作符才是整数除法。

#14楼   回复  引用    

2005-12-15 16:27 by 看官[未注册用户]
-_- ! 艾,上大一的同学 都应该知道的

#15楼   回复  引用    

2006-02-25 21:27 by 路过[未注册用户]
@divide
你太不谦虚了!

#16楼   回复  引用    

2006-02-25 21:29 by 路过[未注册用户]
to: giogio
你也很不谦虚!

#17楼   回复  引用    

2006-02-25 21:30 by 路过[未注册用户]
to: 双鱼座
人真是好的,跑题不对了!



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 296311 x9m2BOOj63A=



相关文章:

相关链接: