Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / системы счисления / 25 сообщений из 25, страница 1 из 1
27.02.2004, 00:18
    #32423471
oksale
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
как в си разобрать число типа SHORT по битам, чтобы работать с каждым битом в отдельности?
...
Рейтинг: 0 / 0
27.02.2004, 01:15
    #32423481
Lepsik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
struct bt{\r
int bit1 : 1;\r
int bit2 : 2;\r
int bit3 : 3;\r
int bit4 : 4;\r
int bit5 : 5;\r
int bit6 : 6;\r
int bit7 : 7;\r
int bit8 : 8;\r
};\r
\r
union un\r
{\r
bt bits;\r
short shrt;\r
};\r
\r
void func()\r
{\r
un A;\r
A.shrt = 100;\r
A.bits.bit1 = 1;\r
A.bits.bit2 = 0;\r
}\r
\r
а лучше читать и сосeдние топики \r
\r
/topic/76808
...
Рейтинг: 0 / 0
27.02.2004, 11:10
    #32423843
oksale
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
Кажется, это мне не совсем подходит. У меня уже есть число типа SHORT, например, 32. Мне необходимо считать информацию из каждого бита этого числа.
...
Рейтинг: 0 / 0
27.02.2004, 11:39
    #32423904
gardenman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
bool getbit(short var,short bitn) {
return (var>>bitn)&0x1;
}
...
Рейтинг: 0 / 0
27.02.2004, 12:18
    #32423977
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
лучше так:

BOOL getbit(short var, BYTE bitn) {
return (var & (1<<bitn));
}
...
Рейтинг: 0 / 0
27.02.2004, 12:47
    #32424065
oksale
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
блин, ничего не понимаю:(( Мне еще не приходилось с таким сталкиваться.
У вас нет ссылки, где можно было бы разобраться в этом?

И что эта ф-ция делает: сдвигает биты или достает один бит? Дурацкий вопрос, но я правда не понимаю :(
...
Рейтинг: 0 / 0
27.02.2004, 22:06
    #32425021
Lepsik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
--Кажется, это мне не совсем подходит.

чем это не подходит ? вы программировать вчера что ли начали ?
un A;
A.shrt = 32;

if( A.bits.bit1 == 1 ) printf("установлен 1-бит"); else printf("сброшен 1-бит");
if( A.bits.bit2 == 1 ) printf("установлен 2-бит"); else printf("сброшен 2-бит");
if( A.bits.bit3 == 1 ) printf("установлен 3-бит"); else printf("сброшен 3-бит");
if( A.bits.bit4 == 1 ) printf("установлен 4-бит"); else printf("сброшен 4-бит");
if( A.bits.bit5 == 1 ) printf("установлен 5-бит"); else printf("сброшен 5-бит");
if( A.bits.bit6 == 1 ) printf("установлен 6-бит"); else printf("сброшен 6-бит");
if( A.bits.bit7 == 1 ) printf("установлен 7-бит"); else printf("сброшен 7-бит");
if( A.bits.bit8 == 1 ) printf("установлен 8-бит"); else printf("сброшен 8-бит");
}

или с помощью булвых оперaций - функцию вам уже показали.
...
Рейтинг: 0 / 0
28.02.2004, 23:52
    #32425325
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
2 Lepsik

Не подходит по следующим причинам:
1) я не встречал реализации, в которых short int занимал бы 1 байт, поэтому Ваш код относится к очень специфическому случаю, а поэтому непереносим.
2) запись в один член объединения, а чтение из другого приводит к неопределенному поведению. Объединения (union) применяется для экономии памяти, а не подобного рода трюков.

2 oksale

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
#include <bitset>
#include <limits>
#include <iostream>

int main()
{
    std::bitset<numeric_limits<short>::digits> b( 32 );
    std::cout << b;
}


Удач.
...
Рейтинг: 0 / 0
01.03.2004, 10:51
    #32425856
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
1. Блин, ну ясно ведь, что человек просто пример привёл, для понятности, иначе бы вообще в одну строчку всё написал. Чё уж докапываться-то? :)

2. А вот и нет. Union часто так же используют для каста, кстати, очень удобно, тип _variant_t, яркий тому пример. А к "неопределённому поведению" приводят кривые руки.
...
Рейтинг: 0 / 0
01.03.2004, 11:07
    #32425885
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
CEMb
1. Блин, ну ясно ведь, что человек просто пример привёл, для понятности, иначе бы вообще в одну строчку всё написал. Чё уж докапываться-то? :)

Ну, да, конечно, пусть новичек рубаху на себе рвет после таких примеров.
Мне впредь у вас спрашивать можно докапываться или нет?

CEMb
2. А вот и нет. Union часто так же используют для каста, кстати, очень удобно, тип _variant_t, яркий тому пример.


