如何正确迭代所有长类型范围

本文关键字:类型 范围 何正确 迭代 | 更新日期: 2023-09-27 18:34:47

如果我想遍历所有长范围,我会巧妙地做:

for (long i = long.MinValue; i <= long.MaxValue; ++i)
{
    // Do something
}

但它永远循环!

例如,如果我这样做:

for (byte b = byte.MinValue; b <= byte.MaxValue; ++b)
{
    // Do something
}

它也永远循环,但我是这样解决的:

for (int i = byte.MinValue; i <= byte.MaxValue; ++i)
{
    byte b = Convert.ToByte(i);
    // Do something
}
  1. 使用long类型我该怎么办?
  2. 对于long类型,如果我不递增 1,而是增加更高的距离,我怎么能达到相同的效果?
  3. 那些在类型范围内循环的"想法"是否正确,是否有一些问题需要警告,或者我可以做得更好吗?

如何正确迭代所有长类型范围

在前两个示例中,由于数字范围溢出,循环将永远持续。

i(第一个示例(或b(第二个示例(超过long(第一个示例(或byte(第二个示例(中可以存储的最大值时,它们的值将溢出到该类型可存储的最小值,循环会反复开始。

请记住:在for循环中,首先检查循环条件,然后检查计数器递增。如果计数器在增量期间溢出,则后续循环条件检查的计算结果仍为 true

要使示例正常工作,请尝试:

for (long i = long.MinValue; ; i++) 
{
    if (i == long.MaxValue)
    {
        break;
    }
}

如果要以更大的步长递增,请尝试:

const long step = 90000000000;
for (long i = long.MinValue; i <= long.MaxValue; )
{
    // check if loop counter overflows when incrementing by the step
    if (unchecked (i + step) < i)
    {
         break;
    }
    // otherwise it is safe to increment it
    else
    {
         i += step;
    }
}
这是

由尝试递增超过MaxValue时的整数溢出引起的。 您可以尝试以下操作:

long i = long.MinValue;
do
{
    // Do something
} while (i++ != long.MaxValue);

这样,i的值在递增之前被检查,循环将正确终止。

您可以使用 BigInteger 来保持循环模式相同并避免溢出:

for (BigInteger i = long.MinValue; i <= long.MaxValue; ++i)
{
    // Do something
}

我还没有对它进行基准测试,但我想这样做会有一个明显的性能损失。

相关文章: