Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Приоритет и очередность вычислений


Автор: FiMa1 11.4.2007, 12:51
Согласно Керниган, Ритчи, рассчитываю на очередность (см. код ниже):
1. Выражение в скобках, где выполняется (а) ~0 (б) UINT32SIZE - n (в) сдвиг
2. Сдвиг результата от действий в скобках на p.

Помогите, плз, разобраться где я наврал...

Код

typedef unsigned uint32;

#define SIZEOFBYTE 8
#define UINT32SIZE sizeof(uint32)*SIZEOFBYTE

uint32 turnoffbites(uint32 x, int p, int n);

int main(void)
{
    uint32 i = turnoffbites(2, 0, 1);

    return 0;
}

/* turns off n bits of the x, from p position */
uint32 turnoffbites(uint32 x, int p, int n)
{
    /* create the mask РАБОЧИЙ ВАРИАНТ */ 
    uint32 m = ~0;
    m = (m >> UINT32SIZE - n) << p;

    /* create the mask НЕРАБОЧИЙ ВАРИАНТ  
    uint32 m = (~0 >> UINT32SIZE - n) << p;*/

    /* cut bits and return the result */
    return x & (~m);
}


Пробовал также вариант uint32 m = (~0 >> 32 - n) << p; чтобы не учитывать операторы макроса для UINT32SIZE...

Автор: ama_kid 11.4.2007, 14:34
что-то я не совсем понял, что тебе надо... Чтобы нерабочий вариант работал так же как рабочий?
ну сделай приведение типа 0 явно:
uint32 m = (~(uint32)0 >> (UINT32SIZE - n)) << p;
Или я не о том?

Автор: FiMa1 11.4.2007, 14:39
Цитата(ama_kid @ 11.4.2007,  14:34)
что-то я не совсем понял, что тебе надо... Чтобы нерабочий вариант работал так же как рабочий?
ну сделай приведение типа 0 явно:
uint32 m = (~(uint32)0 >> (UINT32SIZE - n)) << p;
Или я не о том?

Все так, спасибо. А без явного приведения никак? Почему у Кернигана с Ритчи прокатывает вариант:

Код

/* getbits: получает n бит, начиная с p-й позиции */
unsigned getbits(unsigned x, int p, int n)
{
    return (x >> (p+1-n)) & ~(~0 << n);
}

Автор: SerpentVV 12.4.2007, 09:24
Скорее всего потому, что они писали про язык С, а ты компилируешь в С++.
А С и С++ - две большие разницы...

Автор: FiMa1 12.4.2007, 15:47
Цитата(SerpentVV @ 12.4.2007,  09:24)
Скорее всего потому, что они писали про язык С, а ты компилируешь в С++.
А С и С++ - две большие разницы...

Ответ - нет.. 
Все варианты (и Ритчи и мои) компилировались в MS Visual Studio .NET 2003, проекты заводились как С++. Вариант Керниганf&Ритчи работает согласно задумке:
Цитата

Для иллюстрации некоторых побитовых операций рассмотрим функцию getbits(x, p, n), которая формирует поле в n битов, вырезанных из x, начиная с позиции p, прижимая его к правому краю. Предполагается, что 0-й бит - крайний правый бит, а n и p- осмысленные положительные числа. Например, getbits(x,4,3) вернет в качестве результата 4, 3 и 2-й биты значения x, прижимая их к правому краю:
Код

/* getbits: получает n бит, начиная с p-й позиции */
unsigned getbits(unsigned x, int p, int n)
{
    return (x >> (p+1-n)) & ~(~0 << n);
}


В моём же варианте непорядок...

Автор: vinter 12.4.2007, 16:15
Цитата(FiMa1 @  12.4.2007,  15:47 Найти цитируемый пост)
Ответ - нет.. 


Цитата(SerpentVV @  12.4.2007,  09:24 Найти цитируемый пост)
они писали про язык С


Цитата(FiMa1 @  12.4.2007,  15:47 Найти цитируемый пост)
 проекты заводились как С++

ответ понятен?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)