【问题标题】:C++ size_t modulus operation with negative operand带有负操作数的 C++ size_t 模运算
【发布时间】:2017-01-13 05:08:27
【问题描述】:

所以模运算可以给你三个值:

那么:

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

【问题讨论】:

  • 您的“数学”断言假设在整个数学世界中只有一个模数定义,这当然是不正确的!
  • 对无符号类型的操作不可能有负数。

标签: c++ c++11 size-type


【解决方案1】:

当你混合有符号和无符号值时会发生这种情况——混淆!

[C++14: 5.6/2]:*/的操作数应为算术或无范围枚举类型; % 的操作数应为整数或无范围枚举类型。对操作数执行通常的算术转换并确定结果的类型。

现在,请参阅下面的粗体段落(假设您的 size_t 与您的 int 具有相同的排名;这始终是正确的):

[C++14: 5/10]: 许多期望算术或枚举类型的操作数的二元运算符会导致转换并以类似的方式产生结果类型。目的是产生一个通用类型,这也是结果的类型。 这种模式称为常用算术转换,定义如下:

  • 如果任一操作数属于范围枚举类型 (7.2),则不执行任何转换;如果另一个操作数的类型不同,则表达式格式错误。
  • 如果任一操作数为 long double 类型,则另一个应转换为 long double。
  • 否则,如果任一操作数为双精度,则另一个应转换为双精度。
  • 否则,如果任一操作数为浮点数,则另一个应转换为浮点数。
  • 否则,应在两个操作数上执行积分提升 (4.5)。61 然后以下 规则应适用于提升的操作数:
    • 如果两个操作数的类型相同,则无需进一步转换。
    • 否则,如果两个操作数都是有符号整数类型或都具有无符号整数类型,则整数转换等级较小的操作数应转换为等级较高的操作数类型。
    • 否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号操作数的类型整数类型。
    • 否则,如果带符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为带符号整数类型的操作数的类型输入。
    • 否则,两个操作数都应转换为与带符号整数类型的操作数类型对应的无符号整数类型。

简而言之,您的-7 正在变为std::numeric_limit<size_t>::max() + 1 - 7(无论您的平台上是什么),并且正在对该值执行计算。确实,on my platform, that confirms the result of 1

【讨论】:

  • 所以我应该编写自己的 mod 函数来保持一切一致。谢谢。
  • @Dobob 你不应该盲目地混合无符号和有符号的数学。
  • @Dobob:这根本不是本文的要点。 Serge 是正确的。
猜你喜欢
  • 2012-12-30
  • 2014-05-26
  • 1970-01-01
  • 2018-01-28
  • 2020-11-30
  • 2015-07-23
相关资源
最近更新 更多