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


Автор: rthsobakas 11.4.2009, 20:16
Что означает эта запись?
 UINT64 id;
id=id<<1;

and

UINT64 v;
v=v>>6;


То есть не совсем ясно сущность >> в данном случае

Автор: X-3R1 11.4.2009, 20:21
смещение влево на один бит, и вправо на 6 бит

Автор: azesmcar 11.4.2009, 20:22
rthsobakas

было уже
http://forum.vingrad.ru/forum/topic-252868/hl/index.html

Автор: rthsobakas 11.4.2009, 20:44
X-3R1,  сдвиг какой? циклический арифметический? То есть сдвигает и нули пишет или переносит бит?

Автор: zim22 11.4.2009, 20:45
Цитата(rthsobakas @  11.4.2009,  20:44 Найти цитируемый пост)
 сдвиг какой? циклический арифметический? То есть сдвигает и нули пишет или переносит бит?

а вы сами не можете проверить?
Код

#include <windows.h>
#include <iostream>

void printBit(UINT64 &var)
{
  UINT64 mask = 1;
  for (int i = 0; i != 64; ++i)
    if (mask << i & var) std::cout << "1";
    else std::cout << "0";    
  
  std::cout << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
   UINT64 id = 9999999999999999999;      
   printBit(id);   
   id=id<<1;
   printBit(id);      


UINT64 v = 9999999999999999999;
printBit(v);   

v=v>>6;
   printBit(v);   

    return 0;
}


Автор: inside_pointer 12.4.2009, 00:10
Цитата(rthsobakas)

То есть сдвигает и нули пишет или переносит бит?

ничо не переносит, просто сдвигает и всё (слева будет ставить бит знака, а справа нули)
есть разница между signed и unsigned, у unsigned бит знака ноль, а у signed может быть ноль, а может быть еденица, что там стоит, то и будет ставиться

Автор: mes 12.4.2009, 01:58
Цитата(inside_pointer @  11.4.2009,  23:10 Найти цитируемый пост)
у unsigned бит знака ноль, а у signed может быть ноль, а может быть еденица

у unsigned нет знакового бита

Автор: inside_pointer 12.4.2009, 04:19
да есть он, просто он нулю равен всё время

update:
иначе как она определяет signed там или unsigned и чем заполнять

Автор: W4FhLF 12.4.2009, 05:45
Цитата(inside_pointer @  12.4.2009,  04:19 Найти цитируемый пост)
иначе как она определяет signed там или unsigned и чем заполнять


На этапе компиляции определяет набор команд и действий. 

Автор: inside_pointer 12.4.2009, 06:17
для signed сдвиг зависит от компилятора, может заменять слева знаковым битом, а может другим

почему unsigned - положительное число ?
если компилятор знает про знак, как он его определяет у unsigned ?
я думаю там стоит ноль где-то

Автор: zim22 12.4.2009, 06:59
Цитата(inside_pointer @  12.4.2009,  06:17 Найти цитируемый пост)
я думаю там стоит ноль где-то

а вы сами http://forum.vingrad.ru/index.php?showtopic=254517&view=findpost&p=1836446

Автор: azesmcar 12.4.2009, 10:52
inside_pointer

нету у unsigned знакового бита, т.е. сам бит есть, но он не используется для хранения знака и не для хранения просто нуля. А для того чтобы хранить больше данных, т.е. использовать знаковый бит для хранения числа.
Код

    int a = INT_MAX;
    unsigned int b = UINT_MAX;
    std::cout << a << std::endl;
    std::cout << b << std::endl;


Автор: inside_pointer 12.4.2009, 11:01
понимаешь, он может ноль слева ставить просто так, для всех, а может для знаковых ставить знаковый бит, и, вот, если он для знаковых ставит знаковый бит, то почему он для беззнаковых не ставит знаковый бит (ну который всегда равен нулю) ?
если сравнить число unsigned с нулём, почему оно больше ?

Автор: zim22 12.4.2009, 11:08
Цитата(inside_pointer @  12.4.2009,  11:01 Найти цитируемый пост)
если сравнить число unsigned с нулём, почему оно больше ?

Код
unsigned int i = 0;
if (i ==0) std::cout << "i == 0";


Автор: GoldFinch 12.4.2009, 11:16
нету никакого знакового бита в целых числах, 
то что старший разряд отрицательного целого числа равен 1, это не говорит о том что это знаковый бит

