为什么C ++模运算符对-1%str.size()返回0? [英] Why does the C++ modulo operator return 0 for -1 % str.size()?
问题描述
我很困惑为什么以下代码会产生此输出:
I'm confused why the following code produces this output:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = -1;
string s = "abc";
int j = s.size();
int x = 1 % 3;
int y = i % j;
int z = i % s.size();
cout << s.size() << endl; // 3
cout << x << endl; // 1
cout << y << endl; // -1
cout << z << endl; // 0
}
为什么z = 0?与铸造有关吗?
Why is z = 0? Does it have to do with casting?
推荐答案
因此,将您的代码简化为 minimum 示例,您在问为什么打印 0
:
So, stripping down your code to a minimal example, you're asking why this prints 0
:
#include <iostream>
#include <string>
int main()
{
int a = -1;
std::string::size_type b = 3;
int c = a % b;
std::cout << c << '\n';
}
这里要讨论的主要操作是这样:
The primary operation in question here is this:
a % b
按照标准,
5.6乘法运算符[expr.mul]
- *和/的操作数应具有算术或无范围的枚举类型;%的操作数应具有整数或无作用域的枚举类型.通常对操作数进行算术转换并确定结果的类型.
那么..那些通常的算术转换"呢?这是为了将两个操作数的类型匹配为常见的 prior 类型,以执行实际的操作.以下是顺序:
So.. what about those "usual arithmetic conversions"? This is to mate the types of the two operands to a common type prior to performing the actual operation. The following are considered in order :
- 如果两个操作数都是整数,则首先对两个操作数执行整数提升.如果在整数提升之后操作数仍然具有不同的类型,则转换将继续如下:
- 如果一个操作数的无符号类型T的转换等级至少与另一操作数的类型相同,则另一操作数将转换为类型T.
- 否则,一个操作数的符号类型为T,其转换等级高于另一操作数的类型.仅当类型T能够表示其先前类型的所有值时,另一个操作数才会转换为类型T.
- 否则,两个操作数都将转换为与有符号类型T对应的无符号类型.
这是有效的说法的很多:
- 您有两个操作数,一个
signed int
和一个std :: string :: size_type
-
std :: string :: size_type
的等级比signed int
的等级更大 - 因此,将
signed int
操作数转换为要请求的操作的std :: string:size_type
prior 类型.
- You have two operands, a
signed int
and astd::string::size_type
- The rank of
std::string::size_type
is greater than that ofsigned int
- Therefore, the
signed int
operand is converted to typestd::string:size_type
prior to the operation being requested.
因此,剩下的就是转化,也就是说,还有另外一件合法化的事情:
So all that is left is the conversion, to wit, there is one more piece of legalize:
4.7整体转化[转化积分]
- 如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(取模2 n 其中n是用于表示无符号类型的位数.[注意:以两位数的补码表示,此转换为概念上的,并且位模式没有变化(如果没有截断).—尾注]
- If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note]
这意味着,在32位
std :: string :: size_type
平台上,您将获得2 32 -1作为int
(-1).That means, on a 32-bit
std::string::size_type
platform, you're going to get 232-1 as the converted value fromint
(-1).这意味着...
4294967295 % 3
哪个是... 零.如果
std :: string :: size_type
是64位,则上面的所有内容均保持不变,除非最终计算为:Which is... zero. If
std::string::size_type
is 64-bits, then everything above stays the same, save for the final calculation, which would be:18446744073709551615 % 3
这篇关于为什么C ++模运算符对-1%str.size()返回0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!