C++负数取模操作中的size_t数据类型

9

所以,模运算可以给出三个值:

然后:

-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 ++中如何计算无符号操作数的模运算值?


4
你的“数学”断言假设整个数学世界只有一个模运算的定义,这显然是不正确的! - Lightness Races in Orbit
3
无符号类型的运算永远不可能使用负数作为操作数。 - user743382
1个回答

14
这就是当你混合使用有符号和无符号值时会发生的事情 - 混淆!
引用块中加粗的段落表示:对于*和/的操作数,应具有算术或未加作用域枚举类型;对于%的操作数,应具有整数或未加作用域枚举类型。在操作数上执行通常的算术转换,并确定结果的类型。
现在,请查看下面加粗的段落(假设您的size_t与int具有相同的rank;这总是正确的):
许多希望操作算术或枚举类型的二元运算符以类似的方式进行转换并产生结果类型。其目的是产生一种常见的类型,也是结果的类型。 这种模式称为通常算术转换,其定义如下:
- 如果任一操作数是作用域枚举类型(7.2),则不执行转换;如果另一个操作数没有相同的类型,则表达式无效。 - 如果任一操作数为long double类型,则将另一个操作数转换为long double。 - 否则,如果任一操作数为double,则将另一个操作数转换为double。 - 否则,如果任一操作数为float,则将另一个操作数转换为float。 - 否则,应对两个操作数执行整数提升(4.5)。然后,应将推广的操作数应用以下规则:
- 如果两个操作数具有相同的类型,则不需要进一步转换。 - 否则,如果两个操作数具有有符号整数类型或两者都具有无符号整数类型,则将具有较小整数转换等级的类型的操作数转换为具有更高等级的操作数的类型。
  • 否则,如果无符号整数类型的操作数级别大于或等于另一个操作数类型的级别,则带有有符号整数类型的操作数将被转换为具有无符号整数类型的操作数的类型。
  • 否则,如果具有有符号整数类型的运算数的类型可以表示无符号整数类型的所有值,则具有无符号整数类型的操作数将被转换为具有有符号整数类型的操作数的类型。
  • 否则,两个操作数都将被转换为与具有有符号整数类型的操作数对应的无符号整数类型。
  • 简而言之,您的-7将变成std::numeric_limit <size_t> ::max() + 1-7(在您的平台上是什么),并且执行该值的计算。确实,我的平台上,这证实了1的结果


    所以我应该编写自己的模块函数来保持一致性。谢谢。 - Dobob
    4
    你不应该毫无思考地混合使用无符号和有符号的数学运算。 - Serge
    2
    @Dobob:这完全不是要传达的观点。Serge 是正确的。 - Lightness Races in Orbit

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接