если бы в целых числах использовался знаковый бит, то int(-1) было бы 0x80000001, а не 0xFFFFFFFF
и операция отрицания выглядела бы как "x=x xor 0x80000000" а не "x=(not x)+1 "

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

Автор: mes 12.4.2009, 11:17
Цитата(inside_pointer @  12.4.2009,  10:01 Найти цитируемый пост)
то почему он для беззнаковых не ставит знаковый бит (

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

Цитата(inside_pointer @  12.4.2009,  10:01 Найти цитируемый пост)
если сравнить число unsigned с нулём, почему оно больше ? 

потому что так интерпретируется значение.
вот пример разной интерпретации одного и того же значения в зависимости от типа :
Код

 std::cout << (signed short)  (0xFFFF) << std::endl;
 std::cout << (unsigned short)(0xFFFF) << std::endl;

в данном примере  тот бит который считается знаковым у signed, у unsigned равен 1, но никак не влияет на знак  smile 

Автор: inside_pointer 12.4.2009, 11:24
Цитата(zim22)

Код

    unsigned int i = 0;



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

Автор: zim22 12.4.2009, 11:30
Цитата(inside_pointer @  12.4.2009,  11:24 Найти цитируемый пост)
 интересно что будет ставиться

почему бы тогда явно не выставлять 0/1?

Автор: Anikmar 12.4.2009, 11:41
inside_pointer,
http://kuzelenkov.narod.ru/mati/book/inform/inform5.html

Автор: mes 12.4.2009, 11:44
Цитата(inside_pointer @  12.4.2009,  10:24 Найти цитируемый пост)
ноль - это частный случай, а если у signed int сдвигать ноль вправо и будет система, где ставится знаковый бит, интересно что будет ставиться 

при нуле у signed(также как и unsigned) все биты, в том числе и знаковый равны нулю и как следствие куда бы не сдвигали, все равно будет 0.
А если поставите в старший ("знаковый") бит единицу, то это уже будет не ноль (и у signed, и у unsigned), а конкретное его значение будет зависеть от разрядности,
так для 8ми разрядов signed будет интерпретироваться как -128, а unsigned как 128.


Автор: J0ker 13.4.2009, 00:02
Цитата(inside_pointer @  12.4.2009,  06:17 Найти цитируемый пост)
для signed сдвиг зависит от компилятора, может заменять слева знаковым битом, а может другим

бредить изволите
не зависит это от компилятора
это зависит от представления отрицательных чисел
в текущей общепринятой системе целочисленные отрицательные представлены выставленным старшим битом
при сдвиге знаковый бит копируется - т.е. 10000000 >> 1 = 11000000; 100000000 >> 5 = 11111100 - что соответствует делению на 2^n

Автор: Anikmar 13.4.2009, 07:27
Цитата(J0ker @  13.4.2009,  00:02 Найти цитируемый пост)
при сдвиге знаковый бит копируется - т.е. 10000000 >> 1 = 11000000; 100000000 >> 5 = 11111100 - что соответствует делению на 2^n

Дополняю:
При сдвиге вправо копируется знаковый бит.
Для signed 1 (если отрицательное)
Для unsigned, соответственно, копируется 0

Автор: inside_pointer 13.4.2009, 08:40
Цитата(J0ker)

бредить изволите
не зависит это от компилятора
это зависит от представления отрицательных чисел

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

Anikmar, ноль или один, зависит от того, чему равен знаковый бит.

mes,
Наверное, всё таки, для unsigned он выставляет простые нули... но как тогда быть когда компилятор выставляется слева знаковый бит ? проще же считать, что, раз знак положительный, то и знаковый бит равен нулю

Добавлено через 3 минуты и 3 секунды
Цитата(zim22)

почему бы тогда явно не выставлять 0/1? 

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

Автор: zim22 13.4.2009, 08:59
Цитата(inside_pointer @  13.4.2009,  08:40 Найти цитируемый пост)
так оно бывает по-разному, может явно выставляться

я имел ввиду другое. вы ведь можете наложить на число битовую маску и добиться того, что необходимые разряды 100% будут установлены в 0 или 1.

Автор: Anikmar 13.4.2009, 09:08
Цитата(inside_pointer @  13.4.2009,  08:40 Найти цитируемый пост)
Anikmar, ноль или один, зависит от того, чему равен знаковый бит.

Ага, я уже уточнил.  smile 

Автор: Cheloveck 13.4.2009, 09:12
Код

#include <iostream>
#include <conio.h>
#include <stdlib.h>
using namespace std;

int main(int argc, char **argv)
{
    char buffer[33];
    unsigned int a = 0xFFFFFFFF;
    itoa(a, buffer, 2);
    cout << "unsigned int before shift = " << a << "\t" << buffer << endl;
    itoa(a >>= 1, buffer, 2);
    cout << "unsigned int after shift = " << a << "\t" << buffer << endl;
    signed int b = 0xFFFFFFFF;
    itoa(b, buffer, 2);
    cout << "signed int before shift = " << b << "\t" << buffer << endl;
    itoa(b >>= 1, buffer, 2);
    cout << "signed int after shift = " << b << "\t" << buffer << endl;
    getch();
    return 0;
}

Код

unsigned int before shift = 4294967295  11111111111111111111111111111111
unsigned int after shift = 2147483647   1111111111111111111111111111111
signed int before shift = -1    11111111111111111111111111111111
signed int after shift = -1     11111111111111111111111111111111

изучаем результаты, закрываем тему и не позоримся)))

