C++/Java负数取余(模)

本文对比了C++与Java中取余运算的具体行为,特别是在C++11标准下对于负数取余的明确规定,并通过实际测试验证了Java的行为与C++11的要求一致。

C++用了些年头,Java刚刚学一个多月。

新的C++11标准对取余有了比较明确的规定:

C++ Primer 5th:

The % operator, known as the “remainder” or the “modulus” operator, computes the remainder that results from dividing the left-hand operand by the right-hand operand. The operands to % must have integral type.

In a division, a nonzero quotient is positive if the operands have the same sign and negative otherwise. Earlier versions of the language permitted a negative quotient to be rounded up or down; the new standard requires the quotient to be rounded toward zero (i.e., truncated).

The modulus operator is defined so that if m and n are integers and n is nonzero, then (m/n)*n + m%n is equal to m. By implication, if m%n is nonzero, it has the same sign as m. Earlier versions of the language permitted m%n to have the same sign as n on implementations in which negative m/n was rounded away from zero, but such implementations are now prohibited. Moreover, except for the obscure case where -m overflows, (-m)/n and m/(-n) are always equal to -(m/n), m%(-n) is equal to m%n,
and (-m)%n is equal to -(m%n). More concretely:

Code:
21 % 6; /* result is 3 */
21 % 7; /* result is 0 */
-21 % -8; /* result is -5 */
21 % -5; /* result is 1 */

21 / 6; /* result is 3 */
21 / 7; /* result is 3 */
-21 / -8; /* result is 2 */
21 / -5; /* result is -4 */


C++ Primer 4th:

For both division (/) and modulus(%), when both operands are positive, the result is positive (or zero). If both operands are negative, the result of division is positive (or zero) and the result of modulus is negative (or zero). If only one operand is negative, then the value of the result is machine-dependent for both operators. The sign is also machine-dependent for modulus; the sign is negative (or zero) for division:

     21 % 6;   //  ok: result is 3
     21 % 7;   //  ok: result is 0
     -21 % -8; //  ok: result is -5
     21 % -5;  //  machine-dependent: result is 1 or -4
     21 / 6;   //  ok: result is 3
     21 / 7;   //  ok: result is 3
     -21 / -8; //  ok: result is 2
     21 / -5;  //  machine-dependent: result -4 or -5
When only one operand is negative, the sign and value of the result for the modulus operator can follow either the sign of the numerator or of the denominator. On a machine where modulus follows the sign of the numerator then the value of division truncates toward zero. If modulus matches the sign of the denominator, then the result of division truncates toward minus infinity.

本人实测结果:

编译环境:VS2008 SP1 on Win7 SP1 x64

21 % -5 = 1;

21 / -5 = -4;


Java:

因为Java还是绝对的新手,不知道哪里有Java对取余做的比较明确规范的文档参考。所以只能是在自己的电脑上用编译器做测试:

21 % 6 = 3;
21 % 7 = 0;
-21 % -8 = -5;
21 % -5 = 1;
21 / 6 = 3;
21 / 7 = 3;
-21 / -8 = 2;
21 / -5 = -4

这里测试的结果和C++11要求的结果是一致的。

<think>嗯,用户问能不能负数。这个问题看起来简单,但需要仔细分析。首先,我得回忆一下运算的基本定义。运算通常除法相关,数是除法后的剩部分。但处理负数时,不同的编程语言可能有不同的实现方式,这可能会导致数为负数的情况。 比如,在数学中,数一般是非负的,但在编程中,像PythonJavaScript这样的语言,当被除数或除数为负数时,数的符号可能不同。例如,在Python中,-7 % 3的结果是2,而7 % -3的结果是-1。这可能让用户感到困惑,为什么数会有负数? 接下来,我需要考虑用户可能的背景。如果用户是刚开始学习编程,可能对操作的结果期望数学中的数概念不一致。这时候需要解释清楚不同语言的处理方式,以及为什么会有这样的差异。另外,用户可能在实际编码中遇到了负数数的问题,需要知道如何处理或者避免这种情况。 还要注意用户的问题是否涉及到数学定义编程实现的区别。数学上,数通常定义为非负数,而编程语言中根据实现的不同可能会有不同的结果。例如,Python遵循的是“除数正负决定数符号”的规则,而有些语言可能让数的符号与被除数相同。 另外,可能用户需要知道如何在不同语言中处理负数的情况,比如如何确保数始终为非负数。这时候可以提供一些实际的代码示例,比如使用条件判断或者数学公式来调整结果。 总结一下,回答需要包括以下几点: 1. 运算的基本概念。 2. 数学定义与编程实现的差异。 3. 不同编程语言中的处理方式举例。 4. 负数数的应用场景或如何处理。 需要确保用中文清晰解释,结构分明,并给出示例帮助用户理解。同时要避免使用过于专业的术语,保持通俗易懂。可能还需要提醒用户注意在跨语言编程时的注意事项,以及如何根据需调整数的符号。</think>--- 运算(即运算)的结果是否可以为负数,**决于编程语言的定义运算规则**。以下是详细分析: --- ### **一、数学定义与编程实现的差异** 1. **数学中的数** 数学上,数通常定义为非负数,且满足: $$ a = b \times q + r \quad (0 \leq r < |b|) $$ 例如:$7 \div 3 = 2 \text{ } 1$,即 $7 = 3 \times 2 + 1$,数为正数。 2. **编程中的运算** 编程语言在处理负数时,数的符号可能由**被除数或除数的符号**决定,不同语言规则不同。 --- ### **二、不同编程语言的行为** 1. **Python:数符号由除数决定** - 数符号与除数一致: ```python print(-7 % 3) # 输出 2(除数3为正,数为正) print(7 % -3) # 输出 -2(除数-3为负,数为负) ``` 2. **JavaScript/Java/C++数符号由被除数决定** - 数符号与被除数一致: ```javascript console.log(-7 % 3); // 输出 -1(被除数-7为负,数为负) console.log(7 % -3); // 输出 1(被除数7为正,数为正) ``` 3. **C#:数符号与被除数一致** ```csharp Console.WriteLine(-7 % 3); // 输出 -1 Console.WriteLine(7 % -3); // 输出 1 ``` --- ### **三、负数数的应用场景** 1. **周期性计算** 例如:计算时间循环(将负数时间映射到正数范围): ```python time = -5 % 24 # 输出 19(表示晚上7点) ``` 2. **密码学与哈希算法** 需要确保数为正时,可手动调整: ```python def safe_mod(a, b): return a % b if b > 0 else a % -b ``` --- ### **四、如何确保数为非负数?** 若需强制数为正,可通过公式调整: $$ r = (a \% b + b) \% b $$ - **Python示例**: ```python a, b = -7, 3 r = a % b # 输出 2(无需调整) ``` - **JavaScript示例**: ```javascript let a = -7, b = 3; let r = ((a % b) + b) % b; // 输出 2 ``` --- ### **五、总结** | 关键点 | 说明 | |---------------------|-------------------------------------------| | **数可为负数** | 决于编程语言的规则 | | **符号决定因素** | 被除数或除数(不同语言规则不同) | | **强制数为正** | 使用公式 $(a \% b + b) \% b$ 调整 | --- **实际建议**: 1. 查阅所用语言的规则文档。 2. 涉及负数时,优先使用调整公式确保数非负。 3. 在算法设计中明确数的符号需,避免逻辑错误。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值