|
gcc 4.2.2 и умножение int 16x16 |
|
|
|
Jun 2 2008, 06:30
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(AHTOXA @ Jun 2 2008, 09:10)  Нельзя применять при b=1 и при a=-32768? Прочтите внимательно предыдущий пост. Я показал, что при b=1 можно применять. Но результат несколько неожиданный. При a=-32768 нельзя. P.S. Если выдает ошибку при b=1, то это бага компилятора, которая заключается в безусловной подмене операции /256 операцией взятия старшего байта с последующим знаковым расширением. Согласитесь, что операции сразу в дополнительном коде и беззнаковые с последующим получением отрицательного числа должны давать одинаковый результат на множестве [-32767..+32767]
|
|
|
|
|
Jun 2 2008, 07:54
|

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

|
Цитата(_Pasha @ Jun 2 2008, 12:30)  Прочтите внимательно предыдущий пост. Я показал, что при b=1 можно применять. Но результат несколько неожиданный. Вот неожиданность меня и сбила с толку. Перечитал, понял  Цитата P.S. Если выдает ошибку при b=1, то это бага компилятора, которая заключается в безусловной подмене операции /256 операцией взятия старшего байта с последующим знаковым расширением. А это я вечерком проверю. Можно вопрос немного в сторону? Для чего применяется подобное масштабирование? Ну, пару примеров? А то вижу что штука хорошая, а куда применить - не могу придумать
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 2 2008, 08:10
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(AHTOXA @ Jun 2 2008, 10:54)  Для чего применяется подобное масштабирование? Например, выдаем биполярный сигнал через 10-бит PWM. Базовая линия сигнала (наш ноль) будет на отметке PWM_OFFSET=512. А на АЦП висит резистор громкости, 8-бит достаточно. Код #define PWM_OFFSET 512 uint8_t wrk; int16_t generator_out;
//................................ // having outgoing milestone :)
// read ADC wrk=ADCH; // output OCR1=scale16x8(generator_out,wrk)+ PWM_OFFSET; Проверил на своем gcc4.2.2 выражение c=(int32_t) a*b/256; компилится правильно при b=1, a=-32767, т.е. и в виде константного выражения и в виде реальных вычислений результат = 0xFFFFFF81
|
|
|
|
|
Jun 3 2008, 17:20
|

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

|
Я добрался до АВРки, продолжаю  Урезал осетра, запустил цикл с -32767... Упс, при a = -32766 и b = 128 пишет: ошибка, i1 = -16382, i2 = 49153. Я в шоке  Проверяю на куркуляторе - должно получиться -16383. Окей, ещё одна дырочка в области применения. Но это ерунда  Интереснее другое: как выражение Код i2 = (signed long)i*b/256; при i = -32766 и b = 128 дало 49153?! проверял с avr-gcc.exe (GCC) 4.3.0 20080111 (experimental) avr-gcc.exe (GCC) 4.4.0 20080530 (experimental) от klen-a и avr-gcc.exe (GCC) 4.1.2 (WinAVR 20070525) Это опять я глючу, или таки бага компилятора?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 3 2008, 18:57
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(AHTOXA @ Jun 3 2008, 21:20)  Интереснее другое: как выражение Код i2 = (signed long)i*b/256; при i = -32766 и b = 128 дало 49153?! Ничего интересного: 49153 это 0xC001 или -16383. Убери unsigned из объявления переменой i2. Анатолий. PS: В следующий раз посылайте тестовые примеры полностью, с объявлениями перемеренных. Цитата(_Pasha @ Jun 3 2008, 22:49)  Это глюки не компилера, а отладчика, в котором Вы все это смотрели. Это глюки не отладчика а програмера. Надо правильно выбирать типы переменных.
Сообщение отредактировал aesok - Jun 3 2008, 18:58
|
|
|
|
|
Jun 4 2008, 03:12
|

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

|
Цитата(_Pasha @ Jun 4 2008, 00:49)  Это глюки не компилера, а отладчика, в котором Вы все это смотрели. Судите сами: 49153 = C001, опять же, в дополн коде получим 3FFF, т.е 16383 Я на железке смотрю, так сказать, живьём. Цитата(aesok @ Jun 4 2008, 00:57)  Убери unsigned из объявления переменой i2. Не могу. Его там нет  Мне что, тестовый пример пихать в каждое своё сообщение? Я его уже два раза приводил. PS. Я почти на 100% уверен, что глюк мой, а не компилятора. Только не могу понять где...
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 4 2008, 05:55
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(_Pasha @ Jun 3 2008, 21:49)  Бит SREG.C выскакивает в mulsu когда signed <0. Сейчас тоже позанимаюсь. Короче, не выходит каменный цветок. Куча исключений. 1. При b=0x80 врет на 1 2. Надо повнимательней к переполнениям, т.к. например -1 * 0xff /0x100 даже на "куркуляторе" дает чушь, напоминающую о необходимости обрабатывать исключения. Цитата(AHTOXA @ Jun 4 2008, 06:12)  PS. Я почти на 100% уверен, что глюк мой, а не компилятора. Только не могу понять где... Наверное, куда-то девается (игнорируется) знаковое расширение в старших байтах. GCC4.2.2 на аврстудии показывает все правильно.
|
|
|
|
|
Jun 4 2008, 07:53
|

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

|
Цитата(_Pasha @ Jun 4 2008, 11:55)  Короче, не выходит каменный цветок. Куча исключений. 1. При b=0x80 врет на 1 Ну ничего, всё равно пригодится. Для некритичных к точности но критичных ко времени вычислений (как в примере с ШИМом)  Цитата Наверное, куда-то девается (игнорируется) знаковое расширение в старших байтах. GCC4.2.2 на аврстудии показывает все правильно. Я уже всю голову сломал. Есть ф-я вывода int на дисплей: nokia_put_int(int i); есть два инта: Код int16_t i1; int16_t i2; i1 = scale16x8(i, b); i2 = (signed long)i*b/256; ... nokia_put_int(i1); nokia_put_int(i2); Первый int (i1, -16382 или C002) отображается нормально, в виде отрицательного значения. А вот i2 (-16383 или C001) - почему-то трактуется как unsigned... Вот и пойми тут, в чём разница... Ладно, вечерком ещё поковыряю...
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 5 2008, 17:19
|

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

|
Я лопух:-) Цитата(AHTOXA @ Jun 4 2008, 13:53)  есть два инта: Код int16_t i1; int16_t i2; i1 = scale16x8(i, b); i2 = (signed long)i*b/256; ... nokia_put_int(i1); nokia_put_int(i2); последняя строчка была: nokia_put_ uint(i2); Буковку проглядел
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|