因此,模数运算可以为您提供三个值:
,然后
-7%5 = 3(数学,余数> = 0)
-7%5 = -2(C ++)
-7%(size_t)5 = 4(C ++)
另一个例子:
-7%4 = 1(数学,余数> = 0)
-7%4 = -3(C ++)
-7%(size_t)4 = 1(C ++)
当左手操作数为正时,所有三种方法之间的答案是相同的。但对于负面价值观,他们似乎都有自己的方法。如何用C ++计算无符号操作数上的模运算值?
答案 0 :(得分:9)
当您混合有符号和无符号值时会发生这种情况 - 混乱!
[C++14: 5.6/2]:
*
和/
的操作数应具有算术或未范围的枚举类型;%
的操作数应具有整数或无范围的枚举类型。通常的算术转换是在操作数上执行的,并确定结果的类型。
现在,请参阅下面的粗体段落(假设您的size_t
与您的int
具有相同的排名;这始终是真的):
[C++14: 5/10]:
许多期望算术或枚举类型操作数的二元运算符会以类似的方式引起转换并产生结果类型。目的是产生一个通用类型,它也是结果的类型。 此模式称为通常的算术转换,其定义如下:
- 如果任一操作数是作用域枚举类型(7.2),则不执行任何转换;如果另一个操作数的类型不同,则表达式格式不正确。
- 如果任一操作数的类型为long double,则另一个操作数应转换为long double。
- 否则,如果任一操作数为double,则另一个操作数应转换为double。
- 否则,如果任一操作数为float,则另一操作数应转换为float。
- 否则,应对两个操作数执行整数提升(4.5).61然后执行以下操作 规则应适用于推广的操作数:
- 如果两个操作数具有相同的类型,则无需进一步转换。
- 否则,如果两个操作数都有有符号整数类型或两者都有无符号整数类型,则具有较小整数转换等级类型的操作数应转换为具有更高等级的操作数类型。
- 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数应转换为带有无符号的操作数的类型整数类型。
- 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数应转换为带有符号整数的操作数的类型类型。
- 否则,两个操作数都应转换为无符号整数类型,对应于带有符号整数类型的操作数类型。
简而言之,您的-7
正在变为std::numeric_limit<size_t>::max() + 1 - 7
(无论您的平台上是什么),并且正在对该值执行计算。确实,on my platform, that confirms the result of 1
。