|
|
  |
как перемножать при помощи встроенного умножителя? |
|
|
|
Feb 22 2008, 10:34
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
В том коде, который приведён, ничего работать не будет. tmp не объявлена. Кстати, сдвиг на 12 эквивалентен делению на 4096, а не на 4095... попробуйте так Код unsigned int get_code ( unsigned int num_value, unsigned int k ) { unsigned long tmp;
tmp = num_value * k; asm ("nop"); asm ("nop"); asm ("nop"); tmp = tmp >> 12; return( unsigned int tmp ); }
// или короче unsigned int get_code ( unsigned int num_value, unsigned int k ) { return( (unsigned int)( num_value * k / (unsigned long)4095 )); }
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Feb 22 2008, 14:17
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Вы опять наступаете на те же грабли. Без явного объявления (по-умолчанию) автоматическая переменная имеет тип int, для MSP430 int = 16 бит. Либо объявите переменные как unsigned long, либо делайте в каждом выражении явное приведение типа. Например, Код t =(unsigned int)((unsigned long)((unsigned long)(result[3])<<16UL)+(unsigned long)(result[0])+(unsigned long)((unsigned long)((unsigned long)(result[2])+(unsigned long)(result[1]))<<8UL)); Ну как, нравится?  Думаю, что нет. Так что определяйте типы переменных заранее и не вые надейтесь на "авось". Законы Мерфи-то работают!
|
|
|
|
|
Feb 22 2008, 17:09
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(cornflyer @ Feb 22 2008, 18:41)  я сделал так: unsigned int get_code ( unsigned int num_value, unsigned int k ) { unsigned long t = num_value * k ; asm ( " nop " ) ; asm ( " nop " ) ; asm ( " nop " ) ; asm ( " nop " ) ; return ( t >> 12 ) ; } А надо так: Код unsigned int get_code ( unsigned int num_value, unsigned int k ) { unsigned long t = num_value; t *= k; asm ( " nop " ); asm ( " nop " ); asm ( " nop " ); asm ( " nop " ); return ( t >> 12 ); } Тогда будет всё в порядке. Кстати, без "nop"-ов тоже будет работать :-)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 24 2008, 05:58
|

Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 8-04-06
Из: Новосибирск
Пользователь №: 15 939

|
Так вроде то же самое написано... Попробую догадаться, почему так происходит: В первом случае сначала происходит перемножение num_value и k и происходит переполнение, поэтому когда результат присваивается t, он ошибочный. Во втором случае переменной t присваивается значение num_value и потом только происходит умножение t на k и при этом переполнения не возникает. Так?
|
|
|
|
|
Feb 24 2008, 15:44
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(aag @ Feb 24 2008, 10:58)  В первом случае сначала происходит перемножение num_value и k и происходит переполнение, поэтому когда результат присваивается t, он ошибочный. Да. В первом случае сначала перемножаются два int-а, результат тоже int. Во втором случае - сначала присвоение long-у, потом умножение long-а на int, результат - long. Можно также написать: Код unsigned long t = (unsigned long)num_value * k;
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 26 2008, 06:51
|

Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729

|
Код unsigned int get_code ( unsigned int num_value, unsigned int k ) { unsigned long t = num_value; t *= k; return ( t >> 12 ); } Так работает !!!!!!!!!!!! Ура !!!!!!!!! P.S. Опять наступил на грабли приведения типов в С...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|