Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

Losko avatar Losko 69 Точки

Salt And Pepper

//Здравейте. Опитвам се от число [0 – 18,446,744,073,709,551,615] да извадя бинарния вариант... До "long" е ОК с този код.

//long n = long.Parse(Console.ReadLine());
//string binary = Convert.ToString(n, 2).PadLeft(32, '0');
//Но "ulong" не работи.

Разбрах, че нямам достъчно знания ( побитовите операции не са ми ясни явно :( ) Но освен, тях си написах нещата. Надявам се да ми обясните тези няколко реда които ми обягват, както и защо в решеието което имам за 100/100 ( не моето за жалост ) се използва "if"
и резолтата е 100/100 в моето решение исползвам "switch" и резолтата е 90/100 :(
Това са редовте които ми обягваха и не разбирам на 100% :
if (((dishes >> j) & 1) == 1)
     {
         ulong mask = ~((ulong)1 << j);
          dishes = dishes & mask;
      }
Ето го решението за 100/100:  http://pastebin.com/EKXMjrYb
А това е моето 90/100: http://pastebin.com/6hW7RXc5

Благодаря предварително.

Тагове:
0
Общи приказки 17/06/2016 12:07:18
KrasimirPetkov avatar KrasimirPetkov 328 Точки

Можеш да го cast-неш към long. От гледна точка на битовете, няма разлика при представянето.

Пример:

ulong number = ulong.MaxValue; // Взимаме максималната стойност на ulong
string binary = Convert.ToString((long)number, 2); // Конвертираме го в двоична бройна система
ulong converted = Convert.ToUInt64(binary, 2); // Конвертираме двоичното число отново към ulong за проверка

Console.WriteLine(number); // Първоначалното число
Console.WriteLine(binary); // Двоично представяне
Console.WriteLine(converted); // Конвертираният към ulong string
Console.WriteLine(converted==number); // Сравняваме първоначалното и крайното число

Програмата връща:

18446744073709551615
1111111111111111111111111111111111111111111111111111111111111111
18446744073709551615
True

Надявам се информацията да ти е била от полза.

Успех!

1
17/06/2016 02:06:23
Losko avatar Losko 69 Точки

Не съм сигурен, че одговора ми помага. Най-вероятно понеже не съм задал правелният въпрос.
Цяла работа е, че сега съм на курса "Programming Basics" и то само след първата лекция :). Но решавам задачите от минал изпит. В момента се опитвам да реша задачата " Programming Basics Exam - 21 February 2016 -->> Problem 05 - Salt And Pepper.
Измислил съм някаква "програмна логика" имам структура която да ми стартира самата програма приема и разделя командите. Имам формули за манипулация на бинарния код на числото което трябва да променя. На кратко трябва да променя всеки Н-ти бит на някъква "ulong" число според зависи команда която получавам.  Та идеята ми беше да си направя числото на стринг да го манипулирам като стринг и накрая да го конвертирам в "ulong" отново. Сега като се замисля би трябвало да мога да го направя без цялата хамалогия с обръщане в бинарен код, а просто като така или иначе знам, че са 64-бита  да си направя 1 цикъл който да итерира толкова на брой пъти колкото е 64-бита / на Н-тите числа които трябва да обърна от 0 в 1 или обратното.

0
KrasimirPetkov avatar KrasimirPetkov 328 Точки

В случая начина за конвертиране от ulong към двоичен код, който показах в пост-а по-горе работи. Но идеята на тези задачи е да се решат с побитови операции. Ако искаш да опитваш с конвертиране, Convert.ToString((long)number, 2); и Convert.ToUInt64(binary, 2); работят за ulong. Ако си измислил нещо друго или си решил да се пробваш с побитови операции - супер!

И надявам се знаеш, че този тип задачи вече не се включват в приемния изпит. Ако се подготвяш за него - другите четири задачи ще са ти по-полезни. Ако ги решаваш за обща култура и знания - поздравления от мен и продължавай в същия дух!

1
Losko avatar Losko 69 Точки

Предните 4 са готови. С малко помощ от форума и лекторката ми 100/100. Иначе за жалост разбрах, че сега изпита ще е по-лесен. 
А тази задача се опитвам с побитови операции да я реша, но не искам да питам направо за одговор понеже искам да я реша до колкото мога сам само с насочващи въпроси които задавам за да си зглоя логиката на това което мъча :)

П.С. Гледах един стар лаб днес и попаднах нан ещо много полезно за тази задача.
http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

1
17/06/2016 02:37:49
Losko avatar Losko 69 Точки

Редактирах темичката да е по-точна. Ако погледнеш ще съм благодарен.

0
KrasimirPetkov avatar KrasimirPetkov 328 Точки
if (((dishes >> j) & 1) == 1)
{
    ulong mask = ~((ulong)1 << j);
    dishes = dishes & mask;
}

Нека да се опитам да ти обясня този код. Операцията >> означава изместване вдясно с определен брой позиции (съответно << е изместване вляво). Ще го илюстрирам с прост пример:

Console.WriteLine(8);   // Резултат: 8 - битове: 1000
Console.WriteLine(8>>3);   // Резултат: 1 - битове: 0001

Тоест, ако 8 в двоична система е: 1000, то с >>3 става на 0001, защото изместваме битовете надясно с 3 позиции.

Побитовото "и" (&) ни връща 1, ако и двата бита са единици или 0 във всички останали случаи. Това означава, че ако използваш &1, крайният резултат може да бъде само 1 или 0, защото се отчита дали последния бит от числото е единица/нула, а другите битове нямат никакво значение (тъй като при числото 1 в двоична система само последният бит е 1).

Така се проверява дали даден бит в числото е 1 или 0 (изместваме го до последна позиция и добавяме &1 - така ако е 1 се получава резултат 1, ако е 0 - резултат 0). В задачата, ако този бит е 1, тогава трябва да се смени на 0. Как става това?

Първо, създаваме число, което да има бит със стойност 1 на желната позиция. Ако искаме 1 на 3-та позиция ще използваме 1<<3. Така ще имаме стойност 1 на 3-ти бит (броим от 0), а всички други ще са 0. След като сме създали числото, обръщаме битовете с побитово отрицание ~.

Защо? По този начин всички битове ще бъдат 1, освен този на позицията, която сме избрали. Съответно, при използване на побитово "и" (&) с числото, чийто бит искаме да променим се получава следното: всички битове, които са били 0, ще си останат 0 ( 0 & 1 = 0 ), всички битове, които са били 1, ще си останат 1 ( 1 & 1 = 1 ). Само бита на желаната от нас позиция, ще стане от 1 на 0 ( тъй като 1 & 0 = 0 ). Пример: 10101 & 11011 = 10001. Надявам се, че си разбрал логиката.

 

Относно твоето решение: при case "salt", цикъла си го направил for (int j = 0; j < 63; j += step), а трябва да е for (int j = 0; j <= 63; j += step).

 

Успех!

2
17/06/2016 12:46:06
Losko avatar Losko 69 Точки

Много благодаря. 

1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.