Софтуерно Инженерство
Loading...
+ Нов въпрос
IvanKrastev avatar IvanKrastev 0 Точки

Странно поведение на побитов оператор- >>

Здравейте, моля за малко помощ при разбирането на побитовите оператори. Използвам проста задача, в която съм настроил всички битове на 64 битово положително число на "1". Зададеното число се опитвам да го "преместя" с 64 позиции на дясно, като очаквам резултатът да е 0, но получавам същият резултат. Променях броя на позиициите на преместване произволно, но резултатът е все същият. Това е линк към простият пример, който използвам, за да си обясня работата на побитовите оператори: https://pastebin.com/H45XuS0r.

Благодаря на всички за оказаната помощ.

 

simonradev avatar simonradev 67 Точки

Здравей колега според мен това което се случва е напълно нормално... Ако имаш примерно 3 бита - 001 и ги преместиш с 3 позиции какво ще се случи... отново 001 което е същия резултат... Постъпково би изглеждало по следния начин ако буташ наляво (010, 100, 001) и по следния ако буташ надясно (100, 010, 001)... Когато ползваш 64 бита и преместиш 64 пъти всички битове се връщат по местата си... Същото ще се случи ако имаш 32 бита и преместиш 32 пъти... Това е моето мнение и да си призная не съм работил много с битове така че ако греша ще се радвам някой да ме поправи :) Успех колега

0
29/07/2017 08:24:23
IvanKrastev avatar IvanKrastev 0 Точки

Здравей и благодаря за коментара. Според това, което знам за побитовите оператори за преместване (<< и >>) празните позиции се запълват с 0, докато излезеш от обхвата на ч-лото. Според мен примера, които си дал с число 001, ако го прместиш с три бита на ляво ще получиш 1000 ако имаш достатъчно празни битове от дясно, а ако нямаш достатъчно празни битове за мен е логично да получиш 000 като резултат. В обяснението  за оператор << пише, че "That is, the actual shift count is 0 to 31 bits."

Не мога да разбера защо като премествам битове повече пъти от колкото е позволено защо не "изхвърля" преместените битове попаднали извън обхвата на променливата и не ги замества с нула докато всички битове станат 0, а циклично ги премества -> link.

0
04/08/2017 06:25:48
ppbaev avatar ppbaev 157 Точки

        var num = 9223372036854775807;

        for (int i = 0; i < 256; i++)
        {
            Console.WriteLine(Convert.ToString(num >> i, 2).PadLeft(64, '0'));
        }

Пусни горното може да ти просветне. Може да видиш как на всеки 63 завъртания почва отначало.

Накратко като правиш shift << или >> се взима само част от числото което си подал като number of shifts превърнато в битове. Ако е int се взимат само първите 5 бита, ако е long първите 6.

Пример:

0 в binary си е пак 0.

1 е 1, очевидно.

64 в binary e 1000000, обаче се реже на 6 бита от дясно и пак става 0.

65 е 1000001, което отрязано е 000001 = 1.

и тн. и тн.

Коментара отгоре за съжаление не е верен, при shift-ване позициите се запълват с 0, няма го е ефекта но ротация.

1
borkins avatar borkins 47 Точки

Здравей колега!
Не получаваш 0, защото не може да преместваш числото повече от 31 пъти за int и 63 за long.
Ако числото А е 32 битово и B > 31, то от B се ползват само първите 5 бита за операцията.
Ако числото А е 64 битово и B > 63, то от B се ползват само първите 6 бита за операцията.
Например:
int A = 2147483647, B = 32;
A е 32 битово число, B (bin: 0010 0000) > 31, then B (bin: 0 0000) = 0.
Тогава: A >> B = 2147483647 >> 0 = 2147483647.

long A = 9223372036854775807, B = 65;
A e 64 битово число, B (bin: 0100 0001) > 63, then B (bin: 00 0001) = 1.
Тогава A >> B = 9223372036854775807 >> 65 = 4611686018427387903;

0