Професионална програма
Loading...
+ Нов въпрос
remote87 avatar remote87 121 Точки

[HOMEWORK] Loops: Problem 13 - Binary to decimal number / Progr Basic август 2015 /

Здравейте!

Може ли малко помощ за тази задача. Условието е input-а да е стринг. Бъркам ли някъде в логиката:

Ако имаме числото / бинари / 101010 примерно:

  1     0     1     0     1      0 - вкараното число

2^5, 2^4, 2^3, 2^2, 2^1, 2^ 0 - съответната степен на 2-ката

  |      |      |      |      |       |

32    16   8      4     2      1 - резултата от 2 на съответната степен

  |      |     |       |      |       |

1       0   1       0     1      0 - отново вкараното число

 |        |    |       |       |       |

32     0    8      0      2      0 - умножаваме резултата от 2 повдигнато на степен със числото на съответната позиция

Като сумираме последния ред 32 + 0 + 8 + 0 + 2 + 0 получаваме 42 / числото, на което отговаря 101010 в двуична система /.

Като тръгна да го пиша като код, получавам 21 и ми се струва, че бъркам някъде с дължината на стринга или греша при пресмятането?

            string binary = "101010";
            int digit = 0;
            int power = 0;
            long sum = 0L;
            for (int i = 0; i <= binary.Length - 1; i++)
            {
                digit = binary[i] - '0';
                double temp = Math.Pow(2, power);
                sum += (int)temp * digit;
                power++;
            }
            Console.WriteLine(sum);

EDIT: хм, подкарах го като обърнах i да намаля и да е равно на binary.Length - 1. Някой може ли да ми обясни логиката?
http://pastebin.com/2d4mK5Rc

Тагове:
0
Programming Basics 08/09/2015 13:47:15
tilchev92 avatar tilchev92 Trainer 128 Точки
Best Answer
        string binaryNum = Console.ReadLine();
        int twoPower = 1;
        long decimalNum = 0;
        for (int i = binaryNum.Length - 1; i >= 0 ; i--)
        {
            if(binaryNum[i] == '1')
            {
                decimalNum += twoPower;
            }
            twoPower <<= 1;
        }
        Console.WriteLine(decimalNum);

 

ето ти моето решение, за спорта :D по-особенното е, че ползвам побитово шифтване на ляво вместо умножение за да вдигам степените на 2, което е доста по-лека операция от умножението

1
08/09/2015 18:56:35
remote87 avatar remote87 121 Точки

Лол, доста яко решение! 

Може ли логиката постъпково за шифтването на степента? :)

0
tilchev92 avatar tilchev92 Trainer 128 Точки

Нали при 10тична бройна система като умножим по 10 просто добавяме една нула на числото което сме умножили. При двуичната е същото само че с 2:

1*2 = 10

11*2 = 110

и т.н.

затова като шифтнем добавяме една нула най в дясно ( 1 (1) << 1 = 10 (2) << 1 = 100 (4) и т.н.) реално все едно умножаваме по 2 двуичното число, т.е. вдигаме му степента с 1.

Същото е и при делението само, че се шифтва на обратно (дясно). Доста бързодействие може да се спечели така като вместо да делиш/умножаваш ЦЕЛИ числа на някоя степен на 2ката, ползваш шифтване.

1
08/09/2015 18:57:57
remote87 avatar remote87 121 Точки

Благодаря много!

Ще си коригирам решението понеже знам, че Math.Pow е сравнително бавна операция и е хубаво да се избягва, но изобщо не се бях сетил за тази логика.

Още един път, много благодаря, ще се опитам да го запомня! :)

1
Filkolev avatar Filkolev 4486 Точки

Обхождаш грешно. Както виждаш степените на двойката се гледат отясно наляво, докато ти итерираш през низа в обратната посока. Един вид при вход "101010" програмата ти ще сметне числото "010101", което е 21.

1
remote87 avatar remote87 121 Точки

Благодарско, Фил!

Сметнах го 100 пъти на лист и накрая започнах да се съмнявм дали изобщо го смятам правилно, а не ми дойде на ум, защо всъщност се получава различно в програмата :)

0