Cannot implicity convert type 'int' to 'ushort' : already explicity cast
Asked Answered
F

2

6

I am trying to explicity cast an int into a ushort but am getting the Cannot implicity convert type 'int' to 'ushort'

ushort quotient = ((12 * (ushort)(channel)) / 16);

I am using .Net Micro framework so BitConverter is unavailable. Why I am using ushort in the first place has to do with how my data is being sent over SPI. I can understand this particular error has been brought up before on this site but I cannot see why when I am explicity declaring that I dont care if any data goes missing, just chop the 32 bit into a 16 bit and I will be happy.

            public void SetGreyscale(int channel, int percent)
    {
        // Calculate value in range of 0 through 4095 representing pwm greyscale data: refer to datasheet, 2^12 - 1
        ushort value = (ushort)System.Math.Ceiling((double)percent * 40.95);

        // determine the index position within GsData where our data starts
        ushort quotient = ((12 * (ushort)(channel)) / 16); // There is 12 peices of 16 bits

I would prefer not to change int channel, to ushort channel. How can I solve the error?

Frail answered 14/9, 2013 at 5:32 Comment(0)
R
12

(ushort) channel is ushort but 12 * (ushort)(channel) would be int, do this instead:

ushort quotient = (ushort) ((12 * channel) / 16);
Resurrection answered 14/9, 2013 at 5:36 Comment(4)
Thank you very much, this has solve the problem. I guess this means that because 12 is an int that was causing the problem, or was it also the extra brackets? Either case the problem has been solved and Im very happy so thank you.Frail
@Frail yes, that's because the 12 is int, so the result will be automatically casted to the higher and bigger type.Resurrection
@Frail - note that King's statement is not exactly true - the reason you are getting int result is lack of ushort*ushort operation - there is only int*int and long*long, so even ((ushort)12)*((ushort)channel) will be int. Same true for all other (+,-, /...).Muffin
@AlexeiLevenkov it's a shame for me to know that, I didn't think that's the problem, however the same rule (I mentioned) is applicable for the case such as int and long (int * long -> long). In fact I learned this rule when learning c++, not c#, there may be some difference here between the two.Resurrection
M
4

Multiplication of any int and smaller types produces int. So in your case 12 * ushort produces int.

ushort quotient = (ushort)(12 * channel / 16);

Note that above code is not exactly equivalent to original sample - the cast of channel to ushort may significantly change result if value of channel is outside of ushort range (0.. 0xFFFF). In case if it is important you still need inner cast. Sample below will produce 0 for channel=0x10000 (which is what original sample in question does) unlike more regular looking code above (which gives 49152 result):

ushort quotient = (ushort)((12 * (ushort)channel) / 16); 
Muffin answered 14/9, 2013 at 5:38 Comment(6)
How does (ushort)channel help on the 2nd statement? I'd think the type conversion wouldn't happen until after the math operations due to the parenthesis.Yean
@Yean try with int channel = 0x10000 - first one will multiple as int and produce 49152, but second will cast 0x10000 to ushort first producing 0 (and resulting expression is 0). Note that it may not be what OP wants, but the cast in original post makes expression different from first one I show.Muffin
That's what I figured would happen. Your answer is misleading. It would be more clear if you added your comment above to your answer and emphasized that casting channel in the 2nd statement is not the best thing to do?Yean
@Yean - I've edited answer... I'm not sure what you mean "casting channel in the 2nd statement is not the best thing to do" - it produces different result which may or may not be what OP wants - but I see no reason to judge if it is better. Also note that similar can be said about possibility to divide both 12 and 16 by 4 again producing same results for small numbers and drastically different for large ones... Finite numeric types are just pain to deal with - long live BigInteger :)Muffin
You're right, I shouldn't judge the original intent, and thank you for updating your post. I come from the embedded world and there are few situations when you want a cast to result in zero.Yean
The solution from King solved the problem but this helps explain why it worked that way, thank you for explaining about multiplication of an int with a smaller type. I will avoid that in the future.Frail

© 2022 - 2024 — McMap. All rights reserved.