реклама на сайте
подробности

 
 
> gcc 4.2.2 и умножение int 16x16
_Pasha
сообщение May 29 2008, 03:47
Сообщение #1


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Доброго времени!
Подскажите, как заставить компилятор в Winavr генерить правильный код.
Нужно
Код
int16_t Xarg,Yarg,Zarg;
........................
Zarg= (Xarg*Yarg) >>16;


Приведение к 32-битам - это безумное количество кода.
Надо, чтоб генерился код примерно такой (имена регистров не важны):
Код
lds r16,Xarg
lds r17,Xarg+1
lds r18,Yarg
lds r19,Yarg+1
clr r6 //9
// дальше стандартное знаковое умножение
muls r17,19
movw r4,r0
mul 16,r18
movw r2,r0
mulsu r19,r16
sbc r5,r6
add r3,r0
adc r4,r1
adc r5,r6
mulsu r17,r18
sbc r5,r6
add r3,r0
adc r4,r1
adc r5,r6
// и выделение старшей части 32-битного результата
sts Zarg,r4
sts Zarg+1,r5
// итого 22+9 = 31 такт


Бился головой о стену - ниасилил компилер такой красоты. А очень надо. Если кто уже получал такое чистым Си, поделитесь, пожалуйста, опытом.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 24)
aesok
сообщение May 29 2008, 05:57
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(_Pasha @ May 29 2008, 07:47) *
Бился головой о стену - ниасилил компилер такой красоты. А очень надо. Если кто уже получал такое чистым Си, поделитесь, пожалуйста, опытом.


Нужно править компилятор.

Анатолий.

Сообщение отредактировал aesok - May 29 2008, 06:00
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 29 2008, 06:47
Сообщение #3


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(aesok @ May 29 2008, 08:57) *
Нужно править компилятор.

Анатолий.


А с умножением
Код
static int16_t TR1=-1039; TR0=0;
static uint8_t TR2=30;
.........<skipped>...........................
for(;;)
{
TR0 = (TR1*TR2)>>8;
..<skipped>...............
}


Получаем такую херь:

Код
103:      TR0 = (TR1*TR2)>>8;
+00000833:   91800200    LDS     R24,0x0200       Load direct from data space
+00000835:   91900201    LDS     R25,0x0201       Load direct from data space
+00000837:   019C        MOVW    R18,R24          Copy register pair
+00000838:   E065        LDI     R22,0x05         Load immediate
+00000839:   0F22        LSL     R18              Logical Shift Left
+0000083A:   1F33        ROL     R19              Rotate Left Through Carry
+0000083B:   956A        DEC     R22              Decrement
+0000083C:   F7E1        BRNE    PC-0x03          Branch if not equal
+0000083D:   0F88        LSL     R24              Logical Shift Left
+0000083E:   1F99        ROL     R25              Rotate Left Through Carry
+0000083F:   1B28        SUB     R18,R24          Subtract without carry
+00000840:   0B39        SBC     R19,R25          Subtract with carry
+00000841:   2F23        MOV     R18,R19          Copy register
+00000842:   0F33        LSL     R19              Logical Shift Left
+00000843:   0B33        SBC     R19,R19          Subtract with carry
+00000844:   9330031A    STS     0x031A,R19       Store direct to data space
+00000846:   93200319    STS     0x0319,R18       Store direct to data space


Оптимизация -O2 (!) (ошибочка:оптимизация была -Os) , mega640 (это к тому, что mulsu там есть smile.gif )
Компилер понял, что TR2 таки константа smile.gif, но это 41такт !

В то же время, при тех же условиях
Код
LDS     R24,0x0200//       Load direct from data space
LDS     R25,0x0201//       Load direct from data space
LDI      R18,0x1E// я не говорю о том, что здесь не западло и LDS оставить и не оптимизировать ненужное
// было 5 тактов
mul r24,r18
movw r2,r0
mulsu  r25,r18
ldi  r18,0
sbc r1,r18
add r0,r3
adc r1,r18
//14
STS     0x031A,R1       Store direct to data space
STS     0x0319,R0       Store direct to data space
//18

составит 18 тактов.
В общем, проблема серьезная, поскольку такие операции (умножить и поделить на 256) очень часто употребимы, думаю, не только мной.

УПС, ошибочка в последнем коде. Исправленному верить.
Go to the top of the page
 
+Quote Post
aesok
сообщение May 29 2008, 07:03
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(_Pasha @ May 29 2008, 10:47) *
Оптимизация -O2 (!), mega640 (это к тому, что mulsu там есть smile.gif )


