Невозможно неявно преобразовать тип «int» в «ushort»: уже явно приведено

Я пытаюсь явно преобразовать int в ushort, но получаю тип неявного преобразования Cannot int в ushort.

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

Я использую .Net Micro framework, поэтому BitConverter недоступен. Почему я использую ushort, в первую очередь, связано с тем, как мои данные передаются через SPI. Я могу понять, что эта конкретная ошибка поднималась ранее на этом сайте, но я не понимаю, почему, когда я явно заявляю, что мне все равно, пропадут ли какие-либо данные, просто нарежьте 32-битный бит на 16-битный, и я буду счастлив.

            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

Я бы предпочел не менять внутренний канал на канал ushort. Как я могу решить ошибку?


person Michael    schedule 14.09.2013    source источник


Ответы (2)


(ushort) channel равно ushort, но 12 * (ushort)(channel) будет int, вместо этого сделайте следующее:

ushort quotient = (ushort) ((12 * channel) / 16);
person King King    schedule 14.09.2013
comment
Большое спасибо, это решило проблему. Я предполагаю, что это означает, что потому, что 12 - это int, который вызывал проблему, или это были дополнительные скобки? В любом случае проблема была решена, и я очень счастлив, так что спасибо. - person Michael; 14.09.2013
comment
@Michael Майкл, да, это потому, что 12 равно int, поэтому результат будет автоматически приведен к типу больше и больше. - person King King; 14.09.2013
comment
@ Майкл - обратите внимание, что утверждение Кинга не совсем верно - причина, по которой вы получаете результат int, заключается в отсутствии операции ushort*ushort - есть только int*int и long*long, поэтому даже ((ushort)12)*((ushort)channel) будет int. То же верно и для всех остальных (+,-, /...). - person Alexei Levenkov; 14.09.2013
comment
@AlexeiLevenkov мне стыдно это знать, я не думал, что это проблема, однако то же правило (я упомянул) применимо к таким случаям, как int и long (int * long -> long). На самом деле я усвоил это правило, изучая С++, а не С#, здесь может быть некоторая разница между ними. - person King King; 15.09.2013

Умножение любых int и меньших типов дает int. Итак, в вашем случае 12 * ushort производит int.

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

Обратите внимание, что приведенный выше код не совсем эквивалентен исходному образцу - преобразование channel в ushort может значительно изменить результат, если значение channel выходит за пределы диапазона ushort (0.. 0xFFFF). В случае, если это важно, вам все еще нужен внутренний слепок. Пример ниже будет производить 0 для channel=0x10000 (что и делает исходный образец, о котором идет речь), в отличие от более обычного кода выше (который дает результат 49152):

ushort quotient = (ushort)((12 * (ushort)channel) / 16); 
person Alexei Levenkov    schedule 14.09.2013
comment
Как (ushort)channel помогает во втором утверждении? Я бы подумал, что преобразование типа не произойдет до тех пор, пока не будут выполнены математические операции из-за скобок. - person jmstoker; 14.09.2013
comment
@jmstoker попробуйте с int channel = 0x10000 - первый будет умножен на int и даст 49152, а второй преобразует 0x10000 в ushort, сначала дав 0 (и результирующее выражение будет 0). Обратите внимание, что это может быть не то, чего хочет ОП, но актерский состав в исходном посте отличает выражение от первого, которое я показываю. - person Alexei Levenkov; 14.09.2013
comment
Я так и предполагал. Ваш ответ вводит в заблуждение. Было бы более ясно, если бы вы добавили свой комментарий выше к своему ответу и подчеркнули, что приведение channel во 2-м утверждении - не лучший способ? - person jmstoker; 14.09.2013
comment
@jmstoker - я отредактировал ответ ... Я не уверен, что вы имеете в виду, что кастинг канала во 2-м утверждении не лучший вариант - он дает другой результат, который может быть или не быть чего хочет ОП - но я не вижу причин судить, лучше ли это. Также обратите внимание, что то же самое можно сказать и о возможности разделить как 12, так и 16 на 4, снова получая одинаковые результаты для небольших чисел и совершенно разные для больших... С конечными числовыми типами просто больно иметь дело - да здравствует BigInteger :) - person Alexei Levenkov; 14.09.2013
comment
Вы правы, я не должен судить об первоначальных намерениях, и спасибо за обновление вашего поста. Я родом из встроенного мира, и есть несколько ситуаций, когда вы хотите, чтобы приведение привело к нулю. - person jmstoker; 14.09.2013
comment
Решение от King решило проблему, но это помогает объяснить, почему это работает именно так, спасибо за объяснение умножения int на меньший тип. Я буду избегать этого в будущем. - person Michael; 14.09.2013