Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.236.86.184] |
|
Страницы: (78) « Первая ... 74 75 [76] 77 78 ( Перейти к последнему сообщению ) |
Сообщ.
#1126
,
|
|
|
Тут то можно, а вот как в:
if( a&64 ) Добавлено Я конечно понимаю, что несколько нечестно выдумываю примеры, но вот так и тянет-с: "если (первый, третий, пятый и седьмой биты равны), или (4-ый и 6-й равны нулю, а второй да восьмой равны 1) то": if( (a.1==a.3 && a.1==a.5 && a.1==a.7) || (a.4==a.6 && a.4==0 && a.2==a.8 && a.2==0) ) if( (!((a&(1|4|16|64))^(1|4|16|64)) || !(a&(1|4|16|64))) || (!((a&(2|128))^(2|128)) && !(a&(8|32))) ) Добавлено Пардон, в первой строке в хвосте 1 надо: if( (a.1==a.3 && a.1==a.5 && a.1==a.7) || (a.4==a.6 && a.4==0 && a.2==a.8 && a.2==1) ) Добавлено Как всё это будет выглядеть со сдвигами единицы даже думать (страшно|не хочется). |
Сообщ.
#1127
,
|
|
|
Цитата Славян @ Битами было бы просто: "if( a.7 ), а сдвигами придётся ж скобки мутить!? if(a & (1 << 7)) Цитата Славян @ Ну вот разве что "если биты равны между собой". Но этот пример реально выдуманный, за 28-летнюю практику программирования микроконтроллеров (низкоуровнее некуда) хорошо если пару раз была необходимость сравнивать биты между собой, да и в те разы таких битов было всего два, поэтому можно было записать Я конечно понимаю, что несколько нечестно выдумываю примеры, но вот так и тянет-с: "если (первый, третий, пятый и седьмой биты равны), if(!!(a & (1 << 1)) == !!(a & (1 << 5))) Ваш пример, соответственно, решается так: if( false || (!!(a & (1 << 1)) == !!(a & (1 << 3)) == !!(a & (1 << 5)) == !!(a & (1 << 7))) || ( true && !(a & (1 << 4)) && !(a & (1 << 6)) && (a & (1 << 2)) && (a & (1 << 8)) ) ) Но если отвлечься от придуманных примеров - то в реальных задачах каждый бит отвечает за конкретную сущность и надо именовать его этой сущностью, а не оперировать некими "магическими" числами (неважно - номерами бита или битовыми масками) и тут битовые поля вполне себе с задачей справляются: union shift_reg_pinout { struct { uint8_t AC_out1_red : 1; uint8_t AC_out4_green : 1; uint8_t AC_out4_red : 1; uint8_t AC_out3_green : 1; uint8_t AC_out3_red : 1; uint8_t AC_out2_green : 1; uint8_t AC_out2_red : 1; uint8_t AC_out1_green : 1; uint8_t AC_out5_red : 1; uint8_t AC_in2_green : 1; uint8_t AC_in2_red : 1; uint8_t AC_in1_green : 1; uint8_t AC_in1_red : 1; uint8_t AC_out6_green : 1; uint8_t AC_out6_red : 1; uint8_t AC_out5_green : 1; }; uint16_t Raw; } __attribute__((packed)); А ваше желание реализуется таким же битовым полем с именами членов "_0", "_1", "_2" и т.д. |
Сообщ.
#1128
,
|
|
|
Только в вашем первом коде надо поправить на 6, ибо 1<<n=2n, поэтому 1<<7 = 128.
|
Сообщ.
#1129
,
|
|
|
Цитата Славян @ Вы хотели проверять седьмой бит. Я его и проверил. Или вы биты считаете не с нуля, а с единицы? Тогда и все остальные надо поправлять, я привык биты считать с нуля и да, 1<<7 это 128, а 1 << 0 - это 1. Только в вашем первом коде надо поправить на 6, ибо 1<<n=2n, поэтому 1<<7 = 128. |
Сообщ.
#1130
,
|
|
|
Цитата Dushevny @ Ну в том конкретном пожелании я написал "a&64", что указывает на необходимость сдвига на 6. И запись вида a.0 несколько режет глаз, поэтому думается, что лучше бы было пользоваться видом a.1 - a.8. Вот если бы они индексировались (этап 2 ), как предлагал qraizer (a.i), то тогда выгоднее вести запись их с нуля. Но индексация выглядит сильно коряво, посему я о ней даже не думаю... Или вы биты считаете не с нуля, а с единицы? |
Сообщ.
#1131
,
|
|
|
Цитата Славян @ А, вы про тот пример? Так там я на 6 и сдвигал:Ну в том конкретном пожелании я написал "a&64", что указывает на необходимость сдвига на 6 Цитата Dushevny @ Все, теперь понял. Я не обратил внимания на текст в блоке кода (лучше всего спрятанное лежит на самом видном месте) и начал отвечать на "if(a.7)", полагая, что вы имели ввиду седьмой бит считая с нуля. Все, мир.Таким школьникам бью по рукам линейкой и заставляю сто раз писать на доске a |= 1 << 6. Цитата Славян @ В любой документации биты нумеруются с нуля. Получается, тут все идут не в ногу и только вы один - в ногу И запись вида a.0 несколько режет глаз, поэтому думается, что лучше бы было пользоваться видом a.1 - a.8 |
Сообщ.
#1132
,
|
|
|
Увидел, что 128-битное плавающее записывается как 'long double'.
А почему делают именно связку имеющихся типов, а не какой-то новый, скажем 'longdouble' ? Так как-то парсер проще настроить, или ещё какие-то соображения есть? |
Сообщ.
#1133
,
|
|
|
Если коротко, то тебя обманули. В C/C++ нет чётких характеристик типов данных, есть только их характеристики относительно друг друга. (Единственное исключение – char. Его sizeof == 1, но даже для него нет требований в количестве бит.) В этом смысле long double должен быть не менее мощен, нежели double, и в частности характеристики этих типов могут совпадать.
Даже больше. Стандарты C/C++ не регламентируют представление типов с плавающей точкой. (В отличие от целочисленных, для которых какое-никакое представление регламентируется.) Они описаны в абстрактных понятиях мантиссы/порядка/знака с поведением, основанным на части IEEE-754. Другими словами, реализации не обязаны придерживаться IEEE-754 или чего-то подобного для репрезентации float/double/long double. Просто чаще всего железяки проектируют не конкретно под C/C++, а под RFS-стандарты, и следование IEEE для компоненты FPU обычно выгоднее, т.к. делает эти железяки вполне удобными безотносительно к инструментальным средствам и знакомыми программистам. Поэтому средства разработки тоже не выделываются и просто реализуют IEEE. Причём даже если исходно железяка не поддерживает плавающую точку, и среда вынуждена имитировать её наличие программными методами. Что касается новых слов, то тут всё гораздо прозаичнее. Несложно поднастроить парсер исходного кода, наделив его знанием о новых токенах, немножечко сложнее наделить граммер знанием о характеристиках этого токена. Самое сложное – не поломать существующую кодовую базу, насчитывающую 50-летнюю историю. Когда, скажем, хренадцать лет назад писалась некая большая система, например Oracle DB, никаких bool, typeof, complex итд итп идр в языке не было, поэтому программисты вольны были использовать их в своих целях. Несложно представить, что бы произошло, если бы в C99 добавили bool с false и true. Причём имеющему влияние на всю систему целиком, независимо от того, каково было их распространение в исходном виде, пусть даже и сугубо локальное в отдельных функциях. Поэтому появление нового ключевого слова в языке всегда очень нежелательный процесс. |
Сообщ.
#1134
,
|
|
|
Цитата Qraizer @ Несложно поднастроить парсер исходного кода, наделив его знанием о новых токенах, немножечко сложнее наделить граммер знанием о характеристиках этого токена. Самое сложное – не поломать существующую кодовую базу, насчитывающую 50-летнюю историю. Кстати, хорошая и важная тема! В этом плане С++, да и ряд еще "перпендикулярных" ЯП, типа Pascal, Rust, D и подобных - будут в жутком цейтноте переработки парсеров по мере развития стандартов. То ли дело Perl Шучу, еще и PHP. Они сделали когда-то очень, ИМХО, "знаковый" шаг - разделили понятие "переменная" и все остальное. На мой взгляд, это знатно упрощает парсинги. Я когда-то, лет 20 назад, плотно сидел на Паскале (Borland Turbo, Virtual Pascal, Delphi, Free Pascal), и спустя уже n-месяцев словил себя на мысли, да какого хрена мне писать присвоение как ":="?!! Сравнений на порядки меньше присваиваний. А потом сишные {} вместо паскалевских begin-end просто манили. Так я пришел к Перлу Ну а если без шуток и пафоса ... если бы ввели четкое ограничение в С++ как и в PHP & Perl - именовать переменные, начиная с $ - сложность разбора, ИМХО, сильно бы просела. Повторюсь - IMHO! |
Сообщ.
#1135
,
|
|
|
Ну, так было изначально. В Фортране, например. А потом ещё в Бейсике. Не прижилось, потому что неудобно.
К тому же не только переменными едиными. Как быть с типами, именами структур/классов/объединений, перечислениями, функциями, пространствами имён... ? |
Сообщ.
#1136
,
|
|
|
Цитата Qraizer @ К тому же не только переменными едиными. Как быть с типами, именами структур/классов/объединений, перечислениями, функциями, пространствами имён... ? Последнее время мне приходится работать с PHP. Поверь мне, у меня есть достаточный опыт работы и с С++, и с PHP, соответственно - некоторые оправданные временем умозаключения. Даже скорее не умозаключения - а, как говорят, мышечная память, на уровне набора исходного кода. У PHP много хорошего, которое стоило бы перенять. Но есть и "шлак" в виде "персонального" обозначения видимости методов - в С++ это сделано компактнее, естественние. |
Сообщ.
#1137
,
|
|
|
Нановопрос. (Давно уж спрашивал, но подзабыл ответ).
Если я пишу a = *b, b++; П.С. просто сие видится как "один сложный кусок в единице трансляции/интерпретации, а потому программист должен сам быть уверен, что каша в его выполнении не несёт ничего многозначного"... |
Сообщ.
#1138
,
|
|
|
Славян, по идее, при операции запятая сперва вычисляется левый операнд, а потом правый. В твоем случае, при таком присвоении вычисляется *b и присваивается для а, потом вычисляется b++ и отбрасывается.
А вот если бы было: a = (*b, ++b); То тогда, сперва бы вычислялся операнд *b, потом инкремент b, и результат инкремента присваивался бы a. Но если бы было как написано b++, инкремент был бы строго после присвоения. |
Сообщ.
#1139
,
|
|
|
Запятая вносит точку следования между левым и правым операндом, так что все сайд-эффекты после вычисления левого должны быть нейтрализованы. В твоём случае в , нет смысла, т.к. её приоритет ниже, чем у присваивания.
|
Сообщ.
#1140
,
|
|
|
Есть ли хоть какой-то шанс (хоть 1%-й), что введут в стандарт тип complex? Для комплексных чисел.
А то, мне думается, что чуть ли не 'каждый второй' ваял такой класс/методы работы с ними, но всё же (при наличии стандарта) много ж было бы несколько проще. Или же работает принцип "есть же в бусте, значит наплюём!"? |