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

C#中所有有经验的程序员(我认为这来自C)用于对分区中的整数进行强制转换,以获得decimal / double / float结果而不是int(实际结果被截断)。

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

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

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

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

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

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

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

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

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

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

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

结论:

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

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

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

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

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

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

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

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

外卖应该是表现许多声称和直觉是未经证实的,直到测量和发现真实。

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

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

操作符旨在返回与输入相同的类型。

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

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

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

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