Читайте стандарт. Касты таким образом никто не делает. Яркий пример _varian_t никто подобным образом не использует:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
union test
{
    int d;
    double f;
};

test t;
t.d =  10 ;
std::cout << t.f;


посколько этот код приводит к неопределенному поведению. Еще раз повторю, union используют для экономии памяти. Для кастинга есть static_cast, cost_cast, dynamic_cast, reinterpret_cast.
...
Рейтинг: 0 / 0
01.03.2004, 11:53
    #32425990
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
Анатолий Широков

Полностью поддерживаю

CEMb

Variant'ы обычно реализуются при помощи дополнения union еще и полем в котором храниться еще и текущий тип значения хранящегося в варианте - так что там union просто для экономии памяти
...
Рейтинг: 0 / 0
01.03.2004, 16:15
    #32426651
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторНу, да, конечно, пусть новичек рубаху на себе рвет после таких примеров. Всё равно такой пример более наглядный, чем что-то компактное с кучей индексов. И лучше в начале порвать одну рубаху, чем потом рвать их постоянно.
авторМне впредь у вас спрашивать можно докапываться или нет?
Можно спрашивать, а можно и не спрашивать :)

2. С вариантом, действительно, не совсем к месту. Но про каст читал где-то(как бы не у Шилдта).
...
Рейтинг: 0 / 0
02.03.2004, 02:08
    #32427160
Lepsik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
2Анатолий Широков
--Не подходит по следующим причинам:
--1) я не встречал реализации, в которых short int занимал бы 1 байт, поэтому Ваш код относится к очень специфическому случаю, а поэтому непереносим.

легко на 8-битных процессорах. 16 строчек набивать мне как-то в лом. ТАк что я не понял проблем с реализацией. Если не знали этого, то еще не значит что это неправильно.

--2) запись в один член объединения, а чтение из другого приводит к неопределенному поведению.

рекомендую читать/(или приводить в пример) первоисточники или по крайней мере говорить: "я всегда до сих пор считал и это является всего лишь моим личным мнением, не претендующим на абсолютную правду". Тогда, по крайней мере, читатели не будут введены в заблуждение безапеляционным тоном

---union test
{
int d;
double f;
};


родной мой - складывать надо переменные одного размера, чтобы ожидать правильного кастинга, хотя тут вы кое-где правы - чтобы так делать кастинг - надо знать как они укладывается компилятором

чисто чтобы напомнить
sizeof(int) = 4
sizeof(double) = 8
...
Рейтинг: 0 / 0
02.03.2004, 09:29
    #32427230
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
Lepsik

Родной, это
Код: plaintext
1.
sizeof(int) =  4  
sizeof(double) =  8 


не всегда верно
...
Рейтинг: 0 / 0
02.03.2004, 19:13
    #32428583
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторлегко на 8-битных процессорах. 16 строчек набивать мне как-то в лом. ТАк что я не понял проблем с реализацией. Если не знали этого, то еще не значит что это неправильно.

Я не говорил, что это неправильно, я говорил, что Вы привели специфичный код который негоден для применения на 32 разрядных платформах из-за трактовки short как последовательности из восьми бит. Далее я сказал, что этот код приводит к неопределенному поведению программы, так как согласно 9.5 п.1 ISO/IEC 14882:1998 (E) только один член объединения может быть активен, что означает, что нельзя осуществлять запись в один член, а чтение из другого.

авторрекомендую читать/(или приводить в пример) первоисточники или по крайней мере говорить: "я всегда до сих пор считал и это является всего лишь моим личным мнением, не претендующим на абсолютную правду".


Ответил выше

автор
---union test
{
int d;
double f;
};

родной мой - складывать надо переменные одного размера, чтобы ожидать правильного кастинга, хотя тут вы кое-где правы - чтобы так делать кастинг - надо знать как они укладывается компилятором


Где Вы прочитали эту чушь, что объединение можно использовать для кастинга (цитату пожалуйста)?

зы: Насчет "родного". Ни в каких родственных связях я с Вами не состою, поэтому не предендую на звание "родного". Вполне терпимо отнесусь к обращению "милостливый государь" или "товарищ"
...
Рейтинг: 0 / 0
03.03.2004, 03:44
    #32428792
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
ребята, не кипятитесь...
рекомендации рекомендациями... но юнионы всегда использовались именно для удобного кастинга, типа:

typedef union { unsigned u; char s[sizeof(unsigned)]; } nice_unsigned;
nice_unsigned n;
n.u=0x00434241;
printf("%s", n.s);

использование именно в таком качестве постоянно встречал у MS и Borland - двух ведущих разработчиков компиляторов. :)

ясен пень, что подобные упражнения весьма платформенно-зависимы... ну дык, они именно под конкретные платформы и писали.

не скрою, когда пишу ИМЕННО под Win32, то тоже позволяю себе подобные удобства - платформа-то фиксирована. :)