Автор: Anikmar 13.4.2009, 09:13
Разница для знаковых и беззнаковых при сдвиге вправо я так понимаю обусловлена тем, что сдвиг вправо заменяет операцию деления на 2. Если бы для отрицательных знаковый бит не копировался - отрицательные числа считались бы неправильно.

Автор: J0ker 13.4.2009, 09:14
Цитата(Anikmar @  13.4.2009,  07:27 Найти цитируемый пост)
Дополняю:
При сдвиге вправо копируется знаковый бит.
Для signed 1 (если отрицательное)
Для unsigned, соответственно, копируется 0

исправляю
при сдвиге вправо для signed копируется знаковый бит
для unsugned ничего не копируется, а просто заполняется нулями (т.е. в C/C++ сдвиг не циклический и циклического нет)

Добавлено @ 09:19
Цитата(inside_pointer @  13.4.2009,  08:40 Найти цитируемый пост)
короче, для signed сдвиг зависим, он может заполняться нулями, а может знаковым битом ноль или один

ничего ни от чего не зависим - заполняется всегда знаковым битом - это соответствует делению на 2^n - как и должно быть, т.е. 10000000b == -128; 11000000b == -64; 11100000 == -32

Цитата(inside_pointer @  13.4.2009,  08:40 Найти цитируемый пост)
а от чего это зависит, чем он заполняется просто нулями или знаковым битом, не от компилятора ?

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

Автор: Anikmar 13.4.2009, 09:36
Цитата(J0ker @  13.4.2009,  09:14 Найти цитируемый пост)
исправляю
при сдвиге вправо для signed копируется знаковый бит
для unsugned ничего не копируется, а просто заполняется нулями (т.е. в C/C++ сдвиг не циклический и циклического нет)

Именно это я и имел в виду. Как та собака - все понимает а сказать не может  smile 

Автор: UnrealMan 13.4.2009, 13:11
Цитата(J0ker @  13.4.2009,  09:14 Найти цитируемый пост)
ничего ни от чего не зависим - заполняется всегда знаковым битом - это соответствует делению на 2^n - как и должно быть

минус 0.5 (потому что я сегодня добрый smile)

Цитата(5.8 Shift operators)
The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 divided by the quantity 2 raised to the power E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

Автор: xvr 13.4.2009, 15:30
Цитата(J0ker @ 13.4.2009,  00:02)
при сдвиге знаковый бит копируется - т.е. 10000000 >> 1 = 11000000; 100000000 >> 5 = 11111100 - что соответствует делению на 2^n

Уточнение - не совсем соответствует: (-1/2) == 0 but (-1 >> 1) == -1

Автор: J0ker 13.4.2009, 16:21
Цитата(UnrealMan @  13.4.2009,  13:11 Найти цитируемый пост)
минус 0.5 (потому что я сегодня добрый )

оппа
вот это жопа

впрочем, правильно
два моих утверждения противоречат друг другу...
остановимся на "от представления"  smile

Добавлено через 4 минуты и 45 секунд
Цитата(xvr @ 13.4.2009,  15:30)
Цитата(J0ker @ 13.4.2009,  00:02)
при сдвиге знаковый бит копируется - т.е. 10000000 >> 1 = 11000000; 100000000 >> 5 = 11111100 - что соответствует делению на 2^n

