вы, как и многие до вас, не учитываете правило неявного преобразования типов операндов в выражениях. а правило таково:yur4ik писал(а):Так вот с ее помощью задаю число, а потом пишу его в переменную key (unsigned int) . Переменная полностью совпадает с тем что ввел с клавы. Далее это число нужно умножить на регистр IRC1 и разделить на 100, по началу казалось фигней, но когда IRC1 умножаю на любое число походу происходит переполнение и в результате вижу совсем другой конечный результат. Переменная в которую пишу (f) имеет уже тип unsigned long int, но это так и не помогло![]()
вот так вот делаю: f=(unsigned int)(ICR1*key/100);
Компилятор ругается мол переполнение: overflow is possible in 16 bit multiplication, casting to 'long' may be required
В чем я прокололся?
1. при вычислении выражения с двумя операндами значения обоих операндов приводятся к наибольшему (по размеру) типу этих операндов.
2. если оба операнда имеют тип char - оба преобразуются к int.
3. результат вычисления выражения имеет тот же тип, что и операнды.
4. после того, как выражение вычислено к результату применяется правило приведения типа так же, как было сказано. если больше вычислений в операторе нет - тип результата приводится к типу переменной, принимающей значение.
итак, разберем ваш пример.
переменная а имеет тип long (знак пока роли не играет). поэтому то, что результату выражения (ICR1 * key / 100) вы принудительно назначаете тип int - ничего не меняет, после того, как вы измените тип на int он будет снова ПРИНУДИТЕЛЬНО изменен на тип, соответствующей f, т.е. long. ваше действие БЕССМЫСЛЕННО.
теперь смотрим на выражение. оно вычисляется слева направо, т.е. сначала вычисляется ICR1 * key. key у вас char, поэтому без всяких рассуждений превращается в int. ICR1, как я понимаю, уже имеет тип int. результат выражения тоже будет int!!! но при умножении int * int результат может быть long - вот ваша проблема! и компилятор об этом вас честно предупреждает - скажите ему спасибо.
что же надо сделать, чтобы исправить ситуацию? надо заставить компилятор считать, что в умножении участвует хотя бы один операнд long - никак иначе! то есть вам надо не тип результата менять, а тип операнда!
то есть решением будет f= (long)ICR1 * key / 100; для страховки я бы еще и к константе 100 приписал суффикс L, чтобы она тоже считалась не int-ом, а long-ом. итак, окончательное решение: f= (long)ICR1 * key / 100L;
все теперь работает четко 