Далее я сказал, что этот код приводит к неопределенному поведению программы, так как согласно 9.5 п.1 ISO/IEC 14882:1998 (E) только один член объединения может быть активен, что означает, что нельзя осуществлять запись в один член, а чтение из другого.
нет, это значит только то, что значит и ничего более.
это означает, что стандарт не определяет явно поведение программы в подобных случаях, т.е. оно может отличаться на различных компиляторах/платформах.
...
Рейтинг: 0 / 0
03.03.2004, 10:46
    #32429090
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
MSDN...It is similar to a structure except that all of its members start at the same location in memory.

Тиакм образом, если они там лежат "как надо", можно делать каст, если нет - нельзя или делать как-то иначе.

К примеру, обломный вариан(5 байт на тип, поряок байт в типе):
long 12345 и float 34251
...
Рейтинг: 0 / 0
03.03.2004, 11:04
    #32429130
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторрекомендации рекомендациями... но юнионы всегда использовались именно для удобного кастинга, типа:

typedef union { unsigned u; char s[sizeof(unsigned)]; } nice_unsigned;
nice_unsigned n;
n.u=0x00434241;
printf("%s", n.s);

Этот пример зависит от входных данных и будет работать раз от разу и то только в том случае, если нам посчастливится встретить на пути '\0' при выводе n.s.

Теперь объясните, чем Ваш код лучше явного приведения к (char const *)?
Например, мне необходимо побайтово вывести unsigned в поток:

Код: plaintext
1.
2.
3.
4.
5.
6.
unsigned u = 0x00434241;
	
char const *begin = (char const *)&u;
char const *end = begin + sizeof(u);

for(; begin!=end; begin++)
    printf( "%x" , *begin);


Причем, этот код легко обобщается для вывода любого фундаментального типа и POD структур. Ваш же подход, помимо того, что его еще нужно довести до ума, загрязняет пространство имен бесполезными типами, только ради того, чтобы симулировать и без того имеющийся в наличии кастинг.


авторДалее я сказал, что этот код приводит к неопределенному поведению программы, так как согласно 9.5 п.1 ISO/IEC 14882:1998 (E) только один член объединения может быть активен, что означает, что нельзя осуществлять запись в один член, а чтение из другого.

авторнет, это значит только то, что значит и ничего более.
это означает, что стандарт не определяет явно поведение программы в подобных случаях, т.е. оно может отличаться на различных компиляторах/платформах.

Это и называется неопределенным поведением! Я об этом и долдонил с самого начала.
...
Рейтинг: 0 / 0
04.03.2004, 10:24
    #32430662
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторТеперь объясните, чем Ваш код лучше явного приведения к (char const *)?

Например вот этим. Два примера подряд.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 227 :      nice_unsigned n;
 228 :      n.u=0x00434241;
00404EDD   mov         dword ptr [ebp- 8 ],434241h
 229 :      printf( "%s" , n.s);
00404EE4   mov         esi,esp
00404EE6   lea         eax,[ebp- 8 ]
00404EE9   push        eax
00404EEA   push        offset string  "%s"  ( 00419218 )
00404EEF   call        dword ptr [__imp__printf (0041cae4)]
00404EF5   add         esp, 8 
00404EF8   cmp         esi,esp
00404EFA   call        _chkesp (004060ca)
 230 :
// а тут пошёл второй пример.
 231 :      unsigned u = 0x00434241;
00404EFF   mov         dword ptr [ebp-0Ch],434241h
 232 :
 233 :      char const *begin = (char const *)&u;
00404F06   lea         ecx,[ebp-0Ch]
00404F09   mov         dword ptr [ebp-10h],ecx
 234 :      char const *end = begin + sizeof(u);
00404F0C   mov         edx,dword ptr [ebp-10h]
00404F0F   add         edx, 4 
00404F12   mov         dword ptr [ebp-14h],edx
 235 :
 236 :      for(; begin!=end; begin++)
//  7  операций для цикла
 237 :          printf( "%x" , *begin);
00404F28   mov         edx,dword ptr [ebp-10h]
00404F2B   movsx       eax,byte ptr [edx]
00404F2E   mov         esi,esp
00404F30   push        eax
00404F31   push        offset string  "%x"  (00419d3c)
00404F36   call        dword ptr [__imp__printf (0041cae4)]
00404F3C   add         esp, 8 
00404F3F   cmp         esi,esp
00404F41   call        _chkesp (004060ca)


Выкидываем цикл и вывод.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 228 :      n.u=0x00434241;
00404EDD   mov         dword ptr [ebp- 8 ],434241h
 229 :
 230 :      unsigned u = 0x00434241;
00404EE4   mov         dword ptr [ebp-0Ch],434241h
 231 :      char const *begin = (char const *)&u;