Уточнение - не совсем соответствует: (-1/2) == 0 but (-1 >> 1) == -1

Уточнение - совсем соответствует
вы не в ту сторону округляете
рассмотрите пример любого нечетного

Автор: xvr 13.4.2009, 16:41
Цитата(J0ker @ 13.4.2009,  16:21)

Цитата
Уточнение - не совсем соответствует: (-1/2) == 0 but (-1 >> 1) == -1

Уточнение - совсем соответствует
вы не в ту сторону округляете

Это не я округляю, это компилятор:
Код

#include <stdio.h>

main()
{
 printf("%d %d\n",-1/2,-1>>1);
 return 0;
}


Код

C:\!>cl tt.cxx
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

tt.cxx
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:tt.exe
tt.obj

C:\!>tt.exe
0 -1

Код

[rakhvato@msteplxl11 ~]$ g++ tt.cxx
[rakhvato@msteplxl11 ~]$ ./a.out
0 -1
[rakhvato@msteplxl11 ~]$ g++ -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)


Цитата

рассмотрите пример любого нечетного
Для нечетного будет совпадать

Автор: mes 13.4.2009, 16:48
Цитата(J0ker @  13.4.2009,  15:21 Найти цитируемый пост)
Уточнение - совсем соответствует

 -1>>666 == -1;  smile 

Автор: J0ker 13.4.2009, 16:48
xvr, вы не поняли
округление в сторону ближайшего меньшего
-5/2 = -3
-7/2 = -4
-1/2 = -1
никаких исключений

Автор: J0ker 13.4.2009, 16:48
mes, , вы не поняли
округление в сторону ближайшего меньшего
-5/2 = -3
-7/2 = -4
-1/2 = -1
никаких исключений 
 smile 


Автор: mes 13.4.2009, 16:51
Цитата(J0ker @  13.4.2009,  15:48 Найти цитируемый пост)
округление в сторону ближайшего меньшего

при -1 / 2^666  ближайшее меньшее будет -1 ?!

Автор: J0ker 13.4.2009, 17:00
Цитата(mes @ 13.4.2009,  16:51)
Цитата(J0ker @  13.4.2009,  15:48 Найти цитируемый пост)
округление в сторону ближайшего меньшего

при -1 / 2^666  ближайшее меньшее будет -1 ?!

ну дык
mes, вы тУпите?  smile 

Автор: mes 13.4.2009, 17:36
Цитата(J0ker @  13.4.2009,  16:00 Найти цитируемый пост)
ну дык

ага парюсь.. сбила формулировка 

Цитата(J0ker @  13.4.2009,  15:48 Найти цитируемый пост)
округление в сторону ближайшего меньшего

воспринял как в сторону ближайшего, а про меньшее забыл smile


Автор: xvr 13.4.2009, 19:18
Цитата(J0ker @ 13.4.2009,  16:48)
xvr, вы не поняли
округление в сторону ближайшего меньшего
-5/2 = -3
-7/2 = -4
-1/2 = -1
никаких исключений

Жаль, что компиляторы С/С++ не в курсе, и округляют к 0  smile

Автор: J0ker 13.4.2009, 23:34
Цитата(xvr @  13.4.2009,  19:18 Найти цитируемый пост)
Жаль, что компиляторы С/С++ не в курсе, и округляют к 0

здесь обсуждается не деление, а сдвиг
я вам указую, что никаких исключений при сдвиге нет - ни у positive/negative signed ни у unsigned - и там и там в текущем представлении сдвиг в право на один бит эквивалентен делению на 2 с округлением к меньшему  smile 

Автор: mes 14.4.2009, 00:33
Цитата(xvr @  13.4.2009,  14:30 Найти цитируемый пост)
Цитата

при сдвиге знаковый бит копируется - т.е. 10000000 >> 1 = 11000000; 100000000 >> 5 = 11111100 - что соответствует делению на 2^n

Уточнение - не совсем соответствует: (-1/2) == 0 but (-1 >> 1) == -1 


Цитата(J0ker @  13.4.2009,  22:34 Найти цитируемый пост)
десь обсуждается не деление, а сдвиг
я вам указую, что никаких исключений при сдвиге нет


 smile 

