如何正确迭代所有长类型范围
本文关键字:类型 范围 何正确 迭代 | 更新日期: 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
}
- 使用
long
类型我该怎么办? - 对于
long
类型,如果我不递增 1,而是增加更高的距离,我怎么能达到相同的效果? - 那些在类型范围内循环的"想法"是否正确,是否有一些问题需要警告,或者我可以做得更好吗?
在前两个示例中,由于数字范围溢出,循环将永远持续。
当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
}
我还没有对它进行基准测试,但我想这样做会有一个明显的性能损失。