C++ C++;带负操作数的大小\u t模运算

C++ C++;带负操作数的大小\u t模运算,c++,c++11,size-type,C++,C++11,Size Type,因此,模运算可以给出三个值: 然后: -7%5=3(数学,余数>=0) -7%5=-2(C++) -7%(大小)5=4(C++) 另一个例子: -7%4=1(数学,余数>=0) -7%4=-3(C++) -7%(大小)4=1(C++) 当左手操作数为正时,所有三种方法的答案都相同。但对于负值,它们似乎都有自己的方法。如何在C++中计算未签名操作数的值?< p>这是混合签名和无符号值时发生的情况。混淆! [C++14:5.6/2]:和/的操作数应具有算术或非范围枚举类型%的操作数应具有整数或非范围

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

然后:

-7%5=3(数学,余数>=0)

-7%5=-2(C++)

-7%(大小)5=4(C++)

另一个例子:

-7%4=1(数学,余数>=0)

-7%4=-3(C++)

-7%(大小)4=1(C++)


当左手操作数为正时,所有三种方法的答案都相同。但对于负值,它们似乎都有自己的方法。如何在C++中计算未签名操作数的值?

< p>这是混合签名和无符号值时发生的情况。混淆!
[C++14:5.6/2]:
/
的操作数应具有算术或非范围枚举类型
%
的操作数应具有整数或非范围枚举类型。通常对操作数执行算术转换,并确定结果的类型。

现在,请看下面的粗体部分(假设您的
size\u t
与您的
int
具有相同的等级;这总是正确的):

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

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

简而言之,您的
-7
正在变成
std::numeric\u limit::max()+1-7
(无论您的平台上有什么),并且正在对该值执行计算。事实上,.

您的“数学”断言假设在整个数学世界中只有一个模的定义,这当然是不正确的!对无符号类型的操作不可能采用负操作数。因此,我应该编写自己的mod函数来保持所有操作数的一致性。谢谢。@Dobob你不应该盲目地把无符号和有符号的数学混在一起。@Dobob:这一点都不重要。谢尔盖是对的。