Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 32-битную переменную не получается заполнить двоичными единичками
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Krys
Здравствуйте. Работаю в SDK от Xilinx, это допиленный Eclipse, компилятор GCC.
У меня 32-битную переменную не получается заполнить двоичными единичками. Код такой:
Код
    unsigned int max_per = 0, min_per =
            (unsigned int)((unsigned long long)(1<<32)-(unsigned long long)1);

даёт ноль. Если сдвиг на 31, то единички есть, но 31 штука. Пробовал без преобразования типов - тоже ноль. Короче никак не могу его заставить.
Я понимаю, что можно просто записать 0xFFFFFFFF, но вопрос принципиальный, как заставить?
Xenia
Цитата(Krys @ Dec 25 2014, 06:15) *
Здравствуйте. Работаю в SDK от Xilinx, это допиленный Eclipse, компилятор GCC.
У меня 32-битную переменную не получается заполнить двоичными единичками. Код такой:
Код
    unsigned int max_per = 0, min_per =
            (unsigned int)((unsigned long long)(1<<32)-(unsigned long long)1);

даёт ноль. Если сдвиг на 31, то единички есть, но 31 штука. Пробовал без преобразования типов - тоже ноль. Короче никак не могу его заставить.
Я понимаю, что можно просто записать 0xFFFFFFFF, но вопрос принципиальный, как заставить?


Вот и запишите "по-простому" 0xFFFFFFFF sm.gif. А если хотите через ухо (unsigned long long), то ставьте его перед единичкой, которую сдвигаете влево, т.к. после сдвига это делать поздно - старший знак уже пропал.

Вы проявляете непонимание, свойственное начинающим С-программистам, которые частенько забывают, что приводить операнды к требуемому типу следует ДО операции. Поскольку, если значащие разряды окажутся из-за переполнения потерянными, то переопределением результата к другому типу назад их уже не вернуть.
Krys
Да, всё сработало, большое спасибо. Понимание-то я проявляю, тут скорее забывание про эту одну единственную единичку. Видите: я остальные операнды расширил, даже правую единичку, а эту забыл ))
Через ухо там несильно сложно, по-настоящему можно написать u64, и поймёт. А unsigned long long это я записал для каноничности, чтобы не было подозрений, что где-то u64 объявлен криво.
Xenia
Скажите, понимает ли ваш компилятор определения числовых констант с суффиксом:
1i64
или
1LL
А то Microsoft пишет в документе "C++ Integer Constants", что такие суффиксы в Visual Studio 2013 допустимы. Как в этом отношении ведет себя GCC?

А то бы очень классно выглядело выражение типа
(1i64 << 32)
без явного переопределения типа.
Krys
Спасибо и за эти подсказки.
1i64 - не понимает такой синтаксис.
1LL - работает правильно.
Сергей Борщ
Код
uint32_t min_per = ~(uint32_t)0;
Krys
тоже идея ))
den_po
А можно узнать подробней о версии gcc?

Вот результат выражения из первого поста http://ideone.com/tM7rbC
Ну и вот без лишнего приведения типов http://ideone.com/xqRct2
scifi
Цитата(den_po @ Dec 25 2014, 16:43) *
Вот результат выражения из первого поста http://ideone.com/tM7rbC
Ну и вот без лишнего приведения типов http://ideone.com/xqRct2

Кстати, да. Ведь вполне ожидаемо, что "(unsigned)-1" даст 0xFFFFFFFF.
Krys
Цитата(den_po @ Dec 25 2014, 19:43) *
А можно узнать подробней о версии gcc?

Код
c:\Xilinx\14.7\ISE_DS\EDK\gnu\microblaze\nt\bin>mb-gcc --version
mb-gcc (GCC) 4.6.4 20120924 (Xilinx 14.1 Build EDK_P.13 28 Sep 2013)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



Цитата(scifi @ Dec 25 2014, 20:53) *
Кстати, да. Ведь вполне ожидаемо, что "(unsigned)-1" даст 0xFFFFFFFF.
Хм... действительно, если разобраться, странно... Даже если у меня 32-битная единичка, я её сдвинул за пределы разрядной сетки, получил ноль. Потом единичку отнимаю от нуля. Получаю 0xFFFFFFFF. Косяк ещё и в том, что обычно компилятор давал ворнинг, что сдвигание привело к выходу за пределы разрядной сетки. А в этом случае не поругался.
Krys
есть мысль: может просто сдвиг циклический? Тогда всё сходится. Единичка сдвинутая на 32 разряда попадает на своё прежнее место, отнимаем единичку получаем ноль. Пока проверить не могу, позже.
scifi
Цитата(Krys @ Dec 26 2014, 10:02) *
есть мысль: может просто сдвиг циклический?

Если это так, то компилятор глючный донельзя :-)
Этого просто не может быть.
den_po
Такое бывает, к сожалению
Krys
Цитата(scifi @ Dec 26 2014, 13:29) *
Если это так, то компилятор глючный донельзя :-)
А у ксайлинкса есть какие-то продукты без такого свойства? )))
Там же написано NO WARRANTY )))

Да, догадка подтвердилась. Код
Код
    unsigned int max_per = 0, min_per = (1<<34) - 1;

даёт троечку )))
scifi
Цитата(Krys @ Dec 26 2014, 11:25) *
Да, догадка подтвердилась. Код
Код
    unsigned int max_per = 0, min_per = (1<<34) - 1;

даёт троечку )))

Фигасе. Это точно gcc? Запускается на ПК? А исходники у него есть?
Krys
Ну вот посмотрите в сообщении #10 информацию о версии. Работает на железе. Встраиваемый софтовый проц на ПЛИС. Исходников наверное нет... Т.к. он допилен компанией Xilinx под свои продукты.
scifi
Цитата(Krys @ Dec 26 2014, 11:48) *
Работает на железе. Встраиваемый софтовый проц на ПЛИС.

А, ну если на железе, тогда другое дело. В конце концов, даже в софтовом проце можно инструкции сдвига поменять или просто перепутать, а в исходниках компилятора напортачить ещё проще :-)
Сергей Борщ
Цитата(scifi @ Dec 26 2014, 09:29) *
Если это так, то компилятор глючный донельзя :-)
Как раз нет. Все в пределах стандарта:
Цитата
3 The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand. If the value of the right operand is negative or is
greater than or equal to the width of the promoted left operand, the behavior is undefined.


"Незнание закона не освобождает от ответственности".
Krys
Цитата(Сергей Борщ @ Dec 26 2014, 16:26) *
the behavior is undefined.
Стандарт на неопределённость поведения )))
scifi
Цитата(Сергей Борщ @ Dec 26 2014, 13:26) *
Как раз нет. Все в пределах стандарта:

"Незнание закона не освобождает от ответственности".

Тады ой.
WitFed
А я в последнее время для FFFFFFFF пишу = 0-1, это короче, и никто варнингов почему-то не выдаёт.
Но ~0 ещё короче. Или я что-то не так понял в условиях ?
Сергей Борщ
Цитата(WitFed @ Dec 26 2014, 15:16) *
Или я что-то не так понял в условиях ?
На некоторых архитектурах, на которых int 16-битный, выражение uint32_t min_per = 0 - 1; (хотя 0 здесь лишний, просто -1 дает тот же результат) присвоит min_per значение 0x0000FFFF. Наверное самым коротким и правильным была бы запись uint32_t min_per = -(uint32_t)1;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2018 Invision Power Services, Inc.