所以我有这个代码将检查所有数字上的一些数学方程,然后再分配给amount
。当我在小于2_100_000_000的任何数字下运行这段代码时,它工作得很好,但如果它高于2_099_999_999,它会给出下面的错误,我不明白这两个数字之间的区别是什么。
不要尝试运行2_099_999_999,因为这会花费太长时间
错误:Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?)
完整代码:
using System.Collections.Concurrent;
using System.Threading.Tasks.Dataflow;
int start = 20_000_001;
int amount = 2_999_999_999;
int verified = 0;
int canceled = 0;
DateTime Starting_time = DateTime.Now.AddSeconds(85);
ConcurrentBag<int> canceledNumbers = new ConcurrentBag<int>();
var actionBlock = new ActionBlock<int>(CollatzAction,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount * 2
});
for (int i = start; i < start + amount; i++)
{
await actionBlock.SendAsync(i).ConfigureAwait(false);
}
actionBlock.Complete();
await actionBlock.Completion.ConfigureAwait(false);
Console.WriteLine($"{verified} of {amount} numbers were verified, {canceled} were canceled.");
DateTime Ending_time = DateTime.Now.AddSeconds(85);
Console.WriteLine("Starting time: " + Starting_time);
Console.WriteLine("Ending time: " + Ending_time);
void CollatzAction(int i)
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMinutes(2));
var (oneIsReached, isCanceled) = Collatz(i, cts.Token);
if (oneIsReached)
{
Interlocked.Increment(ref verified);
}
else if (isCanceled)
{
Interlocked.Increment(ref canceled);
canceledNumbers.Add(i);
}
}
(bool oneIsReached, bool isCanceled) Collatz(int i, CancellationToken token)
{
long i2 = i;
while (i2 > 1)
{
if (token.IsCancellationRequested)
{
break;
}
if (i2 % 2 == 0)
{
long i3 = i2 / 2;
i2 = i3;
}
else
{
i2 = i2 * 3 + 1;
}
}
return (i2 == 1, token.IsCancellationRequested);
}
但如果它高于2_099_999_999,它将给出以下错误
我不相信那是实际的极限。我相信(例如)2_123_456_789应该没问题。
在c#中,整型字面值的类型是由它们的值决定的。
来自标准:
整型字面值的类型按如下方式确定:
- 如果文本没有后缀,它具有以下类型中第一个可以表示其值的类型:
int
,uint
,long
,ulong
。
2_999_999_999
不能表示为int
,int
的最大值为2,147,483,647。
所以文字2_999_999_999
的类型是uint
,你的代码试图将值赋给int
。没有从uint
到int
的隐式转换,因此会出现编译时错误。您不希望在这里应用显式转换,否则您将由于溢出而最终得到一个负数。
如果需要,可以使用uint
或64位整数类型。