为什么C ++模运算符对-1%str.size()返回0? [英] Why does the C++ modulo operator return 0 for -1 % str.size()?

查看:74
本文介绍了为什么C ++模运算符对-1%str.size()返回0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑为什么以下代码会产生此输出:

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]

  1. *和/的操作数应具有算术或无范围的枚举类型;%的操作数应具有整数或无作用域的枚举类型.通常对操作数进行算术转换并确定结果的类型.

那么..那些通常的算术转换"呢?这是为了将两个操作数的类型匹配为常见的 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 a std::string::size_type
    • The rank of std::string::size_type is greater than that of signed int
    • Therefore, the signed int operand is converted to type std::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整体转化[转化积分]

    1. 如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(取模2 n 其中n是用于表示无符号类型的位数.[注意:以两位数的补码表示,此转换为概念上的,并且位模式没有变化(如果没有截断).—尾注]
    1. 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 from int (-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