Home > Software design >  Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (a
Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (a

Time:12-01

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.

  •  Tags:  
  • c#
  • Related