c# - 为什么两个整数之间的除法结果会被截断?

标签 c# algorithm int double

所有有经验的 C# 程序员(我认为这来自 C)都习惯于对除法中的整数进行强制转换以获得小数/ double / float 结果而不是 int(截断的实际结果)。

我想知道为什么要这样实现?如果两个数字都是整数,是否有任何充分的理由截断结果?

最佳答案

C# 的历史可追溯至 C,因此“为什么在 C# 中会这样?”的答案是“为什么在 C 中会这样?”的组合。和“没有充分的理由改变吗?”

C的做法是在高级语言和低级操作之间有一个相当紧密的对应关系。处理器通常将整数除法实现为返回商和余数,它们与操作数的类型相同。

(所以我的问题是,“为什么类 C 语言中的整数除法不返回两个整数”,而不是“为什么它不返回浮点值?”)

解决方案是为除法和余数提供单独的操作,每个操作返回一个整数。在 C 的上下文中,这些操作中的每一个的结果都是整数也就不足为奇了。这通常比浮点运算更准确。考虑您对 7/3 的评论中的示例。此值不能用有限二进制数或有限十进制数表示。换句话说,在今天的计算机上,我们不能准确地表示 7/3 除非我们使用整数!这个分数最准确的表示是“商 2,余数 1”。

那么,是否没有充分的理由进行更改?我想不出,而且我可以想出一些改变的好理由。其他答案都没有提到 Visual Basic(至少到第 6 版)有两个用于除以整数的运算符:/ 将整数转换为 double ,并返回 double ,而 \ 执行正常的整数运算。

在努力实现使用浮点除法的二进制搜索算法后,我了解了 \ 运算符。真的很痛苦,整数除法就像一股清新的空气进来了。没有它,在程序的初稿中会有很多特殊处理来涵盖边缘情况和差一错误。

从那次经历中,我得出结论,使用不同的运算符来除整数会造成混淆。

另一种选择是只有一个整数运算,它总是返回一个 double 值,并要求程序员截断它。这意味着您每次需要整数除法时都必须执行两次 int->double 转换,一次截断和一次 double->int 转换。有多少程序员会错误地将结果舍入或舍入而不是截断结果?这是一个更复杂的系统,至少同样容易出现程序员错误,而且速度更慢。

最后,除了二分查找之外,还有许多采用整数运算的标准算法。一个例子是将对象集合分成大小相似的子集合。另一个是在一维数组中的索引和二维矩阵中的坐标之间进行转换。

据我所知,就语言可用性而言,“int/int yields int”的替代方案无法通过成本效益分析,因此没有理由更改从 C 继承的行为。

总结:

  • 整数除法在许多标准算法中经常有用。
  • 当需要对整数进行浮点除法时,可以使用简单、简短和清晰的转换显式调用:(double)a/b 而不是 a/b
  • 其他替代方案会给程序员和处理器带来更多的时钟周期。

关于c# - 为什么两个整数之间的除法结果会被截断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9841332/

相关文章:

java - 素数程序的意外输出

algorithm - 如何去掉数学表达式中不必要的括号

string - sprintf(将 int 转换为 char[])

c# - 使用具有外键的表将数据从 asp.net 页面插入到我的数据库

c# - Azure 服务总线队列 - 将锁定的消息释放回队列

c# - 使用平方根查找素数

java - 将 int 转换为 String(Java)

cocoa - 在 Cocoa 中设置权限

c# - 等效于 Visual Basic 中用于 For Each 循环的 var

c# - 如何将按钮的 Hold/DoubleTap 事件绑定(bind)到 ViewModel 中的属性