Автор: J0ker 14.4.2009, 01:17
mes,
а где я здесь говорю про округление? или как-то привязываю соответствующее сдвигу деление к реализации оного где- и чем-либо?
не выдавайте пжалста свои фантазии за мои слова  smile 

Автор: mes 14.4.2009, 01:57
Цитата(J0ker @  14.4.2009,  00:17 Найти цитируемый пост)
а где я здесь говорю про округление? или как-то привязываю соответствующее сдвигу деление к реализации оного где- и чем-либо?
не выдавайте пжалста свои фантазии за мои слова  smile 

думал две цитаты обойдутся без коммента..Исправляюсь : Я привел их к тому, что Вы оба говорите об одном и том же, но с разных сторон и причины для спора лично я не вижу smile
т.е для полной картины надо обе ваши фразы объединить , типа  этого:
Цитата

результат сдвига вправо всегда соответсвует рез-ту деления (...)  с округлением к меньшему,
однако для отрицательных чисел не соответсвует результату деления посредством "/".




Автор: xvr 14.4.2009, 07:28
Цитата(mes @ 14.4.2009,  01:57)
думал две цитаты обойдутся без коммента..Исправляюсь : Я привел их к тому, что Вы оба говорите об одном и том же, но с разных сторон и причины для спора лично я не вижу smile
т.е для полной картины надо обе ваши фразы объединить , типа  этого:
Цитата

результат сдвига вправо всегда соответсвует рез-ту деления (...)  с округлением к меньшему,
однако для отрицательных чисел не соответсвует результату деления посредством "/".

Полностью согласен. 2 J0ker  - консенсус?  smile 

Автор: Anikmar 14.4.2009, 07:50
Цитата(xvr @  14.4.2009,  07:28 Найти цитируемый пост)
Полностью согласен. 2 J0ker  - консенсус?   

Наливайте!  smile 

Автор: xvr 14.4.2009, 11:36
Цитата(Anikmar @ 14.4.2009,  07:50)
Цитата(xvr @  14.4.2009,  07:28 Найти цитируемый пост)
Полностью согласен. 2 J0ker  - консенсус?   

Наливайте!  smile

Запросто:
 smile  smile  smile  smile  smile  smile  smile  smile  smile  smile  smile  smile  smile  
Больше не дает  smile 

Автор: J0ker 14.4.2009, 16:28
Цитата(xvr @  14.4.2009,  07:28 Найти цитируемый пост)
Полностью согласен. 2 J0ker  - консенсус?

ну если вы все свои проблемы решили, то почему-бы и нет  smile 

Автор: RaP1D 4.5.2009, 19:06
Дабы не создавать новой темы, задам вопрос сюда...

Итак, что означает следующая запись:
Код

float x = 4;
float aa = *(int*)&x;


Если с командой & все понятно, то что означает *(int*)?

Автор: azesmcar 4.5.2009, 19:15
RaP1D

Да, действительно..давайте все вопросы сюда постить. Подождите, у меня вчера стиральная машина ошибку выдавала..
Цитата

Bad alloc: Washing machine is not properly initialized, not enough water.

причем тут эта тема? она битовых смещений касалась.

Автор: RaP1D 4.5.2009, 19:23
azesmcar,  не в этом дело  smile 
Просто название темы "Что означает эта запись?" и чтоб не создавать такой-же я решил сюда...  smile 

Автор: azesmcar 4.5.2009, 19:50
RaP1D

Надо..надо новую тему создавать smile 

это приведение к тиму в стиле С, и разименовка
Код

(int*) //приведение к тиму
*(int*) //разименовка (получение reference (ссылки) из указателя)


Автор: RaP1D 4.5.2009, 20:24
azesmcar, буду знать, спасибо!  smile 

Автор: inside_pointer 5.5.2009, 11:57
Цитата(RaP1D)

Если с командой & все понятно

да, и что же понятно ? тебе понятно, что она берёт адрес байта, который в x'е четвёртый по счёту (например), потом к этому адресу применяет операцию приведения к типу адреса с другим выравниванием, а потом уже полученное разыменовывает (не просто адрес, а тот же самый адрес, только который указывает на начало объекта другого размера (ну там совпадёт, что тоже четыре байта объект, но ты попробуй привести его к (char *) и поймёшь, что при разыменовании объект будет читаться как будто он весь в одном байте, когда float в четырёх)
там битовое представление хранится в этих байтах непрерывно и значение вычисляется из него

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