А почему Вы не используете оптимизацию -Os?

Анатолий.

Сообщение отредактировал aesok - May 29 2008, 07:03
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 29 2008, 07:17
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Я всегда использую -Os, но здесь некоторый кусок кода не пролазил по времени, пришлось его -O2

Еще раз обращаю внимание на мой предыдущий пост - исправил ошибку в последнем коде.

P.P.S
Прошу прощение. Ввел в заблуждение всех.

Подвожу итог, обойдя путаницу.

В показанном примере оптимизация была -Os, выполнялось за 41 такт
Включил обратно -O2 - выполнилось за 25 тактов, за счет замены цикла инлайнами. Это как-бы терпимо, но сама генерация кода все-же вызывает вопросы.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 29 2008, 08:42
Сообщение #6


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(_Pasha @ May 29 2008, 07:47) *
Бился головой о стену - ниасилил компилер такой красоты. А очень надо. Если кто уже получал такое чистым Си, поделитесь, пожалуйста, опытом.
А почему нужно именно на чистом С ?
напишите свою функцию на чистом asm и будет Вам полное счастье. smile.gif

Мне как-то понададобилось умножение 16бит x 16 бит на ATtiny, так там на С
без mul получается вобще ужас с приведением к 32бит, ну а функция на асм
DWORD mulu16by16(WORD, WORD); получилась более менее по времени.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 29 2008, 09:05
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(singlskv @ May 29 2008, 11:42) *
А почему нужно именно на чистом С ?
напишите свою функцию на чистом asm и будет Вам полное счастье. smile.gif


Дык я уже так и сделал, в смысле, прерывание написал.

Получилось примерно следующее:
3 знаковых умножения 16х16 вида X[i] = Beta*Y[i]
15 умножений int16_t * uint8_t
18 операций 16-бит сложения
30 операций 16-бит сравнения (ограничение)

помещается в 553 такта с учетом того, что используются 15 регистров, бесстыдно сохраняемых в стеке + SREG ( это 31+31 = 62 такта на контекст)

Сишный вариант давал 1500 - с чем-то тактов. Даже с -О2.
Устраивает тактов до 800
Беда, однако...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 1 2008, 09:27
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Какая же все-таки грабляндия эта арифметика!
Привожу правильный и проверенный на всем множестве код для операции
(int16_t) = (int16_t)*(uint8_t)/256
в виде AVR gnu-as
Код
#define arg1L  r16
#define arg1H r17
#define scalar r18
#define NULL_REG r6
scale16x8:
  clr       NULL_REG
//...........................
  mul     arg1L,scalar
  mov    r2,r1
  mulsu  arg1H,scalar
  adc     r0,r2
  adc     r1,NULL_REG

; result in r0:r1


Итого 7 тактов.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 1 2008, 14:04
Сообщение #9


фанат дивана
******

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



Цитата(_Pasha @ Jun 1 2008, 15:27) *
Какая же все-таки грабляндия эта арифметика!
Привожу правильный и проверенный на всем множестве код для операции


Переписал для inline асссемблера:

Код
static inline uint16_t scale16x8(uint16_t a, uint8_t b)
{
    uint16_t result;
    uint8_t tmp;
/*
%A0 - low byte of result,
%B0 - hi byte of result,
%1  - tmp
%A2 - low byte of the first operand,
%B2 - hi byte of the first operand,
%3 - second operand
*/

    asm (
        "clr    %1 \n\t"
        "mul    %A2,%3 \n\t"
        "mov    r2,r1 \n\t"
        "mulsu    %B2,%3 \n\t"
        "adc    r0,r2 \n\t"
        "adc    r1,%1 \n\t"
        "movw    %A0, r0 \n\t"
        "clr    __zero_reg__ \n\t"
        : "=&r" (result), "=&r" (tmp)
        : "a" (a), "a" (b)
    );

    return result;
}


Добавил зачистку __zero_reg__, так положено.

Только вот что-то не сходится:

Код
int scale_test(void)
{
    uint16_t a = 0;
    uint8_t b = 0;
    while (TRUE)
    {
        if (scale16x8(a, b) != ((unsigned long)a*b/256))
        {
            nokia_puts_p("a = ");
            nokia_put_word(a);
            nokia_puts_p(",  b = ");
            nokia_put_word(b);
            return FALSE;
        }
        if (a == 0xFFFF && b == 0xFF) return TRUE;
        if (!++b) a++;
    }
}


