So I have this code will check some math equations on all numbers before the number you have assigned to amount
. When I run this code with any number under any number less than 2_100_000_000 it works fine but if its higher than 2_099_999_999 it will give the error bellow, and I do not understand what is the difference between these two number.
don't try running 2_099_999_999 because it will take too long
Erorr: Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?)
Full Code:
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);
}
CodePudding user response:
but if its higher than 2_099_999_999 it will give the error bellow
I don't believe that's the actual limit. I believe it should be fine with (for example) 2_123_456_789.
In the C#, the type of integer literals is determined by their value.
From the standard:
The type of an integer literal is determined as follows:
- If the literal has no suffix, it has the first of these types in which its value can be represented:
int
,uint
,long
,ulong
.
The value 2_999_999_999
cannot be represented as an int
- the maximum value for an int
is 2,147,483,647.
So the type of the literal 2_999_999_999
is uint
, and your code is trying to assign the value to int
. There's no implicit conversion from uint
to int
, hence the compile-time error. You don't want to apply an explicit conversion here, or you'll end up with a negative number due to overflow.
You could use uint
or a 64-bit integer type instead, if you need to.