Share via

Problem with UInt16 arithmetic

Roger Garrett 1 Reputation point
2021-02-01T21:33:26.527+00:00

I've got some incredibly simple code. Three UInt16 variables. I can do simple assignments but it won't let me do simple arithmetic.

Here's the code

        UInt16 A = 1; // This is OK
        UInt16 B = 2; // This is OK
        UInt16 C = A * B; // Does NOT like this.
        C = A * 2; // Does NOT like this.

It highlights the A * B and reports that the A * B part Cannot implicitly convert type "int" to "ushort". An explicit conversion exists. Are you missing a cast?
Likewise for the A * 2 part;

Why doesn't it accept that? What is it expecting me to change?

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

4 answers

Sort by: Most helpful
  1. cheong00 3,491 Reputation points Volunteer Moderator
    2021-02-02T03:24:59.817+00:00

    Humm... I think this is not the most appropriate answer because it does not explain why the compiler won't complain the following code snippet:

    UInt32 A = 1;
    UInt32 B = 2;
    UInt32 C = A * B;
    Console.WriteLine(C);
    

    IMO the real reason is that the MSIL only define arithmetic operators for 32-bit operands only, so the parameter and result of multiplication is Int32/UInt32 before return, and that won't fit in UInt16 therefore explicit conversion is required.

    Was this answer helpful?

    0 comments No comments

  2. WayneAKing 4,936 Reputation points
    2021-02-02T03:10:08.7+00:00

    In addition to the references provided by Timon, the following
    page will show the limits of the various types. Knowing the
    maximum capacity of an arithmetic type is crucial to predicting
    whether or not the calculations you perform may result in data
    loss, due for example to an overflow.

    Integral numeric types (C# reference)
    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types

    • Wayne

    Was this answer helpful?

    0 comments No comments

  3. WayneAKing 4,936 Reputation points
    2021-02-02T02:42:54.847+00:00

    Promotion to int occurs automatically for arithmetic calculations.
    So the result of your arithmetic operations is an int.
    Cast the expressions to a UInt16.

    UInt16 A = 1; // This is OK
    UInt16 B = 2; // This is OK
    //UInt16 C = A * B; // Does NOT like this.
    UInt16 C = (UInt16)(A * B); // likes this.
    //C = A * 2; // Does NOT like this.
    C = (UInt16)(A * 2); // likes this.
    
    • Wayne

    Was this answer helpful?

    0 comments No comments

  4. Timon Yang-MSFT 9,611 Reputation points
    2021-02-02T02:38:53.523+00:00

    Let me talk about the conclusion first, this is by design.

    The result of A*B is of type Int32, and it is illegal to assign it to UInt16.

    This is called Numeric Promotion and is a rule to prevent data loss. You can find many explanations about this on the Internet, such as:

    Arithmetic operators (C# reference)

    Explain integer comparison with promotion

    For example, if A=65534 and B=10, then their addition or multiplication is beyond the scope of UInt16.

    If you are sure that the result will not exceed the range, you can force the conversion.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.