简体   繁体   English

查找最大的unsigned int…为什么不起作用?

[英]Find largest unsigned int … Why doesn't this work?

Couldn't you initialize an unsigned int and then increment it until it doesn't increment anymore? 您是否不能初始化一个无符号的int然后增加它,直到它不再增加? That's what I tried to do and I got a runtime error "Timeout." 这就是我试图做的,并且遇到运行时错误“超时”。 Any idea why this doesn't work? 知道为什么这行不通吗? Any idea how to do it correctly? 任何想法如何正确地做到这一点? #include #包括

int main() { 

    unsigned int i(0), j(1);
    while (i != j) {
       ++i;
       ++j;
    }
    std::cout << i;

    return 0;

} 

Unsigned arithmetic is defined as modulo 2^n in C++ (where n is the number of bits). 无符号算术在C ++中定义为模2 ^ n(其中n是位数)。 So when you increment the maximum value, you get 0 . 因此,当增加最大值时,您将获得0

Because of this, the simplest way to get the maximum value is to use -1 : 因此,获得最大值的最简单方法是使用-1

unsigned int i = -1;
std::cout << i;

(If the compiler gives you a warning, and this bothers you, you can use 0U - 1 , or initialize with 0 , and then decrement.) (如果编译器向您发出警告,并且使您0U - 1困扰,则可以使用0U - 1 ,或者使用0初始化,然后递减。)

Since i will never be equal to j , you have an infinite loop. 因为i 永远不会等于j ,所以您有一个无限循环。

Additionally, this is a very inefficient method for determining the maximum value of an unsigned int . 此外,这对于确定unsigned int的最大值来说是一种非常低效的方法。 numeric_limits gives you the result without looping for 2^(16, 32, 64, or however many bits are in your unsigned int ) iterations. numeric_limits可为您提供结果,而无需循环进行2 ^(16、32、64,或者unsigned int )迭代中有很多位。 If you didn't want to do that, you could write a much smaller loop: 如果您不想这样做,可以编写一个更小的循环:

unsigned int shifts = sizeof(unsigned int) * 8; // or CHAR_BITS
unsigned int maximum_value = 1;
for (int i = 1; i < shifts; ++i)
{
    maximum_value <<= 1;
    ++maximum_value;
}

Or simply do 或者干脆做

unsigned int maximum = (unsigned int)-1;

i will always be different than j , so you have entered an endless loop. i将永远不同于j ,因此您进入了一个无穷循环。 If you want to take this approach, your code should look like this: 如果要采用这种方法,则代码应如下所示:

unsigned int i(0), j(1);
while (i < j) {
   ++i;
   ++j;
}
std::cout << i;

return 0;

Notice I changed it to while (i<j) . 注意,我将其更改为while (i<j) Once j overflows i will be greater than j . 一旦j溢出,我将大于j

When an overflow happens, the value doesn't just stay at the highest, it wraps back abound to the lowest possible number. 当发生溢出时,该值不仅会保持最高,还会回绕到尽可能低的数字。

i and j will be never equal to each other. i和j永远不会相等。 When an unsigned integral value achieves its maximum adding to it 1 will result in that the next value will be the minimum that is 0. For example if to consider unsigned char then its maximum is 255. After adding 1 you will get 0. 当一个无符号整数价值得到最大程度的增加了它1将导致下一个值将是0。例如,如果最低要考虑无符号的字符则其最大值为255加1,你会得到0后。

So your loop is infinite. 因此,您的循环是无限的。

Couldn't you initialize an unsigned int and then increment it until it doesn't increment anymore? 您是否不能初始化一个无符号的int然后增加它,直到它不再增加?

No. Unsigned arithmetic is modular, so it wraps around to zero after the maximum value. 不能。无符号算术是模块化的,因此在最大值之后会回零。 You can carry on incrementing it forever, as your loop does. 您可以像循环一样永久地进行递增。

Any idea how to do it correctly? 任何想法如何正确地做到这一点?

unsigned int max = -1;  // or
unsigned int max = std::numeric_limits<unsigned int>::max();

or, if you want to use a loop to calculate it, change your condition to (j != 0) or (i < j) to stop when j wraps. 或者,如果要使用循环来计算它,请将条件更改为(j != 0)(i < j)以在j换行时停止。 Since i is one behind j , that will contain the maximum value. 由于ij后面,所以将包含最大值。 Note that this might not work for signed types - they give undefined behaviour when they overflow. 请注意,这可能不适用于带符号的类型-它们在溢出时会产生未定义的行为。

I assume you're trying to find the maximum limit that an unsigned integer can store (which is 65,535 in decimal). 我假设您正在尝试查找无符号整数可以存储的最大限制(十进制为65,535)。 The reason that the program will time out is because when the int hits the maximum value it can store, it "Goes off the end." 程序超时的原因是,当int达到可存储的最大值时,它“结束了”。 The next time j increments, it will be 65,535; 下次j递增时,它将为65,535; i will be 0. 我将是0。

This means that the way you're going about it, i would NEVER equal j, and the loop would run indefinitely. 这意味着您要使用的方式永远不会等于j,并且循环将无限期地运行。 If you changed it to what Damien has, you'd have i == 65,535; 如果将其更改为Damien拥有的,则i == 65,535; j equal to 0. j等于0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM