有许多不同的舍入约定,最常见的是向 +inf 舍入、向 -inf 舍入和向零舍入。很多人都认为有一种正确的方法,但他们对这种方法应该是什么有不同的看法;-)
整数除法没有中间非整数结果,但当然除法是确定性完成的,并且对于特定平台和编译器将始终遵循一种特定的舍入约定。
使用 Visual C++,我得到 5/2 = 2 和 -5/2 = -2,向零舍入。
C、C++ 和 Java 中的舍入通常称为“截断”——意思是去掉不需要的位。但这可能具有误导性。使用 4 位 2s 补码二进制,做截断意味着给出...
5/2 = 0101/0010 = 0010.1 --> 0010 = 2
-5/2 = 1011/0010 = 1101.1 --> 1101 = -3
这是向 -infinity 四舍五入,这就是 Python 所做的(或至少它在 Python 2.5 中所做的)。
如果我们使用符号幅度表示,截断是正确的词,但二进制补码几十年来一直是事实上的标准。
在 C 和 C++ 中,我希望虽然它通常被称为截断,但实际上这个细节在标准中没有定义并留给实现 - 允许编译器为平台使用最简单和最快的方法的借口(什么处理器除法指令自然会这样做)。如果你有负数,这只是一个问题 - 我还没有看到任何可以给出 5/2 = 3 的语言或实现。
我不知道 Java 标准是怎么说的。 Python 手册指定了“下限”除法,这是舍入到 -infinity 的常用术语。
编辑
额外说明 - 根据定义,如果 a/b = c 余数 d,则 a = (b*c)+d。为此,您必须选择余数以适应您的舍入约定。
人们倾向于假设余数和模数相同,但 WRT 符号值可能不同 - 取决于舍入规则。根据定义,模值永远不会是负数,但余数可以是负数。
我怀疑 Python 舍入负无穷大规则旨在确保单个 % 运算符作为余数和模数均有效。在 C 和 C++ 中,% 的含义(余数或模数)是(是的,您猜对了)实现定义。
Ada 实际上有两个独立的运算符 - mod 和 rem。需要将除法四舍五入到零,因此 mod 和 rem do 给出不同的结果。