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

时间:2012-03-23 14:52:01

标签: c# algorithm int double

C#中所有有经验的程序员(我认为这来自C)用于对一个除法中的整数进行强制转换,得到十进制/双/浮点结果而不是int(实际结果被截断)。

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

6 个答案:

答案 0 :(得分:13)

C#将其遗产追溯到C,所以答案为“为什么在C#中这样?”是“C为什么会这样?”的组合。并且“没有充分的理由改变?”

C的方法是在高级语言和低级操作之间具有相当接近的对应关系。处理器通常实现整数除法,作为返回商和余数,两者都与操作数的类型相同。

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

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

那么,没有充分的理由改变吗?我无法想到,我可以想到改变的一些好理由。其他答案都没有提到Visual Basic(至少通过版本6)有两个运算符来划分整数:/将整数转换为double,并返回一个double,而\执行正常的整数运算

在努力使用浮点除法实现二进制搜索算法之后,我了解了\运算符。真的很痛苦,整齐的分裂就像呼吸新鲜空气一样。没有它,在程序的初稿中有很多特殊处理来覆盖边缘情况和一个一个错误。

根据这一经验,我得出的结论是,使用不同的运算符来划分整数是令人困惑的。

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

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

据我所知,“int / int yield int”的替代品在语言可用性方面无法进行成本效益分析,因此没有理由改变从C继承的行为。

总结:

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

答案 1 :(得分:12)

  

如果两个数字都是整数,是否有任何理由截断结果?

当然;我可以很容易地想到十几个这样的场景。例如:您有一个大图像,并且图像的缩略图版本在两个维度上都小10倍。当用户单击大图像中的某个点时,您希望识别缩小图像中的相应像素。显然,你将x和y坐标除以10.为什么你想得到一个 in decimal 的结果?相应的坐标将成为缩略图位图中的整数坐标。

双打非常适合物理计算,小数位对于财务计算非常有用,但几乎所有用于完成任何数学计算机的工作都完全用整数表示。我不想因为我做了一些分裂而不断地将双精度或小数转换回整数。如果您正在解决物理或财务问题,那么为什么您首先使用整数?使用 nothing 但是加倍或小数。使用整数来解决有限的数学问题。

答案 2 :(得分:10)

计算整数的速度(通常)比浮点值更快。此外,所有其他整数/整数运算(+-*)都返回一个整数。

编辑: 根据OP的要求,这里有一些补充:

OP的问题在于他们认为/在数学意义上是除法,而语言中的/运算符执行其他操作(不是数学除法)。通过这种逻辑,他们应该质疑所有其他操作(+-*)的有效性,因为这些操作具有特殊的溢出规则,这与预期的不同来自他们的数学同行。如果这对某人来说很麻烦,他们应该找到另一种语言,其中的操作按照人的预期执行。

关于有利于整数值的性能差异的主张:当我写答案时,我只有“民间”知识和“直觉”来支持声明(这是我的“通常”免责声明)。事实上,正如加布指出的那样,有些平台并不成立。另一方面,我发现这个link(第12点)显示了英特尔平台上的混合性能(不过使用的语言是Java)。

外卖应该是有表现的,许多主张和直觉在经过测量并发现真实之前是不成立的。

答案 3 :(得分:2)

是的,如果最终结果需要是一个整数。这取决于要求。

如果这些确实是您的要求,那么您不希望存储小数,然后截断它。你会浪费内存和处理时间来完成已经内置的功能。

答案 4 :(得分:2)

操作符设计为返回与输入相同的类型。

编辑(评论回复): 为什么?我不设计语言,但我会假设大多数时候你会坚持使用你开始使用的数据类型,在剩下的实例中,你会用什么标准自动假设用户想要哪种类型?你需要它时会自动期待一个字符串吗? (诚​​意打算)

答案 5 :(得分:1)

如果向int添加int,则期望获得int。如果从int中减去int,则期望获得int。如果你用int多个int,你期望得到一个int。那么,如果将int除以int,为什么不期望int结果呢?如果你期望一个int,那么你将不得不截断。

如果你不想那样,那么你需要先将你的注意力转换为其他东西。

编辑:我还要注意,如果你真的想了解这是为什么,那么你应该开始研究二进制数学如何工作以及如何在电子电路中实现它。当然没有必要详细了解它,但快速概述它将真正帮助您了解硬件的低级细节如何过滤到高级语言的细节。