Ошибка при a=0x8000 и b=1.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 1 2008, 14:22
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(AHTOXA @ Jun 1 2008, 18:04) *
Ошибка при a=0x8000 и b=1.
У Вас
static inline uint16_t scale16x8(uint16_t a , uint8_t b )
а было:
(int16_t) = (int16_t )*(uint8_t)/256
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 1 2008, 15:47
Сообщение #11


фанат дивана
******

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



Цитата(singlskv @ Jun 1 2008, 20:22) *
У Вас
static inline uint16_t scale16x8(uint16_t a , uint8_t b )
а было:
(int16_t) = (int16_t )*(uint8_t)/256


Точно! Виноват :-)
Исправил:

Код
static inline int16_t scale16x8(int16_t a, uint8_t b)
{
    int16_t result;
    uint8_t tmp;
/*
%A0 - low byte of result,
%B0 - hi byte of result,
%1  - tmp
%A2 - low byte of the first operand,
%B2 - hi byte of the first operand,
%3 - second operand
*/

    asm (
        "clr    %1 \n\t"
        "mul    %A2,%3 \n\t"
        "mov    r2,r1 \n\t"
        "mulsu    %B2,%3 \n\t"
        "adc    r0,r2 \n\t"
        "adc    r1,%1 \n\t"
        "movw    %A0, r0 \n\t"
        "clr    __zero_reg__ \n\t"
        : "=&r" (result), "=&r" (tmp)
        : "a" (a), "a" (b)
    );

    return result;
}

int scale_test(void)
{
    int16_t i = -32768;
    uint8_t b = 0;
    int16_t i1, i2;
    while (TRUE)
    {
        i1 = scale16x8(i, b);
        i2 = (signed long)i*b/256;
        if (i1 != i2)
        {
            nokia_puts_p("   a = ");
            nokia_put_int(i);
            nokia_puts_p(",   b = ");
            nokia_put_word(b);
            return FALSE;
        }
        b++;
        if (!b)
        {
            i++;
        }
        if ((i == 32767) && (b == 0xFF)) break;
    }
    return TRUE;
}


Но всё равно, выдаёт ошибку при i=-32768 и b=1... Опять я где-то что-то проглядел? smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 1 2008, 20:06
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Jun 1 2008, 18:47) *
Но всё равно, выдаёт ошибку при i=-32768 и b=1... Опять я где-то что-то проглядел? smile.gif


a14.gif
Про b=1 - это хорошо... Легкая неадекватность поведения замечена.
А вот про -32768 то есть 0x8000, предлагаю извлечь дополнительный код из него lol.gif
bb-offtopic.gif
Меняю стакан соломы на обратный билет с Марса...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 2 2008, 03:57
Сообщение #13


фанат дивана
******

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



Цитата(_Pasha @ Jun 2 2008, 02:06) *
Про b=1 - это хорошо... Легкая неадекватность поведения замечена.


То есть, функция таки работает не "во всём множестве"? :-)

Цитата
А вот про -32768 то есть 0x8000, предлагаю извлечь дополнительный код из него lol.gif


А зачем? :-) Или -32768 не бывает? smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 2 2008, 05:19
Сообщение #14


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(AHTOXA @ Jun 2 2008, 06:57) *
То есть, функция таки работает не "во всём множестве"? :-)
А зачем? :-) Или -32768 не бывает? smile.gif


Таки да. Каюсь, не проверил оные значения ввиду нехватки времени и отсутсвия их практической ценности в целевом проекте.

На самом деле с единицей оказалось все правильно. Возьмем -32767=0x8001 smile.gif
Для того, чтобы доказать, что 0x8001 >>8 != 0x80, приведем его в беззнаковый вид.
Дополнительный код даст 0x7fff, операция сдвига на 8 бит даст 0x7f. Извлекаем обратно дополнительный код из результата, получаем 0x81. При расширении знака в старший байт имеем 0xFF81, что и наблюдаеццо в симуляторе. Как ни странно. Хотя здравый смысл подсказывает, что signed 0x8001 >>8 = 0xFF80.

-32768 - счастливое исключение smile.gif Поскольку +32768 в двух байтах не бывает, попытка привести к беззнаковому умножению 16*8 тоже ни к чему не приведет.
Но на этом беда не заканчивается. Однобайтовый int8_t тоже ведь имеет встроенный баг 0x80. Видимо, придется обрабатывать как исключение. Но проще съехать с базара и сказать Таки да! Не на всем множестве! biggrin.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 2 2008, 06:10
Сообщение #15