00404EEB   lea         eax,[ebp-0Ch]
00404EEE   mov         dword ptr [ebp-10h],eax


плюс две операции. Например, в риалтайме это может стать существенным.
Разница в 200%. Я не говорю, что второй пример хуже. Просто в конкретной ситуации он бы был хуже.
...
Рейтинг: 0 / 0
04.03.2004, 11:56
    #32430892
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
2 CEMb

Вас не смущает то, что первый пример нерабочий (я даже объяснил выше почему)? А, ну да, зачем это. Главное, чтобы он был быстрый. Неправда ли, коллега?:)

Ладно, раз Вы настаиваите, вот Вам рабочий аналог кода vdimas-а:

Код: plaintext
1.
2.
3.
 /*STDLIB*/ 
unsigned u = 0x00434241;
fwrite(&u, sizeof(u),  1 , stdout);


Сравнивайте на здоровье.
...
Рейтинг: 0 / 0
04.03.2004, 12:26
    #32430951
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторВас не смущает то, что первый пример нерабочий (я даже объяснил выше почему)? А, ну да, зачем это. Главное, чтобы он был быстрый. Неправда ли, коллега?:)

Неправда :)

Пример рабочий, на моей машине работал.
Чтоб он был быстрый - это зависит от ситуации. Иногда надо. Тогда надо позаботиться о безопастности. О чём я и говорил раньше (про "кривые руки"). То есть вставляя проверки, заставляя компилятор делать самому касты, етс, мы теряем время. Если время нам недорого - пожалуйста, если дорого - тогда берём ответственность за безопастность на себя.
...
Рейтинг: 0 / 0
04.03.2004, 12:47
    #32431020
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторПример рабочий, на моей машине работал.

Попрошу выполнить следующее:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
typedef union { unsigned u; char s[sizeof(unsigned)]; } nice_unsigned; 

unsinged begin = 0xFFFFFFFF;
unsinged u = 0xFFFFFFFF;
unsinged end = 0xFFFFFFFF;

nice_unsigned n; 
n.u=u; 
printf( "%s" , n.s);  


Еще раз повторю, решение зависящее от входных данных не является корректным решением.

авторЧтоб он был быстрый - это зависит от ситуации. Иногда надо. Тогда надо позаботиться о безопастности. О чём я и говорил раньше (про "кривые руки"). То есть вставляя проверки, заставляя компилятор делать самому касты, етс, мы теряем время. Если время нам недорого - пожалуйста, если дорого - тогда берём ответственность за безопастность на себя.

Каст такой какой приведен здесь разруливается компилятором, то есть в компайлтайме, а не в рантайме. Так что, о задержке в рантайме на кастинг - ложь.

Рантайм возникнет только при использовании dynamic_cast, но это тема другого разговора.

Все, предлагаю закончить.
...
Рейтинг: 0 / 0
04.03.2004, 12:50
    #32431035
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
поправка:

Код: plaintext
1.
2.
3.
4.
5.
6.
typedef union { unsigned u; char s[sizeof(unsigned)]; } nice_unsigned; 

unsinged begin = 0xFFFFFFFF;
nice_unsigned n;
unsinged end = 0xFFFFFFFF;
n.u=0xFFFFFFFF; 
printf( "%s" , n.s);  
...
Рейтинг: 0 / 0
04.03.2004, 13:11
    #32431089
JibSkeart
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
А что это никто не предложил такой математический школьный способ ??

char c[7];
int a = 123;
for (int i=0;i<=7;i++)
{
if (a%2 == 0) {c[8-i] = '0';} else {c[8-i] = '1';}
a = a/2;
}

Зыыы , это вспомнилось


i_i
(';')
(V),(V),,

JS
...
Рейтинг: 0 / 0
04.03.2004, 16:29
    #32431545
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
системы счисления
авторВсе, предлагаю закончить.
Да, пора закругляться...

авторрешение зависящее от входных данных не является корректным решением.
...может это надо было бы и вынести в отдельную ветку... :)
Не согласен. Если мы может быть уверенными в том, что наши данные будут определённого формата - то всё корректно.
К примеру, прога делает сдвиг и л.сложение в WORD несколько сотен тысяч раз в секунду. Интересен 4 с начала байт. То есть, сдвиг на 11 и &0x1. Ясно, что на BYTE и на LONG работать не будет. Но не делать же проверку на размер 100000 раз. Надо просто поставить условие, что для данной операции будет использоваться тока WORD. Ситуация, конечно, редкая, но такое бывает.

Хех, тут можно как раз каст сделать к байту... Не та ситуация... Но вобщем, подойдёт любая ситуация в реал-тайме с проверками. Сравнить хотя бы движок VC и LabVIEW. Первый работает гораздо быстрее второго даже с кучей всяких dll, потому что у второго в рантайме куча всяких проверок стоит.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / системы счисления / 25 сообщений из 25, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]