фанат дивана
******

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



Цитата(_Pasha @ Jun 2 2008, 11:19) *
Но проще съехать с базара и сказать Таки да! Не на всем множестве! biggrin.gif


Я отнюдь не наезжаю, боже упаси! Просто хочу знать границы применимости smile.gif Что выходит на данный момент?
Нельзя применять при b=1 и при a=-32768?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 2 2008, 06:30
Сообщение #16


;
******

Группа: Участник
Сообщений: 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]
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 2 2008, 07:54
Сообщение #17


фанат дивана
******

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



Цитата(_Pasha @ Jun 2 2008, 12:30) *
Прочтите внимательно предыдущий пост.
Я показал, что при b=1 можно применять. Но результат несколько неожиданный.


Вот неожиданность меня и сбила с толку. Перечитал, понялsmile.gif

Цитата
P.S. Если выдает ошибку при b=1, то это бага компилятора, которая заключается в безусловной подмене операции /256 операцией взятия старшего байта с последующим знаковым расширением.


А это я вечерком проверю.

Можно вопрос немного в сторону? Для чего применяется подобное масштабирование? Ну, пару примеров? А то вижу что штука хорошая, а куда применить - не могу придуматьsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 2 2008, 08:10
Сообщение #18


;
******

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 3 2008, 17:20
Сообщение #19


фанат дивана
******

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



Я добрался до АВРки, продолжаюsmile.gif

Урезал осетра, запустил цикл с -32767...
Упс, при a = -32766 и b = 128 пишет:
ошибка, i1 = -16382, i2 = 49153.
Я в шокеsmile.gif Проверяю на куркуляторе - должно получиться -16383. Окей, ещё одна дырочка в области применения. Но это ерундаsmile.gif
Интереснее другое: как выражение
Код
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)

Это опять я глючу, или таки бага компилятора?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 3 2008, 18:49
Сообщение #20


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Это глюки не компилера, а отладчика, в котором Вы все это смотрели.
Судите сами: 49153 = C001, опять же, в дополн коде получим 3FFF, т.е 16383

Спасибо, что не успокоились, а то я так и прошляпил бы эти грабли (что врет на единицу).
В принципе, пофиксил. Надо порядок умножений попробовать поменять. Бит SREG.C выскакивает в mulsu когда signed <0. Сейчас тоже позанимаюсь.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 3 2008, 18:57
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 4 2008, 03:12
Сообщение #22


фанат дивана
******

Группа: Свой
Сообщений: 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.


Не могу. Его там нет smile.gif Мне что, тестовый пример пихать в каждое своё сообщение? Я его уже два раза приводил.

PS. Я почти на 100% уверен, что глюк мой, а не компилятора. Только не могу понять где...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 4 2008, 05:55
Сообщение #23


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_Pasha @ Jun 3 2008, 21:49) *
Бит SREG.C выскакивает в mulsu когда signed <0. Сейчас тоже позанимаюсь.


Короче, не выходит каменный цветок. smile.gif
Куча исключений.
1. При b=0x80 врет на 1
2. Надо повнимательней к переполнениям, т.к. например -1 * 0xff /0x100 даже на "куркуляторе" дает чушь, напоминающую о необходимости обрабатывать исключения.


Цитата(AHTOXA @ Jun 4 2008, 06:12) *
PS. Я почти на 100% уверен, что глюк мой, а не компилятора. Только не могу понять где...


Наверное, куда-то девается (игнорируется) знаковое расширение в старших байтах.
GCC4.2.2 на аврстудии показывает все правильно.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 4 2008, 07:53
Сообщение #24


фанат дивана
******

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



Цитата(_Pasha @ Jun 4 2008, 11:55) *
Короче, не выходит каменный цветок. smile.gif
Куча исключений.
1. При b=0x80 врет на 1


Ну ничего, всё равно пригодится. Для некритичных к точности но критичных ко времени вычислений (как в примере с ШИМом) smile.gif


Цитата
Наверное, куда-то девается (игнорируется) знаковое расширение в старших байтах.
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... Вот и пойми тут, в чём разница...

Ладно, вечерком ещё поковыряю...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 5 2008, 17:19
Сообщение #25


фанат дивана
******

Группа: Свой
Сообщений: 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);
Буковку прогляделsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 03:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.02826 секунд с 7
ELECTRONIX ©2004-2016